diff options
Diffstat (limited to 'lib/libpam/modules/pam_ssh/pam_ssh.c')
-rw-r--r-- | lib/libpam/modules/pam_ssh/pam_ssh.c | 183 |
1 files changed, 81 insertions, 102 deletions
diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.c b/lib/libpam/modules/pam_ssh/pam_ssh.c index 929ff4f..36c86dd 100644 --- a/lib/libpam/modules/pam_ssh/pam_ssh.c +++ b/lib/libpam/modules/pam_ssh/pam_ssh.c @@ -52,13 +52,10 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #define PAM_SM_AUTH -#define PAM_SM_ACCOUNT #define PAM_SM_SESSION -#define PAM_SM_PASSWORD #include <security/pam_appl.h> #include <security/pam_modules.h> -#include <security/pam_mod_misc.h> #include <security/openpam.h> #include <openssl/dsa.h> @@ -119,8 +116,8 @@ auth_via_key(pam_handle_t *pamh, const char *file, const char *dir, /* locate the user's private key file */ if (!asprintf(&path, "%s/%s", dir, file)) { - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); - return PAM_SERVICE_ERR; + openpam_log(PAM_LOG_ERROR, "%m"); + return (PAM_SERVICE_ERR); } /* Try to decrypt the private key with the passphrase provided. If @@ -128,7 +125,7 @@ auth_via_key(pam_handle_t *pamh, const char *file, const char *dir, comment = NULL; if ((retval = openpam_borrow_cred(pamh, user)) != PAM_SUCCESS) - return retval; + return (retval); key = key_load_private(path, pass, &comment); openpam_restore_cred(pamh); free(path); @@ -136,38 +133,38 @@ auth_via_key(pam_handle_t *pamh, const char *file, const char *dir, comment = strdup(file); if (!key) { free(comment); - return PAM_AUTH_ERR; + return (PAM_AUTH_ERR); } /* save the key and comment to pass to ssh-agent in the session phase */ if (!asprintf(&data_name, "ssh_private_key_%d", key_idx)) { - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + openpam_log(PAM_LOG_ERROR, "%m"); free(comment); - return PAM_SERVICE_ERR; + return (PAM_SERVICE_ERR); } retval = pam_set_data(pamh, data_name, key, key_cleanup); free(data_name); if (retval != PAM_SUCCESS) { key_free(key); free(comment); - return retval; + return (retval); } if (!asprintf(&data_name, "ssh_key_comment_%d", key_idx)) { - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + openpam_log(PAM_LOG_ERROR, "%m"); free(comment); - return PAM_SERVICE_ERR; + return (PAM_SERVICE_ERR); } retval = pam_set_data(pamh, data_name, comment, ssh_cleanup); free(data_name); if (retval != PAM_SUCCESS) { free(comment); - return retval; + return (retval); } ++key_idx; - return PAM_SUCCESS; + return (PAM_SUCCESS); } @@ -202,7 +199,7 @@ add_keys(pam_handle_t *pamh) saved = environ; if ((environ = pam_getenvlist(pamh)) == NULL) { environ = saved; - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + openpam_log(PAM_LOG_ERROR, "%m"); return (PAM_BUF_ERR); } ac = ssh_get_authentication_connection(); @@ -212,8 +209,8 @@ add_keys(pam_handle_t *pamh) environ = saved; } if (!ac) { - openpam_log(PAM_LOG_ERROR, "%s: %s: %m", MODULE_NAME, socket); - return PAM_SESSION_ERR; + openpam_log(PAM_LOG_ERROR, "%m"); + return (PAM_SESSION_ERR); } /* hand off each private key to the agent */ @@ -221,18 +218,18 @@ add_keys(pam_handle_t *pamh) final = 0; for (key_idx = 0; ; key_idx++) { if (!asprintf(&data_name, "ssh_private_key_%d", key_idx)) { - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + openpam_log(PAM_LOG_ERROR, "%m"); ssh_close_authentication_connection(ac); - return PAM_SERVICE_ERR; + return (PAM_SERVICE_ERR); } retval = pam_get_data(pamh, data_name, (const void **)&key); free(data_name); if (retval != PAM_SUCCESS) break; if (!asprintf(&data_name, "ssh_key_comment_%d", key_idx)) { - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + openpam_log(PAM_LOG_ERROR, "%m"); ssh_close_authentication_connection(ac); - return PAM_SERVICE_ERR; + return (PAM_SERVICE_ERR); } retval = pam_get_data(pamh, data_name, (const void **)&comment); @@ -245,19 +242,19 @@ add_keys(pam_handle_t *pamh) } ssh_close_authentication_connection(ac); - return final ? PAM_SUCCESS : PAM_SESSION_ERR; + return (final ? PAM_SUCCESS : PAM_SESSION_ERR); } PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, - int argc, const char **argv) + int argc __unused, const char *argv[] __unused) { int authenticated; /* user authenticated? */ char *dotdir; /* .ssh dir name */ char *file; /* current key file */ - char *keyfiles; /* list of key files to add */ - int options; /* options for pam_get_pass() */ + const char *kfspec; /* list of key files to add */ + char *keyfiles; const char *pass; /* passphrase */ const struct passwd *pwent; /* user's passwd entry */ struct passwd *pwent_keep; /* our own copy */ @@ -265,28 +262,27 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, const char *user; /* username */ keyfiles = NULL; - options = 0; - for (; argc; argc--, argv++) - if (strncmp(*argv, OPT_KEYFILES "=", sizeof OPT_KEYFILES) - == 0) { - if (!(keyfiles = strchr(*argv, '=') + 1)) - return PAM_AUTH_ERR; - } else if (strcmp(*argv, OPT_TRY_FIRST_PASS) == 0) - options |= PAM_OPT_TRY_FIRST_PASS; - else if (strcmp(*argv, OPT_USE_FIRST_PASS) == 0) - options |= PAM_OPT_USE_FIRST_PASS; - + if ((kfspec = openpam_get_option(pamh, OPT_KEYFILES)) != NULL) { + if ((kfspec = strchr(kfspec, '=')) == NULL) { + openpam_log(PAM_LOG_ERROR, "invalid keyfile list"); + return (PAM_SERVICE_ERR); + } + ++kfspec; + } else { + kfspec = DEF_KEYFILES; + } if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) - return retval; - if (!((pwent = getpwnam(user)) && pwent->pw_dir)) - return PAM_AUTH_ERR; + return (retval); + if (user == NULL || (pwent = getpwnam(user)) == NULL || + pwent->pw_dir == NULL || pwent->pw_dir[0] == '\0') + return (PAM_AUTH_ERR); /* pass prompt message to application and receive passphrase */ retval = pam_get_authtok(pamh, PAM_AUTHTOK, &pass, NEED_PASSPHRASE); if (retval != PAM_SUCCESS) - return retval; + return (retval); OpenSSL_add_all_algorithms(); /* required for DSA */ @@ -295,50 +291,51 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, session phase */ if (!asprintf(&dotdir, "%s/%s", pwent->pw_dir, SSH_CLIENT_DIR)) { - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); - return PAM_SERVICE_ERR; + openpam_log(PAM_LOG_ERROR, "%m"); + return (PAM_SERVICE_ERR); } authenticated = 0; - keyfiles = strdup(keyfiles ? keyfiles : DEF_KEYFILES); + keyfiles = strdup(kfspec); for (file = strtok(keyfiles, SEP_KEYFILES); file; file = strtok(NULL, SEP_KEYFILES)) if (auth_via_key(pamh, file, dotdir, pwent, pass) == PAM_SUCCESS) authenticated++; - free(dotdir); free(keyfiles); + free(dotdir); if (!authenticated) - return PAM_AUTH_ERR; + return (PAM_AUTH_ERR); /* copy the passwd entry (in case successive calls are made) and save it for the session phase */ if (!(pwent_keep = malloc(sizeof *pwent))) { openpam_log(PAM_LOG_ERROR, "%m"); - return PAM_SERVICE_ERR; + return (PAM_SERVICE_ERR); } (void) memcpy(pwent_keep, pwent, sizeof *pwent_keep); if ((retval = pam_set_data(pamh, "ssh_passwd_entry", pwent_keep, ssh_cleanup)) != PAM_SUCCESS) { free(pwent_keep); - return retval; + return (retval); } - return PAM_SUCCESS; + return (PAM_SUCCESS); } PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, - int argc __unused, const char **argv __unused) + int argc __unused, const char *argv[] __unused) { - return PAM_SUCCESS; + + return (PAM_SUCCESS); } PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags __unused, - int argc __unused, const char **argv __unused) + int argc __unused, const char *argv[] __unused) { char *agent_socket; /* agent socket */ char *env_end; /* end of env */ @@ -359,7 +356,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, /* dump output of ssh-agent in ~/.ssh */ if ((retval = pam_get_data(pamh, "ssh_passwd_entry", (const void **)&pwent)) != PAM_SUCCESS) - return retval; + return (retval); /* * Use reference counts to limit agents to one per user per host. @@ -379,8 +376,8 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, (void) gethostname(hname, sizeof hname); if (asprintf(&per_agent, "%s/.ssh/agent-%s", pwent->pw_dir, hname) == -1) { - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); - return PAM_SERVICE_ERR; + openpam_log(PAM_LOG_ERROR, "%m"); + return (PAM_SERVICE_ERR); } /* save the per-agent filename in case we want to delete it on @@ -389,14 +386,14 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, if ((retval = pam_set_data(pamh, "ssh_agent_env_agent", per_agent, ssh_cleanup)) != PAM_SUCCESS) { free(per_agent); - return retval; + return (retval); } /* take on the user's privileges for writing files and starting the agent */ if ((retval = openpam_borrow_cred(pamh, pwent)) != PAM_SUCCESS) - return retval; + return (retval); /* Try to create the per-agent file or open it for reading if it exists. If we can't do either, we won't try to link a @@ -416,11 +413,10 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, env_read = popen(SSH_AGENT, "r"); openpam_restore_cred(pamh); if (!env_read) { - openpam_log(PAM_LOG_ERROR, "%s: %s: %m", MODULE_NAME, - SSH_AGENT); + openpam_log(PAM_LOG_ERROR, "%s: %m", SSH_AGENT); if (env_write >= 0) (void) close(env_write); - return PAM_SESSION_ERR; + return (PAM_SESSION_ERR); } } @@ -451,7 +447,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, (void) close(env_write); if (agent_socket) free(agent_socket); - return PAM_SERVICE_ERR; + return (PAM_SERVICE_ERR); } *env_value++ = '\0'; @@ -463,7 +459,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, if (strcmp(&env_string[strlen(env_string) - strlen(ENV_SOCKET_SUFFIX)], ENV_SOCKET_SUFFIX) == 0 && !(agent_socket = strdup(env_value))) { - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + openpam_log(PAM_LOG_ERROR, "%m"); if (start_agent) (void) pclose(env_read); else @@ -472,7 +468,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, (void) close(env_write); if (agent_socket) free(agent_socket); - return PAM_SERVICE_ERR; + return (PAM_SERVICE_ERR); } else if (strcmp(&env_string[strlen(env_string) - strlen(ENV_PID_SUFFIX)], ENV_PID_SUFFIX) == 0 && ((agent_pid = strdup(env_value)) == NULL || @@ -488,7 +484,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, free(agent_socket); if (agent_pid) free(agent_pid); - return retval; + return (retval); } } @@ -498,56 +494,54 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, if (start_agent) { switch (retval = pclose(env_read)) { case -1: - openpam_log(PAM_LOG_ERROR, "%s: %s: %m", MODULE_NAME, - SSH_AGENT); + openpam_log(PAM_LOG_ERROR, "%s: %m", SSH_AGENT); if (agent_socket) free(agent_socket); - return PAM_SESSION_ERR; + return (PAM_SESSION_ERR); case 0: break; case 127: - openpam_log(PAM_LOG_ERROR, "%s: cannot execute %s", - MODULE_NAME, SSH_AGENT); + openpam_log(PAM_LOG_ERROR, "cannot execute %s", + SSH_AGENT); if (agent_socket) free(agent_socket); - return PAM_SESSION_ERR; + return (PAM_SESSION_ERR); default: - openpam_log(PAM_LOG_ERROR, "%s: %s exited %s %d", - MODULE_NAME, + openpam_log(PAM_LOG_ERROR, "%s exited %s %d", SSH_AGENT, WIFSIGNALED(retval) ? "on signal" : "with status", WIFSIGNALED(retval) ? WTERMSIG(retval) : WEXITSTATUS(retval)); if (agent_socket) free(agent_socket); - return PAM_SESSION_ERR; + return (PAM_SESSION_ERR); } } else (void) fclose(env_read); if (!agent_socket) - return PAM_SESSION_ERR; + return (PAM_SESSION_ERR); if (start_agent && (retval = add_keys(pamh)) != PAM_SUCCESS) - return retval; + return (retval); free(agent_socket); /* if we couldn't access the per-agent file, don't link a per-session filename to it */ if (no_link) - return PAM_SUCCESS; + return (PAM_SUCCESS); /* the per-session file contains the display name or tty name as well as the hostname */ if ((retval = pam_get_item(pamh, PAM_TTY, (const void **)&tty)) != PAM_SUCCESS) - return retval; + return (retval); if (asprintf(&per_session, "%s/.ssh/agent-%s-%s", pwent->pw_dir, hname, tty) == -1) { - openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); - return PAM_SERVICE_ERR; + openpam_log(PAM_LOG_ERROR, "%m"); + return (PAM_SERVICE_ERR); } /* save the per-session filename so we can delete it on session @@ -556,19 +550,19 @@ pam_sm_open_session(pam_handle_t *pamh, int flags __unused, if ((retval = pam_set_data(pamh, "ssh_agent_env_session", per_session, ssh_cleanup)) != PAM_SUCCESS) { free(per_session); - return retval; + return (retval); } (void) unlink(per_session); /* remove cruft */ (void) link(per_agent, per_session); - return PAM_SUCCESS; + return (PAM_SUCCESS); } PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags __unused, - int argc __unused, const char **argv __unused) + int argc __unused, const char *argv[] __unused) { const char *env_file; /* ssh-agent environment */ pid_t pid; /* ssh-agent process id */ @@ -588,7 +582,7 @@ pam_sm_close_session(pam_handle_t *pamh, int flags __unused, (const void **)&env_file)) == PAM_SUCCESS && env_file && stat(env_file, &sb) == 0) { if (sb.st_nlink > 1) - return PAM_SUCCESS; + return (PAM_SUCCESS); (void) unlink(env_file); } @@ -596,35 +590,20 @@ pam_sm_close_session(pam_handle_t *pamh, int flags __unused, if ((retval = pam_get_data(pamh, "ssh_agent_pid", (const void **)&ssh_agent_pid)) != PAM_SUCCESS) - return retval; + return (retval); /* Kill the agent. SSH's ssh-agent does not have a -k option, so just call kill(). */ pid = atoi(ssh_agent_pid); if (pid <= 0) - return PAM_SESSION_ERR; + return (PAM_SESSION_ERR); if (kill(pid, SIGTERM) != 0) { - openpam_log(PAM_LOG_ERROR, "%s: %s: %m", MODULE_NAME, - ssh_agent_pid); - return PAM_SESSION_ERR; + openpam_log(PAM_LOG_ERROR, "%s: %m", ssh_agent_pid); + return (PAM_SESSION_ERR); } - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, - int argc __unused, const char **argv __unused) -{ - return (PAM_IGNORE); -} - -PAM_EXTERN int -pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, - int argc __unused, const char **argv __unused) -{ - return (PAM_IGNORE); + return (PAM_SUCCESS); } PAM_MODULE_ENTRY(MODULE_NAME); |