Sun Aug 26 08:54:03 2018 UTC ()
adjust to new libssh api.


(christos)
diff -r1.25 -r1.26 src/lib/libpam/modules/pam_ssh/pam_ssh.c

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

--- src/lib/libpam/modules/pam_ssh/pam_ssh.c 2018/04/07 19:28:32 1.25
+++ src/lib/libpam/modules/pam_ssh/pam_ssh.c 2018/08/26 08:54:03 1.26
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pam_ssh.c,v 1.25 2018/04/07 19:28:32 christos Exp $ */ 1/* $NetBSD: pam_ssh.c,v 1.26 2018/08/26 08:54:03 christos 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,62 +28,62 @@ @@ -28,62 +28,62 @@
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.25 2018/04/07 19:28:32 christos Exp $"); 41__RCSID("$NetBSD: pam_ssh.c,v 1.26 2018/08/26 08:54:03 christos 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>
55 55
56#define PAM_SM_AUTH 56#define PAM_SM_AUTH
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 "sshkey.h"
66#include "buffer.h" 66#include "sshbuf.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) \ 70#define ssh_add_identity(auth, key, comment) \
71 ssh_add_identity_constrained(auth, key, comment, 0, 0, 0) 71 ssh_add_identity_constrained(auth, key, comment, 0, 0, 0)
72 72
73extern char **environ; 73extern char **environ;
74 74
75struct pam_ssh_key { 75struct pam_ssh_key {
76 Key *key; 76 struct sshkey *key;
77 char *comment; 77 char *comment;
78}; 78};
79 79
80static const char *pam_ssh_prompt = "SSH passphrase: "; 80static const char *pam_ssh_prompt = "SSH passphrase: ";
81static const char *pam_ssh_have_keys = "pam_ssh_have_keys"; 81static const char *pam_ssh_have_keys = "pam_ssh_have_keys";
82 82
83static const char *pam_ssh_keyfiles[] = { 83static const char *pam_ssh_keyfiles[] = {
84 ".ssh/identity", /* SSH1 RSA key */ 84 ".ssh/identity", /* SSH1 RSA key */
85 ".ssh/id_rsa", /* SSH2 RSA key */ 85 ".ssh/id_rsa", /* SSH2 RSA key */
86 ".ssh/id_dsa", /* SSH2 DSA key */ 86 ".ssh/id_dsa", /* SSH2 DSA key */
87 ".ssh/id_ecdsa", /* SSH2 ECDSA key */ 87 ".ssh/id_ecdsa", /* SSH2 ECDSA key */
88 NULL 88 NULL
89}; 89};
@@ -93,77 +93,78 @@ static const char *const pam_ssh_agent_a @@ -93,77 +93,78 @@ static const char *const pam_ssh_agent_a
93static const char *const pam_ssh_agent_envp[] = { NULL }; 93static const char *const pam_ssh_agent_envp[] = { NULL };
94 94
95/* 95/*
96 * Attempts to load a private key from the specified file in the specified 96 * Attempts to load a private key from the specified file in the specified
97 * directory, using the specified passphrase. If successful, returns a 97 * directory, using the specified passphrase. If successful, returns a
98 * struct pam_ssh_key containing the key and its comment. 98 * struct pam_ssh_key containing the key and its comment.
99 */ 99 */
100static struct pam_ssh_key * 100static struct pam_ssh_key *
101pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase, 101pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase,
102 int nullok) 102 int nullok)
103{ 103{
104 struct pam_ssh_key *psk; 104 struct pam_ssh_key *psk;
105 char fn[PATH_MAX]; 105 char fn[PATH_MAX];
 106 int r;
106 char *comment; 107 char *comment;
107 Key *key; 108 struct sshkey *key;
108 109
109 if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn)) 110 if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn))
110 return (NULL); 111 return (NULL);
111 comment = NULL; 112 comment = NULL;
112 /* 113 /*
113 * If the key is unencrypted, OpenSSL ignores the passphrase, so 114 * If the key is unencrypted, OpenSSL ignores the passphrase, so
114 * it will seem like the user typed in the right one. This allows 115 * it will seem like the user typed in the right one. This allows
115 * a user to circumvent nullok by providing a dummy passphrase. 116 * a user to circumvent nullok by providing a dummy passphrase.
116 * Verify that the key really *is* encrypted by trying to load it 117 * Verify that the key really *is* encrypted by trying to load it
117 * with an empty passphrase, and if the key is not encrypted, 118 * with an empty passphrase, and if the key is not encrypted,
118 * accept only an empty passphrase. 119 * accept only an empty passphrase.
119 */ 120 */
120 key = key_load_private(fn, "", &comment); 121 r = sshkey_load_private(fn, "", &key, &comment);
121 if (key != NULL && !(*passphrase == '\0' && nullok)) { 122 if (r && !(*passphrase == '\0' && nullok)) {
122 key_free(key); 123 sshkey_free(key);
123 free(comment); 124 free(comment);
124 return (NULL); 125 return (NULL);
125 } 126 }
126 if (key == NULL) 127 if (r)
127 key = key_load_private(fn, passphrase, &comment); 128 sshkey_load_private(fn, passphrase, &key, &comment);
128 if (key == NULL) { 129 if (r) {
129 openpam_log(PAM_LOG_DEBUG, "failed to load key from %s", fn); 130 openpam_log(PAM_LOG_DEBUG, "failed to load key from %s", fn);
130 if (comment != NULL) 131 if (comment != NULL)
131 free(comment); 132 free(comment);
132 return (NULL); 133 return (NULL);
133 } 134 }
134 135
135 openpam_log(PAM_LOG_DEBUG, "loaded '%s' from %s", comment, fn); 136 openpam_log(PAM_LOG_DEBUG, "loaded '%s' from %s", comment, fn);
136 if ((psk = malloc(sizeof(*psk))) == NULL) { 137 if ((psk = malloc(sizeof(*psk))) == NULL) {
137 key_free(key); 138 sshkey_free(key);
138 free(comment); 139 free(comment);
139 return (NULL); 140 return (NULL);
140 } 141 }
141 psk->key = key; 142 psk->key = key;
142 psk->comment = comment; 143 psk->comment = comment;
143 return (psk); 144 return (psk);
144} 145}
145 146
146/* 147/*
147 * Wipes a private key and frees the associated resources. 148 * Wipes a private key and frees the associated resources.
148 */ 149 */
149static void 150static void
150pam_ssh_free_key(pam_handle_t *pamh __unused, 151pam_ssh_free_key(pam_handle_t *pamh __unused,
151 void *data, int pam_err __unused) 152 void *data, int pam_err __unused)
152{ 153{
153 struct pam_ssh_key *psk; 154 struct pam_ssh_key *psk;
154 155
155 psk = data; 156 psk = data;
156 key_free(psk->key); 157 sshkey_free(psk->key);
157 free(psk->comment); 158 free(psk->comment);
158 free(psk); 159 free(psk);
159} 160}
160 161
161PAM_EXTERN int 162PAM_EXTERN int
162pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, 163pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
163 int argc __unused, const char *argv[] __unused) 164 int argc __unused, const char *argv[] __unused)
164{ 165{
165 const char **kfn, *passphrase, *user; 166 const char **kfn, *passphrase, *user;
166 const void *item; 167 const void *item;
167 struct passwd *pwd, pwres; 168 struct passwd *pwd, pwres;
168 struct pam_ssh_key *psk; 169 struct pam_ssh_key *psk;
169 int nkeys, nullok, pam_err, pass; 170 int nkeys, nullok, pam_err, pass;