From 2acc042fe73f0a2b9b6435fc92ceae9be9c18381 Mon Sep 17 00:00:00 2001 From: vilmibm Date: Fri, 3 Mar 2023 22:01:21 +0000 Subject: [PATCH] first pass on keyfile helper --- cmd/createkeyfile/main.go | 96 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 cmd/createkeyfile/main.go diff --git a/cmd/createkeyfile/main.go b/cmd/createkeyfile/main.go new file mode 100644 index 0000000..889611c --- /dev/null +++ b/cmd/createkeyfile/main.go @@ -0,0 +1,96 @@ +package main + +/* + +The purpose of this command is to be run as a new user. It initializes their ssh authorized_keys2 file, which allows them to ssh in for the first time. + +This is an isolated command because creating a file and chowning it normally requires root permissions. We don't want to run the welcome command as root, so we give it `sudo` permission to run this one command as any user. The keyfile path is hardcoded, so if someone were to assume `welcome`'s identity, it could of course cause havoc but not delete + +This is a port of the old createkeyfile.py script from the former admin system. + +There are two functional changes: + +1. It also creates `.ssh`. I can't remember if there was a reason the old script didn't do that as there is no record one way or the other. But having this command make `.ssh` means one fewer thing in the sudoers file. + +2. It guards against overwriting of both .ssh and authorized_keys2. This is solely to limit the effect of a security breach. In the old admin system keys were managed via the django admin, meaning this script was used to add keys to authorized_keys2. these days we just edit authorized_keys2 directly, so this new command should only ever be used to initialize .ssh for a new user. + +*/ + +import ( + "fmt" + "os" + "os/user" + "path" +) + +const keyfileName = "authorized_keys2" + +func quit(msg string) { + fmt.Println(msg) + os.Exit(1) +} + +func main() { + u, err := user.Current() + if err != nil { + quit(err.Error()) + } + + sshPath := path.Join("/home", u.Username, ".ssh") + keyfilePath := path.Join(sshPath, keyfileName) + + if err = os.Mkdir(sshPath, os.FileMode(0600)); err != nil { + quit(err.Error()) + } + + f, err := os.Create(keyfilePath) + if err != nil { + quit(err.Error()) + } + + defer f.Close() + + if err = os.Chmod(keyfilePath, os.FileMode(0600)); err != nil { + quit(err.Error()) + } + + stdin := []byte{} + + n, err := os.Stdin.Read(stdin) + if err != nil { + quit(err.Error()) + } else if n == 0 { + quit("nothing passed on STDIN") + } + + n, err = f.Write(stdin) + if err != nil { + quit(err.Error()) + } else if n == 0 { + quit("wrote nothing to keyfile") + } +} + +/* + +The old script, in full: + +#!/usr/bin/env python3 +"""this script allows django to add public keys for a user. it's in its own +script so that a specific command can be added to the ttadmin user's sudoers +file.""" +import sys + +KEYFILE_PATH = '/home/{}/.ssh/authorized_keys2' + + +def main(argv): + username = argv[1] + with open(KEYFILE_PATH.format(username), 'w') as f: + f.write(sys.stdin.read()) + + +if __name__ == '__main__': + exit(main(sys.argv)) + +*/