Fri Dec 16 17:30:12 2011 UTC ()
-remove remainders of the misguided changes in revs 1.5-1.9
-iron out more unnecessary differences to FreeBSD


(drochner)
diff -r1.17 -r1.18 src/lib/libpam/modules/pam_ssh/pam_ssh.c

cvs diff -r1.17 -r1.18 src/lib/libpam/modules/pam_ssh/pam_ssh.c (expand / switch to unified diff)

--- src/lib/libpam/modules/pam_ssh/pam_ssh.c 2011/05/06 17:22:09 1.17
+++ src/lib/libpam/modules/pam_ssh/pam_ssh.c 2011/12/16 17:30:12 1.18
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pam_ssh.c,v 1.17 2011/05/06 17:22:09 drochner Exp $ */ 1/* $NetBSD: pam_ssh.c,v 1.18 2011/12/16 17:30:12 drochner Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003 Networks Associates Technology, Inc. 4 * Copyright (c) 2003 Networks Associates Technology, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This software was developed for the FreeBSD Project by ThinkSec AS and 7 * This software was developed for the FreeBSD Project by ThinkSec AS and
8 * NAI Labs, the Security Research Division of Network Associates, Inc. 8 * NAI Labs, the Security Research Division of Network Associates, Inc.
9 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 9 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
10 * DARPA CHATS research program. 10 * DARPA CHATS research program.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE. 34 * SUCH DAMAGE.
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38#ifdef __FreeBSD__ 38#ifdef __FreeBSD__
39__FBSDID("$FreeBSD: src/lib/libpam/modules/pam_ssh/pam_ssh.c,v 1.40 2004/02/10 10:13:21 des Exp $"); 39__FBSDID("$FreeBSD: src/lib/libpam/modules/pam_ssh/pam_ssh.c,v 1.40 2004/02/10 10:13:21 des Exp $");
40#else 40#else
41__RCSID("$NetBSD: pam_ssh.c,v 1.17 2011/05/06 17:22:09 drochner Exp $"); 41__RCSID("$NetBSD: pam_ssh.c,v 1.18 2011/12/16 17:30:12 drochner Exp $");
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/wait.h> 45#include <sys/wait.h>
46 46
47#include <errno.h> 47#include <errno.h>
48#include <fcntl.h> 48#include <fcntl.h>
49#include <paths.h> 49#include <paths.h>
50#include <pwd.h> 50#include <pwd.h>
51#include <signal.h> 51#include <signal.h>
52#include <stdio.h> 52#include <stdio.h>
53#include <string.h> 53#include <string.h>
54#include <unistd.h> 54#include <unistd.h>
@@ -57,62 +57,64 @@ __RCSID("$NetBSD: pam_ssh.c,v 1.17 2011/ @@ -57,62 +57,64 @@ __RCSID("$NetBSD: pam_ssh.c,v 1.17 2011/
57#define PAM_SM_SESSION 57#define PAM_SM_SESSION
58 58
59#include <security/pam_appl.h> 59#include <security/pam_appl.h>
60#include <security/pam_modules.h> 60#include <security/pam_modules.h>
61#include <security/openpam.h> 61#include <security/openpam.h>
62 62
63#include <openssl/evp.h> 63#include <openssl/evp.h>
64 64
65#include "key.h" 65#include "key.h"
66#include "buffer.h" 66#include "buffer.h"
67#include "authfd.h" 67#include "authfd.h"
68#include "authfile.h" 68#include "authfile.h"
69 69
 70#define ssh_add_identity(auth, key, comment) \
 71 ssh_add_identity_constrained(auth, key, comment, 0, 0)
 72
70extern char **environ; 73extern char **environ;
71 74
72struct pam_ssh_key { 75struct pam_ssh_key {
73 Key *key; 76 Key *key;
74 char *comment; 77 char *comment;
75}; 78};
76 79
77static const char *pam_ssh_prompt = "SSH passphrase: "; 80static const char *pam_ssh_prompt = "SSH passphrase: ";
78static const char *pam_ssh_have_keys = "pam_ssh_have_keys"; 81static const char *pam_ssh_have_keys = "pam_ssh_have_keys";
79 82
80static const char *pam_ssh_keyfiles[] = { 83static const char *pam_ssh_keyfiles[] = {
81 ".ssh/identity", /* SSH1 RSA key */ 84 ".ssh/identity", /* SSH1 RSA key */
82 ".ssh/id_rsa", /* SSH2 RSA key */ 85 ".ssh/id_rsa", /* SSH2 RSA key */
83 ".ssh/id_dsa", /* SSH2 DSA key */ 86 ".ssh/id_dsa", /* SSH2 DSA key */
84 NULL 87 NULL
85}; 88};
86 89
87static const char *pam_ssh_agent = "/usr/bin/ssh-agent"; 90static const char *pam_ssh_agent = "/usr/bin/ssh-agent";
88static const char *pam_ssh_agent_argv[] = { "ssh_agent", "-s", NULL }; 91static const char *const pam_ssh_agent_argv[] = { "ssh_agent", "-s", NULL };
89static const char *pam_ssh_agent_envp[] = { NULL }; 92static const char *const pam_ssh_agent_envp[] = { NULL };
90 93
91/* 94/*
92 * Attempts to load a private key from the specified file in the specified 95 * Attempts to load a private key from the specified file in the specified
93 * directory, using the specified passphrase. If successful, returns a 96 * directory, using the specified passphrase. If successful, returns a
94 * struct pam_ssh_key containing the key and its comment. 97 * struct pam_ssh_key containing the key and its comment.
95 */ 98 */
96static struct pam_ssh_key * 99static struct pam_ssh_key *
97pam_ssh_load_key(struct passwd *pwd, const char *kfn, const char *passphrase) 100pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase)
98{ 101{
99 struct pam_ssh_key *psk; 102 struct pam_ssh_key *psk;
100 char fn[PATH_MAX]; 103 char fn[PATH_MAX];
101 char *comment; 104 char *comment;
102 Key *key; 105 Key *key;
103 106
104 if (snprintf(fn, sizeof(fn), "%s/%s", pwd->pw_dir, kfn) > 107 if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn))
105 (int)sizeof(fn)) 
106 return (NULL); 108 return (NULL);
107 comment = NULL; 109 comment = NULL;
108 key = key_load_private(fn, passphrase, &comment); 110 key = key_load_private(fn, passphrase, &comment);
109 if (key == NULL) { 111 if (key == NULL) {
110 openpam_log(PAM_LOG_DEBUG, "failed to load key from %s", fn); 112 openpam_log(PAM_LOG_DEBUG, "failed to load key from %s", fn);
111 if (comment != NULL) 113 if (comment != NULL)
112 free(comment); 114 free(comment);
113 return (NULL); 115 return (NULL);
114 } 116 }
115 117
116 openpam_log(PAM_LOG_DEBUG, "loaded '%s' from %s", comment, fn); 118 openpam_log(PAM_LOG_DEBUG, "loaded '%s' from %s", comment, fn);
117 if ((psk = malloc(sizeof(*psk))) == NULL) { 119 if ((psk = malloc(sizeof(*psk))) == NULL) {
118 key_free(key); 120 key_free(key);
@@ -134,78 +136,65 @@ pam_ssh_free_key(pam_handle_t *pamh __un @@ -134,78 +136,65 @@ pam_ssh_free_key(pam_handle_t *pamh __un
134 struct pam_ssh_key *psk; 136 struct pam_ssh_key *psk;
135 137
136 psk = data; 138 psk = data;
137 key_free(psk->key); 139 key_free(psk->key);
138 free(psk->comment); 140 free(psk->comment);
139 free(psk); 141 free(psk);
140} 142}
141 143
142PAM_EXTERN int 144PAM_EXTERN int
143pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, 145pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
144 int argc __unused, const char *argv[] __unused) 146 int argc __unused, const char *argv[] __unused)
145{ 147{
146 const char **kfn, *passphrase, *user; 148 const char **kfn, *passphrase, *user;
 149 const void *item;
147 struct passwd *pwd, pwres; 150 struct passwd *pwd, pwres;
148 struct pam_ssh_key *psk; 151 struct pam_ssh_key *psk;
149 int nkeys, pam_err, pass; 152 int nkeys, pam_err, pass;
150 char pwbuf[1024]; 153 char pwbuf[1024];
151 154
152 /* PEM is not loaded by default */ 155 /* PEM is not loaded by default */
153 OpenSSL_add_all_algorithms(); 156 OpenSSL_add_all_algorithms();
154 157
155 /* get user name and home directory */ 158 /* get user name and home directory */
156 pam_err = pam_get_user(pamh, &user, NULL); 159 pam_err = pam_get_user(pamh, &user, NULL);
157 if (pam_err != PAM_SUCCESS) 160 if (pam_err != PAM_SUCCESS)
158 return (pam_err); 161 return (pam_err);
159 if (getpwnam_r(user, &pwres, pwbuf, sizeof(pwbuf), &pwd) != 0 || 162 if (getpwnam_r(user, &pwres, pwbuf, sizeof(pwbuf), &pwd) != 0 ||
160 pwd == NULL) 163 pwd == NULL)
161 return (PAM_USER_UNKNOWN); 164 return (PAM_USER_UNKNOWN);
162 if (pwd->pw_dir == NULL) 165 if (pwd->pw_dir == NULL)
163 return (PAM_AUTH_ERR); 166 return (PAM_AUTH_ERR);
164 167
165 /* switch to user credentials */ 168 /* switch to user credentials */
166 pam_err = openpam_borrow_cred(pamh, pwd); 169 pam_err = openpam_borrow_cred(pamh, pwd);
167 if (pam_err != PAM_SUCCESS) 170 if (pam_err != PAM_SUCCESS)
168 return (pam_err); 171 return (pam_err);
169 172
170#ifdef notyet 173 pass = (pam_get_item(pamh, PAM_AUTHTOK, &item) == PAM_SUCCESS &&
171 for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) { 174 item != NULL);
172 char path[MAXPATHLEN]; 
173 (void)snprintf(path, sizeof(path), "%s/%s", pwd->pw_dir, *kfn); 
174 if (access(path, R_OK) == 0) 
175 break; 
176 } 
177 
178 if (*kfn == NULL) { 
179 openpam_restore_cred(pamh); 
180 return (PAM_AUTH_ERR); 
181 } 
182#endif 
183 
184 pass = (pam_get_item(pamh, PAM_AUTHTOK, 
185 (const void **)__UNCONST(&passphrase)) == PAM_SUCCESS); 
186 load_keys: 175 load_keys:
187 /* get passphrase */ 176 /* get passphrase */
188 pam_err = pam_get_authtok(pamh, PAM_AUTHTOK, 177 pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
189 &passphrase, pam_ssh_prompt); 178 &passphrase, pam_ssh_prompt);
190 if (pam_err != PAM_SUCCESS) { 179 if (pam_err != PAM_SUCCESS) {
191 openpam_restore_cred(pamh); 180 openpam_restore_cred(pamh);
192 return (pam_err); 181 return (pam_err);
193 } 182 }
194 183
195 /* try to load keys from all keyfiles we know of */ 184 /* try to load keys from all keyfiles we know of */
196 nkeys = 0; 185 nkeys = 0;
197 for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) { 186 for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) {
198 psk = pam_ssh_load_key(pwd, *kfn, passphrase); 187 psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase);
199 if (psk != NULL) { 188 if (psk != NULL) {
200 pam_set_data(pamh, *kfn, psk, pam_ssh_free_key); 189 pam_set_data(pamh, *kfn, psk, pam_ssh_free_key);
201 ++nkeys; 190 ++nkeys;
202 } 191 }
203 } 192 }
204 193
205 /* 194 /*
206 * If we tried an old token and didn't get anything, and 195 * If we tried an old token and didn't get anything, and
207 * try_first_pass was specified, try again after prompting the 196 * try_first_pass was specified, try again after prompting the
208 * user for a new passphrase. 197 * user for a new passphrase.
209 */ 198 */
210 if (nkeys == 0 && pass == 1 && 199 if (nkeys == 0 && pass == 1 &&
211 openpam_get_option(pamh, "try_first_pass") != NULL) { 200 openpam_get_option(pamh, "try_first_pass") != NULL) {
@@ -366,27 +355,27 @@ pam_ssh_add_keys_to_agent(pam_handle_t * @@ -366,27 +355,27 @@ pam_ssh_add_keys_to_agent(pam_handle_t *
366 openpam_log(PAM_LOG_DEBUG, 355 openpam_log(PAM_LOG_DEBUG,
367 "%s: cannot get authentication connection", 356 "%s: cannot get authentication connection",
368 __func__); 357 __func__);
369 pam_err = PAM_SYSTEM_ERR; 358 pam_err = PAM_SYSTEM_ERR;
370 goto end; 359 goto end;
371 } 360 }
372 361
373 /* look for keys to add to it */ 362 /* look for keys to add to it */
374 for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) { 363 for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) {
375 const void *vp; 364 const void *vp;
376 pam_err = pam_get_data(pamh, *kfn, &vp); 365 pam_err = pam_get_data(pamh, *kfn, &vp);
377 psk = vp; 366 psk = vp;
378 if (pam_err == PAM_SUCCESS && psk != NULL) { 367 if (pam_err == PAM_SUCCESS && psk != NULL) {
379 if (ssh_add_identity_constrained(ac, psk->key, psk->comment, 0, 0)) 368 if (ssh_add_identity(ac, psk->key, psk->comment))
380 openpam_log(PAM_LOG_DEBUG, 369 openpam_log(PAM_LOG_DEBUG,
381 "added %s to ssh agent", psk->comment); 370 "added %s to ssh agent", psk->comment);
382 else 371 else
383 openpam_log(PAM_LOG_DEBUG, "failed " 372 openpam_log(PAM_LOG_DEBUG, "failed "
384 "to add %s to ssh agent", psk->comment); 373 "to add %s to ssh agent", psk->comment);
385 /* we won't need the key again, so wipe it */ 374 /* we won't need the key again, so wipe it */
386 pam_set_data(pamh, *kfn, NULL, NULL); 375 pam_set_data(pamh, *kfn, NULL, NULL);
387 } 376 }
388 } 377 }
389 pam_err = PAM_SUCCESS; 378 pam_err = PAM_SUCCESS;
390 end: 379 end:
391 /* disconnect from agent */ 380 /* disconnect from agent */
392 if (ac != NULL) 381 if (ac != NULL)