forked from hswaw/hscloud
In addition to k8s certificates, prodaccess now issues HSPKI certificates, with DN=$username.sso.hswaw.net. These are installed into XDG_CONFIG_HOME (or os equiv). //go/pki will now automatically attempt to load these certificates. This means you can now run any pki-dependant tool with -hspki_disable, and with automatic mTLS! Change-Id: I5b28e193e7c968d621bab0d42aabd6f0510fed6d
117 lines
2.7 KiB
Go
117 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"crypto/x509"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/user"
|
|
"syscall"
|
|
|
|
"github.com/golang/glog"
|
|
"golang.org/x/crypto/ssh/terminal"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials"
|
|
|
|
"code.hackerspace.pl/cluster/certs"
|
|
pb "code.hackerspace.pl/hscloud/cluster/prodvider/proto"
|
|
)
|
|
|
|
var (
|
|
flagProdvider string
|
|
flagUsername string
|
|
flagForce bool
|
|
)
|
|
|
|
func init() {
|
|
flag.Set("logtostderr", "true")
|
|
}
|
|
|
|
func main() {
|
|
user, err := user.Current()
|
|
if err == nil {
|
|
flagUsername = user.Username
|
|
}
|
|
|
|
flag.StringVar(&flagProdvider, "prodvider", "prodvider.hswaw.net:443", "Prodvider endpoint")
|
|
flag.StringVar(&flagUsername, "username", flagUsername, "Username to authenticate with")
|
|
flag.BoolVar(&flagForce, "force", false, "Force retrieving certificates even if they already exist")
|
|
flag.Parse()
|
|
|
|
if flagUsername == "" {
|
|
glog.Exitf("Username could not be detected, please provide with -username flag")
|
|
}
|
|
|
|
cp := x509.NewCertPool()
|
|
if ok := cp.AppendCertsFromPEM(certs.Data["ca-kube.crt"]); !ok {
|
|
glog.Exitf("Could not load k8s CA")
|
|
}
|
|
|
|
creds := credentials.NewClientTLSFromCert(cp, "")
|
|
conn, err := grpc.Dial(flagProdvider, grpc.WithTransportCredentials(creds))
|
|
if err != nil {
|
|
glog.Exitf("Could not dial prodvider: %v", err)
|
|
}
|
|
|
|
prodvider := pb.NewProdviderClient(conn)
|
|
ctx := context.Background()
|
|
|
|
if !needKubernetesCreds() && !flagForce {
|
|
fmt.Printf("Kubernetes credentials exist. Use `prodaccess -force` to force update.\n")
|
|
os.Exit(0)
|
|
}
|
|
|
|
attempts := 0
|
|
for {
|
|
ok := authenticate(ctx, prodvider)
|
|
attempts += 1
|
|
if !ok {
|
|
if attempts >= 3 {
|
|
os.Exit(1)
|
|
}
|
|
} else {
|
|
fmt.Printf("Good evening professor. I see you have driven here in your Ferrari.\n")
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
}
|
|
|
|
func authenticate(ctx context.Context, prodvider pb.ProdviderClient) bool {
|
|
req := &pb.AuthenticateRequest{
|
|
Username: flagUsername,
|
|
Password: password(),
|
|
}
|
|
|
|
res, err := prodvider.Authenticate(ctx, req)
|
|
if err != nil {
|
|
glog.Exitf("Prodvider error: %v", err)
|
|
}
|
|
|
|
switch res.Result {
|
|
case pb.AuthenticateResponse_RESULT_AUTHENTICATED:
|
|
break
|
|
case pb.AuthenticateResponse_RESULT_INVALID_CREDENTIALS:
|
|
fmt.Printf("Invalid username or password.\n")
|
|
return false
|
|
default:
|
|
glog.Exitf("Unknown authentication result: %v", res.Result)
|
|
}
|
|
|
|
useKubernetesKeys(res.KubernetesKeys)
|
|
fmt.Printf("-> Kubernetes credentials installed\n")
|
|
useHSPKIKeys(res.HspkiKeys)
|
|
fmt.Printf("-> HSPKI credentials installed\n")
|
|
|
|
return true
|
|
}
|
|
|
|
func password() string {
|
|
fmt.Printf("Enter SSO/LDAP password for %s@hackerspace.pl: ", flagUsername)
|
|
bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
fmt.Printf("\n")
|
|
return string(bytePassword)
|
|
}
|