From 5cac17676a6c2963f21eedae14845b59cd89899b Mon Sep 17 00:00:00 2001 From: lash Date: Sat, 21 Sep 2024 00:32:39 +0100 Subject: [PATCH] WIP adapt ssh server sketch to urdt setup --- cmd/ssh/main.go | 240 ++++++++++++++++++++++++++++++++++++ internal/storage/storage.go | 4 + 2 files changed, 244 insertions(+) create mode 100644 cmd/ssh/main.go diff --git a/cmd/ssh/main.go b/cmd/ssh/main.go new file mode 100644 index 0000000..f973dff --- /dev/null +++ b/cmd/ssh/main.go @@ -0,0 +1,240 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + "path" + "os" + "sync" + + "golang.org/x/crypto/ssh" + + "git.defalsify.org/vise.git/db" + "git.defalsify.org/vise.git/engine" + "git.defalsify.org/vise.git/logging" + "git.defalsify.org/vise.git/resource" + gdbmdb "git.defalsify.org/vise.git/db/gdbm" + + "git.grassecon.net/urdt/ussd/internal/handlers" + "git.grassecon.net/urdt/ussd/internal/storage" + "git.grassecon.net/urdt/ussd/internal/handlers/ussd" +) + +var ( + wg sync.WaitGroup + auth map[string]string + keyStore db.Db + logg = logging.NewVanilla() + scriptDir = path.Join("services", "registration") +) + +type auther struct { + SessionId string + Ctx context.Context +} + +func(a *auther) Check(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) { + keyStore.SetPrefix(storage.DATATYPE_CUSTOM) + k := append([]byte{0x01}, pubKey.Marshal()...) + v, err := keyStore.Get(a.Ctx, k) + if err != nil { + return nil, err + } + a.SessionId = string(v) + fmt.Fprintf(os.Stderr, "connect: %s\n", a.SessionId) + return nil, nil +} + +func populateAuth() { + auth = make(map[string]string) + pubKey, _, _, rest, err := ssh.ParseAuthorizedKey([]byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCu5rYCxMBsVAL1TEkMQgmElAYEZj5zYDdyHjUxZ6qzHBOZD9GAzdxx9GyQDx2vdYm3329tLH/69ky1YA3nUz8SnJGBD6hC5XrqwN6zo9R9oOHAKTwiPGhey2NTVmheP+9XNHukBnOlkkWOQlpDDvMbWOztaZOWDaA8OIeP0t6qzFqLyelyg65lxzM3BKd7bCmmfzl/64BcP1MotAmB9DUxmY0Wb4Q2hYZfNYBx50Z4xthTgKV+Xoo8CbTduKotIz6hluQGvWdtxlCJQEiZ2f4RYY87JSA6/BAH2fhxuLHMXRpzocJNqARqCWpdcTGSg7bzxbKvTFH9OU4wZtr9ie40OR4zsc1lOBZL0rnp8GLkG8ZmeBQrgEDlmR9TTlz4okgtL+c5TCS37rjZYVjmtGwihws0EL9+wyv2dSQibirklC4wK5eWHKXl5vab19qzw/qRLdoRBK40DxbRKggxA7gqSsKrmrf+z7CuLIz/kxF+169FBLbh1MfBOGdx1awm6aU= lash@furioso")) + if err != nil { + panic(err) + } + auth[string(pubKey.Marshal())] = "+25113243546" + _ = rest +} + +func serve(ch ssh.NewChannel) { + if ch == nil { + return + } + if ch.ChannelType() != "session" { + ch.Reject(ssh.UnknownChannelType, "that is not the channel you are looking for") + return + } + channel, requests, err := ch.Accept() + if err != nil { + panic(err) + } + defer channel.Close() + wg.Add(1) + go func(reqIn <-chan *ssh.Request) { + defer wg.Done() + for req := range reqIn { + req.Reply(req.Type == "shell", nil) + } + _ = requests + }(requests) + + n, err := channel.Write([]byte("foobarbaz\n")) + if err != nil { + panic(err) + } + log.Printf("wrote %d", n) +} + +func sshRun(ctx context.Context, hl *ussd.Handlers) { + running := true + + defer wg.Wait() + + auth := auther{Ctx: ctx} + cfg := ssh.ServerConfig{ + PublicKeyCallback: auth.Check, + } + + privateBytes, err := os.ReadFile("/home/lash/.ssh/id_rsa_tmp") + if err != nil { + log.Fatal("Failed to load private key: ", err) + } + private, err := ssh.ParsePrivateKey(privateBytes) + if err != nil { + log.Fatal("Failed to parse private key: ", err) + } + cfg.AddHostKey(private) + + lst, err := net.Listen("tcp", "0.0.0.0:2022") + if err != nil { + panic(err) + } + + for running { + conn, err := lst.Accept() + if err != nil { + panic(err) + } + + go func(conn net.Conn) { + defer conn.Close() + for true { + srvConn, nC, rC, err := ssh.NewServerConn(conn, &cfg) + if err != nil { + log.Printf("rejected client: %v", err) + } + log.Printf("haveconn %v", srvConn) + + wg.Add(1) + go func() { + ssh.DiscardRequests(rC) + wg.Done() + }() + + for ch := range nC { + serve(ch) + } + } + }(conn) + } +} + +func sshLoadKeys(ctx context.Context, dbDir string) error { + keyStoreFile := path.Join(dbDir, "ssh_authorized_keys.gdbm") + keyStore = gdbmdb.NewGdbmDb() + keyStore.Connect(ctx, keyStoreFile) + pubKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCu5rYCxMBsVAL1TEkMQgmElAYEZj5zYDdyHjUxZ6qzHBOZD9GAzdxx9GyQDx2vdYm3329tLH/69ky1YA3nUz8SnJGBD6hC5XrqwN6zo9R9oOHAKTwiPGhey2NTVmheP+9XNHukBnOlkkWOQlpDDvMbWOztaZOWDaA8OIeP0t6qzFqLyelyg65lxzM3BKd7bCmmfzl/64BcP1MotAmB9DUxmY0Wb4Q2hYZfNYBx50Z4xthTgKV+Xoo8CbTduKotIz6hluQGvWdtxlCJQEiZ2f4RYY87JSA6/BAH2fhxuLHMXRpzocJNqARqCWpdcTGSg7bzxbKvTFH9OU4wZtr9ie40OR4zsc1lOBZL0rnp8GLkG8ZmeBQrgEDlmR9TTlz4okgtL+c5TCS37rjZYVjmtGwihws0EL9+wyv2dSQibirklC4wK5eWHKXl5vab19qzw/qRLdoRBK40DxbRKggxA7gqSsKrmrf+z7CuLIz/kxF+169FBLbh1MfBOGdx1awm6aU= lash@furioso")) + if err != nil { + return err + } + //auth[string(pubKey.Marshal())] = "+25113243546" + k := append([]byte{0x01}, pubKey.Marshal()...) + keyStore.SetPrefix(storage.DATATYPE_CUSTOM) + return keyStore.Put(ctx, k, []byte("+25113243546")) +} + +func main() { + var dbDir string + var resourceDir string + var size uint + var engineDebug bool + var stateDebug bool + var host string + var port uint + flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from") + flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir") + flag.BoolVar(&engineDebug, "engine-debug", false, "use engine debug output") + flag.BoolVar(&stateDebug, "state-debug", false, "use engine debug output") + flag.UintVar(&size, "s", 160, "max size of output") + flag.StringVar(&host, "h", "127.0.0.1", "http host") + flag.UintVar(&port, "p", 7123, "http port") + flag.Parse() + + logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size) + + ctx := context.Background() + pfp := path.Join(scriptDir, "pp.csv") + + cfg := engine.Config{ + Root: "root", + OutputSize: uint32(size), + FlagCount: uint32(16), + } + if stateDebug { + cfg.StateDebug = true + } + if engineDebug { + cfg.EngineDebug = true + } + + menuStorageService := storage.MenuStorageService{} + rs, err := menuStorageService.GetResource(scriptDir, ctx) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + err = menuStorageService.EnsureDbDir(dbDir) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + userdataStore := menuStorageService.GetUserdataDb(dbDir, ctx) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + defer userdataStore.Close() + + dbResource, ok := rs.(*resource.DbResource) + if !ok { + os.Exit(1) + } + + lhs, err := handlers.NewLocalHandlerService(pfp, true, dbResource, cfg, rs) + lhs.WithDataStore(&userdataStore) + + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + hl, err := lhs.GetHandler() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + stateStore, err := menuStorageService.GetStateStore(dbDir, ctx) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + defer stateStore.Close() + + sshLoadKeys(ctx, dbDir) + sshRun(ctx, hl) +} diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 53f4392..009819e 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -5,6 +5,10 @@ import ( "git.defalsify.org/vise.git/persist" ) +const ( + DATATYPE_CUSTOM = 128 +) + type Storage struct { Persister *persist.Persister UserdataDb db.Db