The module needs to read authorized ssh keys from file. Tests validate the file name and content. This first implementation reads only one key, support for multiple keys would be added later. Fancy ways to obtain auth keys need to be implemented in separate modules and keys would be shared via PAM environment (to be implemented). Signed-off-by: Domenico Andreoli <domenico.andreoli@xxxxxxxxx> --- pam-ssh-agent.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ regress/pam-ssh-agent.sh | 24 +++++++++++++++--- 2 files changed, 84 insertions(+), 4 deletions(-) Index: b/pam-ssh-agent.c =================================================================== --- a/pam-ssh-agent.c +++ b/pam-ssh-agent.c @@ -35,7 +35,12 @@ #include <pam/pam_modules.h> #endif +#include "authfile.h" +#include "authfd.h" +#include "ssherr.h" + static int pam_debug; +static const char *auth_file; static int parse_args(int argc, const char **argv) @@ -45,6 +50,14 @@ parse_args(int argc, const char **argv) for (i=0; i!=argc; i++) { if (!strcmp(argv[i], "debug")) { pam_debug = 1; + } else if (!strncmp(argv[i], "file=", 5)) { + if (argv[i][5] == '\0') + continue; + auth_file = argv[i] + 5; + if (auth_file[0] != '/') { + syslog(LOG_ERR, "auth file error: Path is not absolute: %s", auth_file); + invalid++; + } } else { syslog(LOG_ERR, "invalid argument: %s", argv[i]); invalid++; @@ -54,9 +67,37 @@ parse_args(int argc, const char **argv) return invalid; } +static int +ssh_read_identitylist(const char *filename, struct ssh_identitylist **idlp) +{ + struct ssh_identitylist *idl = NULL; + int r; + + if ((idl = calloc(1, sizeof(*idl))) == NULL || + (idl->keys = calloc(1, sizeof(*idl->keys))) == NULL || + (idl->comments = calloc(1, sizeof(*idl->comments))) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + + r = sshkey_load_public(filename, &idl->keys[0], &idl->comments[0]); + if (r) + goto out; + + idl->nkeys = 1; + *idlp = idl; + idl = NULL; + +out: + if (idl != NULL) + ssh_free_identitylist(idl); + return r; +} + int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { + struct ssh_identitylist *auth_ids = NULL; int ret; openlog("pam_ssh_agent_auth", 0, LOG_AUTHPRIV); @@ -70,11 +111,34 @@ pam_sm_authenticate(pam_handle_t *pamh, const char *user = "(unknown)"; pam_get_user(pamh, &user, NULL); syslog(LOG_DEBUG, "USER: %s", user); + syslog(LOG_DEBUG, "FILE: %s", auth_file ? auth_file : "(null)"); + } + + if (auth_file == NULL) { + syslog(LOG_ERR, "auth file error: file= is not specified"); + ret = PAM_SERVICE_ERR; + goto out; + } + + ret = ssh_read_identitylist(auth_file, &auth_ids); + if (ret) { + syslog(LOG_ERR, "auth file error: %s: %s", ssh_err(ret), auth_file); + ret = PAM_AUTHINFO_UNAVAIL; + goto out; + } + + if (pam_debug) { + unsigned i; + syslog(LOG_DEBUG, "auth file has %u key(s):", (unsigned) auth_ids->nkeys); + for (i=0; i!=auth_ids->nkeys; i++) + syslog(LOG_DEBUG, " %d) %s", i, auth_ids->comments[i]); } ret = PAM_SUCCESS; out: + if (auth_ids != NULL) + ssh_free_identitylist(auth_ids); if (pam_debug) syslog(LOG_DEBUG, "result: %s", pam_strerror(pamh, ret)); closelog(); Index: b/regress/pam-ssh-agent.sh =================================================================== --- a/regress/pam-ssh-agent.sh +++ b/regress/pam-ssh-agent.sh @@ -14,9 +14,13 @@ export PAM_WRAPPER_SERVICE_DIR=$OBJ/pam- PAM_SUCCESS=0 PAM_SERVICE_ERR=3 +PAM_AUTHINFO_UNAVAIL=9 . $OBJ/keytype_gen.sh +first_kt=`echo $ktypes | cut -d" " -f1` +AUTH_FILE=$OBJ/key.$first_kt.pub + pam_agent_test() { rm -rf $PAM_WRAPPER_SERVICE_DIR @@ -36,8 +40,20 @@ EOF trace "invalid arguments" expect=$PAM_SERVICE_ERR pam_agent_test invalid arguments -trace "debug argument" -expect=$PAM_SUCCESS pam_agent_test debug - trace "without arguments" -expect=$PAM_SUCCESS pam_agent_test +expect=$PAM_SERVICE_ERR pam_agent_test # file= is required + +trace "with non-absolute auth file path" +expect=$PAM_SERVICE_ERR pam_agent_test file=nonabsolute.$$ + +trace "with non-existent auth file" +expect=$PAM_AUTHINFO_UNAVAIL pam_agent_test file=/nonexistent.$$ + +trace "with empty auth file" +expect=$PAM_AUTHINFO_UNAVAIL pam_agent_test file=/dev/null + +trace "authenticate agent (debug)" +expect=$PAM_SUCCESS pam_agent_test file=$AUTH_FILE debug + +trace "authenticate agent (non-debug)" +expect=$PAM_SUCCESS pam_agent_test file=$AUTH_FILE _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev