Deleted Added
full compact
pam_ssh.c (89753) pam_ssh.c (89760)
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>
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 89753 2002-01-24 17:26:27Z des $");
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
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
71/*
72 * Generic cleanup function for SSH "Key" type.
73 */
74
75/*
76 * Generic cleanup function for SSH "Key" type.
77 */
78
75void
76key_cleanup(pam_handle_t *pamh, void *data, int error_status)
79static void
80key_cleanup(pam_handle_t *pamh __unused, void *data, int error_status __unused)
77{
78 if (data)
79 key_free(data);
80}
81
82
83/*
84 * Generic PAM cleanup function for this module.
85 */
86
81{
82 if (data)
83 key_free(data);
84}
85
86
87/*
88 * Generic PAM cleanup function for this module.
89 */
90
87void
88ssh_cleanup(pam_handle_t *pamh, void *data, int error_status)
91static void
92ssh_cleanup(pam_handle_t *pamh __unused, void *data, int error_status __unused)
89{
90 if (data)
91 free(data);
92}
93
94
95/*
96 * Authenticate a user's key by trying to decrypt it with the password
97 * provided. The key and its comment are then stored for later
98 * retrieval by the session phase. An increasing index is embedded in
99 * the PAM variable names so this function may be called multiple times
100 * for multiple keys.
101 */
102
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
103int
107static int
104auth_via_key(pam_handle_t *pamh, int type, const char *file,
105 const char *dir, const struct passwd *user, const char *pass)
106{
107 char *comment; /* private key comment */
108 char *data_name; /* PAM state */
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 */
109 static int index = 0; /* for saved keys */
113 static int indx = 0; /* for saved keys */
110 Key *key; /* user's key */
111 char *path; /* to key files */
112 int retval; /* from calls */
113 uid_t saved_uid; /* caller's uid */
114
115 /* locate the user's private key file */
116 if (!asprintf(&path, "%s/%s", dir, file)) {
117 syslog(LOG_CRIT, "%s: %m", MODULE_NAME);

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

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

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

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

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

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

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

449 env_value, ssh_cleanup);
450 if (retval != PAM_SUCCESS)
451 PAM_RETURN(retval);
452 PAM_LOG("Environment write successful");
453 }
454 }
455 if (env_fp)
456 fclose(env_fp);
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);
457 retval = pclose(pipe);
461 retval = pclose(lpipe);
458 switch (retval) {
459 case -1:
460 syslog(LOG_ERR, "%s: %s: %m", MODULE_NAME, SSH_AGENT);
461 PAM_RETURN(PAM_SESSION_ERR);
462 case 0:
463 break;
464 case 127:
465 syslog(LOG_ERR, "%s: cannot execute %s", MODULE_NAME,

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

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

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

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

--- 36 unchanged lines hidden ---
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 ---