implemented simple ssh dual control

This commit is contained in:
ston1th 2025-01-23 00:15:25 +01:00
commit 60012be942
12 changed files with 446 additions and 20 deletions

134
pkg/ssh/ssh.go Normal file
View file

@ -0,0 +1,134 @@
// Copyright (C) 2023 Marius Schellenberger
package ssh
import (
"context"
"errors"
"flag"
"fmt"
"os"
"text/tabwriter"
apiclient "git.giftfish.de/ston1th/keyctl/pkg/api/client"
clientv1 "git.giftfish.de/ston1th/keyctl/pkg/api/v1/client"
"git.giftfish.de/ston1th/keyctl/pkg/core"
"golang.org/x/sys/unix"
)
var fs = flag.NewFlagSet("", flag.ExitOnError)
func exit(err error) {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
func Run(arg string) {
ctx := context.Background()
switch arg {
case "approve":
id, err := idFlags("access id")
if err != nil {
exit(err)
}
c := client()
err = c.AcceptAccess(ctx, id)
if err != nil {
exit(err)
}
case "reject":
id, err := idFlags("access id")
if err != nil {
exit(err)
}
c := client()
err = c.RejectAccess(ctx, id)
if err != nil {
exit(err)
}
case "login":
endpoint, err := loginFlags()
if err != nil {
exit(err)
}
opts, err := apiclient.ClientOptionsFromConfig(
apiclient.Config{Endpoint: endpoint},
)
if err != nil {
exit(err)
}
c := client(opts...)
host, err := os.Hostname()
if err != nil {
exit(err)
}
// TODO: fix me (user)
ok, err := c.Access(ctx, host, "user")
if err != nil {
exit(err)
}
if ok {
unix.Exec("/bin/bash", []string{"bash"}, os.Environ()) // does not return
}
case "req":
c := client()
access, err := c.GetAccess(ctx)
if err != nil {
exit(err)
}
print(access)
}
os.Exit(0)
}
func client(opts ...apiclient.ClientOption) (c *clientv1.Client) {
var err error
if opts == nil {
opts, err = apiclient.ClientOptionsFromEnv()
if err != nil {
exit(err)
}
}
apic := apiclient.NewClient(opts...)
//if socket, ok := apic.IsUnix(); ok {
// err = unveil(socket)
// if err != nil {
// exit(err)
// }
//}
c, err = clientv1.NewClient(apic)
if err != nil {
exit(err)
}
return
}
func print(tw core.TableWriter) {
if tw.Len() == 0 {
return
}
w := tabwriter.NewWriter(os.Stdout, 1, 0, 1, ' ', tabwriter.Debug)
fmt.Fprintln(w, tw.Fields())
for _, v := range tw.Values() {
fmt.Fprintln(w, v)
}
w.Flush()
}
func idFlags(desc string) (id string, err error) {
fs.StringVar(&id, "id", "", desc)
fs.Parse(os.Args[3:])
if id == "" {
err = errors.New("missing flag: id")
}
return
}
func loginFlags() (endpoint string, err error) {
fs.StringVar(&endpoint, "endpoint", "", "keyctl endpoint")
fs.Parse(os.Args[3:])
if endpoint == "" {
err = errors.New("missing flag: endpoint")
}
return
}