better messages when the user modifies the .authorized_keys file from

within the session.
This commit is contained in:
Erik Brakkee 2024-08-06 22:28:34 +02:00
parent d109c72f66
commit d134f1e944
3 changed files with 34 additions and 25 deletions

View File

@ -329,9 +329,12 @@ func main() {
// Authentiocation
authorizedKeys := NewAuthorizedPublicKeys(authorizedKeysFile)
authorizedKeys, err := NewAuthorizedPublicKeys(authorizedKeysFile)
if err != nil {
os.Exit(1)
}
// initial check
pubkeys := authorizedKeys.Parse()
pubkeys, _ := authorizedKeys.Parse()
if len(pubkeys) == 0 {
log.Printf("No public keys found in '%s', exiting", authorizedKeysFile)
os.Exit(1)

View File

@ -26,15 +26,16 @@ func publicKeyHandler(ctx ssh.Context, key gossh.PublicKey, authorizedKey gossh.
return false
}
func readSshPublicKeys(fileName string) ([]ssh.PublicKey, error) {
func readSshPublicKeys(fileName string) ([]ssh.PublicKey, []string, error) {
file, err := os.Open(fileName)
if err != nil {
return nil, fmt.Errorf("Failed to open file: '%s': %s", fileName, err)
return nil, nil, fmt.Errorf("Failed to open file: '%s': %s", fileName, err)
}
defer file.Close()
res := make([]ssh.PublicKey, 0)
scanner := bufio.NewScanner(file)
var errorKeys []string
for scanner.Scan() {
lineText := scanner.Text()
ind := strings.Index(lineText, "#")
@ -49,12 +50,13 @@ func readSshPublicKeys(fileName string) ([]ssh.PublicKey, error) {
line := []byte(lineText)
parsedKey, _, _, _, err := ssh.ParseAuthorizedKey(line)
if err != nil {
errorKeys = append(errorKeys, lineText)
log.Printf("Failed to parse authorized key: %v", lineText)
} else {
res = append(res, parsedKey)
}
}
return res, nil
return res, errorKeys, nil
}
type AuthorizedPublicKeys struct {
@ -63,18 +65,18 @@ type AuthorizedPublicKeys struct {
publicKeys []ssh.PublicKey
}
func NewAuthorizedPublicKeys(authorizedKeysFile string) *AuthorizedPublicKeys {
func NewAuthorizedPublicKeys(authorizedKeysFile string) (*AuthorizedPublicKeys, error) {
pubkeys := AuthorizedPublicKeys{
authorizedKeysFile: authorizedKeysFile,
mutex: sync.Mutex{},
publicKeys: nil,
}
pubkeys.publicKeys, _ = pubkeys.Parse()
if len(pubkeys.publicKeys) == 0 {
return nil, fmt.Errorf("No valid public keys found, login is impossible, exiting")
}
go pubkeys.monitorAuthorizedKeysFile(authorizedKeysFile)
return &pubkeys
}
func (pubkeys *AuthorizedPublicKeys) notifyUsers(message string) {
session.MessageUsers(message)
return &pubkeys, nil
}
func (pubkeys *AuthorizedPublicKeys) setPubKeys(keys []ssh.PublicKey) {
@ -106,30 +108,34 @@ func (pubkeys *AuthorizedPublicKeys) monitorAuthorizedKeysFile(authorizedPublicK
select {
case event, ok := <-watcher.Events:
if !ok {
pubkeys.notifyUsers(
session.MessageUsers(
fmt.Sprintf("Watching authorized keys file '%s' stopped", authorizedPublicKeysFile))
return
}
base := filepath.Base(event.Name)
log.Println("CHANGE " + base + " " + authorizedPublicKeysFile + " " + filepath.Base(authorizedPublicKeysFile))
if base == filepath.Base(authorizedPublicKeysFile) {
keys := pubkeys.Parse()
keys, errorKeys := pubkeys.Parse()
for _, errorKey := range errorKeys {
session.MessageUsers(fmt.Sprintf("Public key '%s' is invalid", errorKey))
}
if len(keys) == 0 {
pubkeys.notifyUsers(
fmt.Sprintf("Authorized keys file '%s' does not contain any valid keys, using last known configuration", authorizedPublicKeysFile))
session.MessageUsers(
fmt.Sprintf("Authorized keys file '%s' does not exist or does not contain any valid keys, using last known configuration", authorizedPublicKeysFile))
} else {
pubkeys.notifyUsers(fmt.Sprintf("Updated authorized keys, now %d valid keys", len(keys)))
session.MessageUsers(fmt.Sprintf("Updated authorized keys, now %d valid key(s)", len(keys)))
pubkeys.setPubKeys(keys)
}
}
case err, ok := <-watcher.Errors:
if ok {
pubkeys.notifyUsers(fmt.Sprintf(
session.MessageUsers(fmt.Sprintf(
"Watching authorized keys file '%s' stopped",
pubkeys.authorizedKeysFile))
}
pubkeys.notifyUsers(fmt.Sprintf(
session.MessageUsers(fmt.Sprintf(
"Watching authorized keys file '%s' stopped: %v",
pubkeys.authorizedKeysFile, err))
return
@ -137,24 +143,24 @@ func (pubkeys *AuthorizedPublicKeys) monitorAuthorizedKeysFile(authorizedPublicK
}
}
func (pubkeys *AuthorizedPublicKeys) Parse() []ssh.PublicKey {
func (pubkeys *AuthorizedPublicKeys) Parse() ([]ssh.PublicKey, []string) {
if pubkeys.authorizedKeysFile == "" {
return nil
return nil, nil
}
keys, err := readSshPublicKeys(pubkeys.authorizedKeysFile)
keys, errorKeys, err := readSshPublicKeys(pubkeys.authorizedKeysFile)
if os.IsNotExist(err) {
log.Printf("Authorized keys file '%s' not found.", pubkeys.authorizedKeysFile)
return nil
return nil, nil
}
if err != nil {
log.Println("Public key authentication will not work since no public keys were found.")
}
return keys
return keys, errorKeys
}
func (key *AuthorizedPublicKeys) authorize(ctx ssh.Context, userProvidedKey ssh.PublicKey) bool {
//
keys := key.Parse()
keys, _ := key.Parse()
if len(keys) == 0 {
keys = key.getPubKeys()
}

2
go.mod
View File

@ -1,6 +1,6 @@
module converge
go 1.22.5
go 1.21.9
require (
github.com/ActiveState/termtest/conpty v0.5.0