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