better messages when the user modifies the .authorized_keys file from
within the session.
This commit is contained in:
parent
3c803d6125
commit
e9744a7c2f
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user