cert-manager-webhook-sthome/pkg/auth/kerberos.go

127 lines
2.3 KiB
Go

package auth
import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"os/exec"
"os/user"
"sync"
cred "github.com/jcmturner/gokrb5/credentials"
)
const (
kinitCmd = "kinit"
kvnoCmd = "kvno"
klistCmd = "klist"
spn = "DNS/upd.sthome.net@STHOME.LAN"
)
type output struct {
buf *bytes.Buffer
lines []string
*sync.Mutex
}
func newOutput() *output {
return &output{
buf: &bytes.Buffer{},
lines: []string{},
Mutex: &sync.Mutex{},
}
}
func (rw *output) Write(p []byte) (int, error) {
rw.Lock()
defer rw.Unlock()
return rw.buf.Write(p)
}
func (rw *output) Lines() []string {
rw.Lock()
defer rw.Unlock()
s := bufio.NewScanner(rw.buf)
for s.Scan() {
rw.lines = append(rw.lines, s.Text())
}
return rw.lines
}
func login() error {
file, err := os.Create("/etc/krb5.conf")
if err != nil {
return fmt.Errorf("cannot open krb5.conf: %v", err)
}
defer file.Close()
fmt.Fprintf(file, krb5conf)
cmd := exec.Command(kinitCmd, dnsupdateuser)
stdinR, stdinW := io.Pipe()
stderrR, stderrW := io.Pipe()
cmd.Stdin = stdinR
cmd.Stderr = stderrW
err = cmd.Start()
if err != nil {
return fmt.Errorf("could not start %s command: %v", kinitCmd, err)
}
go func() {
io.WriteString(stdinW, "passwordvalue")
stdinW.Close()
}()
errBuf := new(bytes.Buffer)
go func() {
io.Copy(errBuf, stderrR)
stderrR.Close()
}()
err = cmd.Wait()
if err != nil {
return fmt.Errorf("%s did not run successfully: %v stderr: %s", kinitCmd, err, string(errBuf.Bytes()))
}
return nil
}
func getServiceTkt() error {
cmd := exec.Command(kvnoCmd, spn)
err := cmd.Start()
if err != nil {
return fmt.Errorf("could not start %s command: %v", kvnoCmd, err)
}
err = cmd.Wait()
if err != nil {
return fmt.Errorf("%s did not run successfully: %v", kvnoCmd, err)
}
return nil
}
func klist() ([]string, error) {
cmd := exec.Command(klistCmd, "-Aef")
stdout := newOutput()
cmd.Stdout = stdout
err := cmd.Start()
if err != nil {
return []string{}, fmt.Errorf("could not start %s command: %v", klistCmd, err)
}
err = cmd.Wait()
if err != nil {
return []string{}, fmt.Errorf("%s did not run successfully: %v", klistCmd, err)
}
return stdout.Lines(), nil
}
func loadCCache() (*cred.CCache, error) {
usr, _ := user.Current()
cpath := "/tmp/krb5cc_" + usr.Uid
return cred.LoadCCache(cpath)
}