1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
diff --git a/obj/ssh.go b/obj/ssh.go
new file mode 100644
index 0000000..ab70493
--- /dev/null
+++ b/obj/ssh.go
@@ -0,0 +1,99 @@
+package obj
+
+import (
+ "context"
+ "fmt"
+ "log/slog"
+ "os"
+ "os/signal"
+ "path/filepath"
+ "syscall"
+ "time"
+
+ "github.com/charmbracelet/wish"
+ "github.com/picosh/pico/db"
+ "github.com/picosh/pico/db/postgres"
+ "github.com/picosh/pico/filehandlers/util"
+ "github.com/picosh/pico/shared"
+ "github.com/picosh/pico/shared/storage"
+ "github.com/picosh/pobj"
+ "github.com/picosh/send/send/utils"
+)
+
+type AssetNamesPriv struct {
+ DBPool db.DB
+}
+
+var _ pobj.AssetNames = &AssetNamesPriv{}
+var _ pobj.AssetNames = (*AssetNamesPriv)(nil)
+
+func (an *AssetNamesPriv) BucketName(userName string) string {
+ user, _ := an.DBPool.FindUserForName(userName)
+ return shared.GetAssetBucketName(user.ID)
+}
+func (an *AssetNamesPriv) ObjectName(entry *utils.FileEntry) string {
+ return filepath.Join("pico-private", entry.Filepath)
+}
+
+func StartSshServer() {
+ logger := slog.Default()
+ host := pobj.GetEnv("OBJ_SSH_HOST", "0.0.0.0")
+ port := pobj.GetEnv("OBJ_SSH_PORT", "2222")
+ cfg := NewConfigSite()
+ dbpool := postgres.NewDB(cfg.DbURL, cfg.Logger)
+ defer dbpool.Close()
+
+ var st storage.StorageServe
+ var err error
+ if cfg.MinioURL == "" {
+ st, err = storage.NewStorageFS(cfg.StorageDir)
+ } else {
+ st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
+ }
+
+ assetNames := &AssetNamesPriv{
+ DBPool: dbpool,
+ }
+ objcfg := &pobj.Config{
+ Logger: logger,
+ Storage: st,
+ AssetNames: assetNames,
+ }
+
+ handler := pobj.NewUploadAssetHandler(objcfg)
+
+ sshAuth := util.NewSshAuthHandler(dbpool, logger, cfg)
+ s, err := wish.NewServer(
+ wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
+ wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
+ wish.WithPublicKeyAuth(sshAuth.PubkeyAuthHandler),
+ pobj.WithProxy(handler),
+ )
+ if err != nil {
+ logger.Error(err.Error())
+ return
+ }
+
+ done := make(chan os.Signal, 1)
+ signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
+ logger.Info(
+ "starting SSH server",
+ "host", host,
+ "port", port,
+ )
+ go func() {
+ if err = s.ListenAndServe(); err != nil {
+ logger.Error(err.Error())
+ }
+ }()
+
+ <-done
+ logger.Info("stopping SSH server")
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+ defer func() {
+ cancel()
+ }()
+ if err := s.Shutdown(ctx); err != nil {
+ logger.Error(err.Error())
+ }
+}
|