Deleted Added
sdiff udiff text old ( 89753 ) new ( 89760 )
full compact
1/*-
2 * Copyright (c) 1999, 2000 Andrew J. Korty
3 * All rights reserved.
4 * Copyright (c) 2001 Networks Associates Technologies, Inc.
5 * All rights reserved.
6 *
7 * Portions of this software were developed for the FreeBSD Project by
8 * ThinkSec AS and NAI Labs, the Security Research Division of Network

--- 21 unchanged lines hidden (view full) ---

30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: head/lib/libpam/modules/pam_ssh/pam_ssh.c 89760 2002-01-24 18:37:17Z markm $");
39
40#include <sys/param.h>
41#include <sys/socket.h>
42#include <sys/stat.h>
43#include <sys/wait.h>
44
45#include <dirent.h>
46#include <pwd.h>

--- 16 unchanged lines hidden (view full) ---

63#include <openssl/evp.h>
64
65#include "key.h"
66#include "authfd.h"
67#include "authfile.h"
68#include "log.h"
69#include "pam_ssh.h"
70
71static int auth_via_key(pam_handle_t *, int, const char *, const char *, const struct passwd *, const char *);
72static void key_cleanup(pam_handle_t *, void *, int);
73static void ssh_cleanup(pam_handle_t *, void *, int);
74
75/*
76 * Generic cleanup function for SSH "Key" type.
77 */
78
79static void
80key_cleanup(pam_handle_t *pamh __unused, void *data, int error_status __unused)
81{
82 if (data)
83 key_free(data);
84}
85
86
87/*
88 * Generic PAM cleanup function for this module.
89 */
90
91static void
92ssh_cleanup(pam_handle_t *pamh __unused, void *data, int error_status __unused)
93{
94 if (data)
95 free(data);
96}
97
98
99/*
100 * Authenticate a user's key by trying to decrypt it with the password
101 * provided. The key and its comment are then stored for later
102 * retrieval by the session phase. An increasing index is embedded in
103 * the PAM variable names so this function may be called multiple times
104 * for multiple keys.
105 */
106
107static int
108auth_via_key(pam_handle_t *pamh, int type, const char *file,
109 const char *dir, const struct passwd *user, const char *pass)
110{
111 char *comment; /* private key comment */
112 char *data_name; /* PAM state */
113 static int indx = 0; /* for saved keys */
114 Key *key; /* user's key */
115 char *path; /* to key files */
116 int retval; /* from calls */
117 uid_t saved_uid; /* caller's uid */
118
119 /* locate the user's private key file */
120 if (!asprintf(&path, "%s/%s", dir, file)) {
121 syslog(LOG_CRIT, "%s: %m", MODULE_NAME);

--- 9 unchanged lines hidden (view full) ---

131 free(path);
132 seteuid(saved_uid);
133 if (key == NULL)
134 return PAM_AUTH_ERR;
135 /*
136 * Save the key and comment to pass to ssh-agent in the session
137 * phase.
138 */
139 if (!asprintf(&data_name, "ssh_private_key_%d", indx)) {
140 syslog(LOG_CRIT, "%s: %m", MODULE_NAME);
141 free(comment);
142 return PAM_SERVICE_ERR;
143 }
144 retval = pam_set_data(pamh, data_name, key, key_cleanup);
145 free(data_name);
146 if (retval != PAM_SUCCESS) {
147 key_free(key);
148 free(comment);
149 return retval;
150 }
151 if (!asprintf(&data_name, "ssh_key_comment_%d", indx)) {
152 syslog(LOG_CRIT, "%s: %m", MODULE_NAME);
153 free(comment);
154 return PAM_SERVICE_ERR;
155 }
156 retval = pam_set_data(pamh, data_name, comment, ssh_cleanup);
157 free(data_name);
158 if (retval != PAM_SUCCESS) {
159 free(comment);
160 return retval;
161 }
162 ++indx;
163 return PAM_SUCCESS;
164}
165
166
167PAM_EXTERN int
168pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv)
169{
170 struct options options; /* module options */
171 int authenticated; /* user authenticated? */
172 char *dotdir; /* .ssh2 dir name */
173 struct dirent *dotdir_ent; /* .ssh2 dir entry */
174 DIR *dotdir_p; /* .ssh2 dir pointer */
175 const char *pass; /* passphrase */
176 struct passwd *pwd; /* user's passwd entry */

--- 106 unchanged lines hidden (view full) ---

283
284 PAM_LOG("Saved ssh_passwd_entry");
285
286 PAM_RETURN(PAM_SUCCESS);
287}
288
289
290PAM_EXTERN int
291pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv)
292{
293 struct options options; /* module options */
294
295 pam_std_option(&options, NULL, argc, argv);
296
297 PAM_LOG("Options processed");
298
299 PAM_RETURN(PAM_SUCCESS);
300}
301
302PAM_EXTERN int
303pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv)
304{
305 struct options options;
306
307 pam_std_option(&options, NULL, argc, argv);
308
309 PAM_LOG("Options processed");
310
311 PAM_RETURN(PAM_IGNORE);
312}
313
314PAM_EXTERN int
315pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv)
316{
317 struct options options;
318
319 pam_std_option(&options, NULL, argc, argv);
320
321 PAM_LOG("Options processed");
322
323 PAM_RETURN(PAM_IGNORE);
324}
325
326typedef AuthenticationConnection AC;
327
328PAM_EXTERN int
329pam_sm_open_session(pam_handle_t *pamh, int flags __unused, int argc, const char **argv)
330{
331 struct options options; /* module options */
332 AC *ac; /* to ssh-agent */
333 char *agent_socket; /* agent socket */
334 char *comment; /* on private key */
335 char *env_end; /* end of env */
336 char *env_file; /* to store env */
337 FILE *env_fp; /* env_file handle */
338 char *env_value; /* envariable value */
339 char *data_name; /* PAM state */
340 int final; /* final return value */
341 int indx; /* for saved keys */
342 Key *key; /* user's private key */
343 FILE *lpipe; /* ssh-agent handle */
344 struct passwd *pwd; /* user's passwd entry */
345 int retval; /* from calls */
346 uid_t saved_uid; /* caller's uid */
347 const char *tty; /* tty or display name */
348 char hname[MAXHOSTNAMELEN]; /* local hostname */
349 char env_string[BUFSIZ]; /* environment string */
350
351 pam_std_option(&options, NULL, argc, argv);

--- 40 unchanged lines hidden (view full) ---

392 PAM_LOG("Saved env_file");
393
394 /* start the agent as the user */
395 saved_uid = geteuid();
396 seteuid(pwd->pw_uid);
397 env_fp = fopen(env_file, "w");
398 if (env_fp != NULL)
399 chmod(env_file, S_IRUSR);
400 lpipe = popen(SSH_AGENT, "r");
401 seteuid(saved_uid);
402 if (!lpipe) {
403 syslog(LOG_ERR, "%s: %s: %m", MODULE_NAME, SSH_AGENT);
404 if (env_fp)
405 fclose(env_fp);
406 PAM_RETURN(PAM_SESSION_ERR);
407 }
408
409 PAM_LOG("Agent started as user");
410
411 /*
412 * Save environment for application with pam_putenv().
413 */
414 agent_socket = NULL;
415 while (fgets(env_string, sizeof env_string, lpipe)) {
416 if (env_fp)
417 fputs(env_string, env_fp);
418 env_value = strchr(env_string, '=');
419 if (env_value == NULL)
420 continue;
421 env_end = strchr(env_value, ';');
422 if (env_end == NULL)
423 continue;
424 *env_end = '\0';
425 /* pass to the application ... */
426 retval = pam_putenv(pamh, env_string);
427 if (retval != PAM_SUCCESS) {
428 pclose(lpipe);
429 if (env_fp)
430 fclose(env_fp);
431 PAM_RETURN(PAM_SERVICE_ERR);
432 }
433
434 PAM_LOG("Put to environment: %s", env_string);
435
436 *env_value++ = '\0';

--- 16 unchanged lines hidden (view full) ---

453 env_value, ssh_cleanup);
454 if (retval != PAM_SUCCESS)
455 PAM_RETURN(retval);
456 PAM_LOG("Environment write successful");
457 }
458 }
459 if (env_fp)
460 fclose(env_fp);
461 retval = pclose(lpipe);
462 switch (retval) {
463 case -1:
464 syslog(LOG_ERR, "%s: %s: %m", MODULE_NAME, SSH_AGENT);
465 PAM_RETURN(PAM_SESSION_ERR);
466 case 0:
467 break;
468 case 127:
469 syslog(LOG_ERR, "%s: cannot execute %s", MODULE_NAME,

--- 17 unchanged lines hidden (view full) ---

487 syslog(LOG_ERR, "%s: %s: %m", MODULE_NAME, agent_socket);
488 PAM_RETURN(PAM_SESSION_ERR);
489 }
490
491 PAM_LOG("Connected to agent");
492
493 /* hand off each private key to the agent */
494 final = 0;
495 for (indx = 0; ; indx++) {
496 if (!asprintf(&data_name, "ssh_private_key_%d", indx)) {
497 syslog(LOG_CRIT, "%s: %m", MODULE_NAME);
498 ssh_close_authentication_connection(ac);
499 PAM_RETURN(PAM_SERVICE_ERR);
500 }
501 retval = pam_get_data(pamh, data_name, (const void **)&key);
502 free(data_name);
503 if (retval != PAM_SUCCESS)
504 break;
505 if (!asprintf(&data_name, "ssh_key_comment_%d", indx)) {
506 syslog(LOG_CRIT, "%s: %m", MODULE_NAME);
507 ssh_close_authentication_connection(ac);
508 PAM_RETURN(PAM_SERVICE_ERR);
509 }
510 retval = pam_get_data(pamh, data_name, (const void **)&comment);
511 free(data_name);
512 if (retval != PAM_SUCCESS)
513 break;

--- 5 unchanged lines hidden (view full) ---

519
520 PAM_LOG("Keys handed off");
521
522 PAM_RETURN(final ? PAM_SUCCESS : PAM_SESSION_ERR);
523}
524
525
526PAM_EXTERN int
527pam_sm_close_session(pam_handle_t *pamh, int flags __unused, int argc, const char **argv)
528{
529 struct options options; /* module options */
530 const char *env_file; /* ssh-agent environment */
531 pid_t pid; /* ssh-agent process id */
532 int retval; /* from calls */
533 const char *ssh_agent_pid; /* ssh-agent pid string */
534
535 pam_std_option(&options, NULL, argc, argv);

--- 36 unchanged lines hidden ---