repos / pico

pico services mono repo
git clone https://github.com/picosh/pico.git

pico / pkg / apps / pastes
Eric Bower  ·  2026-01-25

ssh.go

 1package pastes
 2
 3import (
 4	"context"
 5	"os"
 6	"os/signal"
 7	"syscall"
 8	"time"
 9
10	"github.com/picosh/pico/pkg/db/postgres"
11	"github.com/picosh/pico/pkg/filehandlers"
12	"github.com/picosh/pico/pkg/pssh"
13	"github.com/picosh/pico/pkg/send/auth"
14	"github.com/picosh/pico/pkg/send/list"
15	"github.com/picosh/pico/pkg/send/pipe"
16	"github.com/picosh/pico/pkg/send/protocols/rsync"
17	"github.com/picosh/pico/pkg/send/protocols/scp"
18	"github.com/picosh/pico/pkg/send/protocols/sftp"
19	"github.com/picosh/pico/pkg/shared"
20)
21
22func StartSshServer() {
23	appName := "pastes-ssh"
24
25	host := shared.GetEnv("PASTES_HOST", "0.0.0.0")
26	port := shared.GetEnv("PASTES_SSH_PORT", "2222")
27	promPort := shared.GetEnv("PASTES_PROM_PORT", "9222")
28	cfg := NewConfigSite(appName)
29	logger := cfg.Logger
30
31	ctx, cancel := context.WithCancel(context.Background())
32	defer cancel()
33
34	dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
35	defer func() {
36		_ = dbh.Close()
37	}()
38	hooks := &FileHooks{
39		Cfg: cfg,
40		Db:  dbh,
41	}
42
43	fileMap := map[string]filehandlers.ReadWriteHandler{
44		"fallback": filehandlers.NewScpPostHandler(dbh, cfg, hooks),
45	}
46	handler := filehandlers.NewFileHandlerRouter(cfg, dbh, fileMap)
47	sshAuth := shared.NewSshAuthHandler(dbh, logger, "pastes")
48
49	// Create a new SSH server
50	server, err := pssh.NewSSHServerWithConfig(
51		ctx,
52		logger,
53		appName,
54		host,
55		port,
56		promPort,
57		"ssh_data/term_info_ed25519",
58		sshAuth.PubkeyAuthHandler,
59		[]pssh.SSHServerMiddleware{
60			pipe.Middleware(handler, ""),
61			list.Middleware(handler),
62			scp.Middleware(handler),
63			rsync.Middleware(handler),
64			auth.Middleware(handler),
65			pssh.PtyMdw(pssh.DeprecatedNotice(), 200*time.Millisecond),
66			pssh.LogMiddleware(handler, dbh),
67		},
68		[]pssh.SSHServerMiddleware{
69			sftp.Middleware(handler),
70			pssh.LogMiddleware(handler, dbh),
71		},
72		nil,
73	)
74
75	if err != nil {
76		logger.Error("failed to create ssh server", "err", err.Error())
77		os.Exit(1)
78	}
79
80	done := make(chan os.Signal, 1)
81	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
82	logger.Info("Starting SSH server", "addr", server.Config.ListenAddr)
83	go func() {
84		if err = server.ListenAndServe(); err != nil {
85			logger.Error("serve", "err", err.Error())
86			os.Exit(1)
87		}
88	}()
89
90	exit := func() {
91		logger.Info("stopping ssh server")
92		cancel()
93	}
94
95	<-done
96	exit()
97}