forked from urdt/ussd
241 lines
6.3 KiB
Go
241 lines
6.3 KiB
Go
|
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)
|
||
|
}
|