better messages when the user modifies the .authorized_keys file from
within the session.
This commit is contained in:
		
							parent
							
								
									d109c72f66
								
							
						
					
					
						commit
						d134f1e944
					
				| @ -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