OpenCoverage

auth2-pubkey.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/auth2-pubkey.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: auth2-pubkey.c,v 1.86 2018/09/20 03:28:06 djm Exp $ */-
2/*-
3 * Copyright (c) 2000 Markus Friedl. All rights reserved.-
4 *-
5 * Redistribution and use in source and binary forms, with or without-
6 * modification, are permitted provided that the following conditions-
7 * are met:-
8 * 1. Redistributions of source code must retain the above copyright-
9 * notice, this list of conditions and the following disclaimer.-
10 * 2. Redistributions in binary form must reproduce the above copyright-
11 * notice, this list of conditions and the following disclaimer in the-
12 * documentation and/or other materials provided with the distribution.-
13 *-
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR-
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES-
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.-
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,-
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT-
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF-
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-
24 */-
25-
26#include "includes.h"-
27-
28#include <sys/types.h>-
29#include <sys/stat.h>-
30-
31#include <errno.h>-
32#include <fcntl.h>-
33#ifdef HAVE_PATHS_H-
34# include <paths.h>-
35#endif-
36#include <pwd.h>-
37#include <signal.h>-
38#include <stdio.h>-
39#include <stdarg.h>-
40#include <string.h>-
41#include <time.h>-
42#include <unistd.h>-
43#include <limits.h>-
44-
45#include "xmalloc.h"-
46#include "ssh.h"-
47#include "ssh2.h"-
48#include "packet.h"-
49#include "sshbuf.h"-
50#include "log.h"-
51#include "misc.h"-
52#include "servconf.h"-
53#include "compat.h"-
54#include "sshkey.h"-
55#include "hostfile.h"-
56#include "auth.h"-
57#include "pathnames.h"-
58#include "uidswap.h"-
59#include "auth-options.h"-
60#include "canohost.h"-
61#ifdef GSSAPI-
62#include "ssh-gss.h"-
63#endif-
64#include "monitor_wrap.h"-
65#include "authfile.h"-
66#include "match.h"-
67#include "ssherr.h"-
68#include "channels.h" /* XXX for session.h */-
69#include "session.h" /* XXX for child_set_env(); refactor? */-
70-
71/* import */-
72extern ServerOptions options;-
73extern u_char *session_id2;-
74extern u_int session_id2_len;-
75-
76static char *-
77format_key(const struct sshkey *key)-
78{-
79 char *ret, *fp = sshkey_fingerprint(key,-
80 options.fingerprint_hash, SSH_FP_DEFAULT);-
81-
82 xasprintf(&ret, "%s %s", sshkey_type(key), fp);-
83 free(fp);-
84 return ret;
never executed: return ret;
0
85}-
86-
87static int-
88userauth_pubkey(struct ssh *ssh)-
89{-
90 Authctxt *authctxt = ssh->authctxt;-
91 struct passwd *pw = authctxt->pw;-
92 struct sshbuf *b = NULL;-
93 struct sshkey *key = NULL;-
94 char *pkalg = NULL, *userstyle = NULL, *key_s = NULL, *ca_s = NULL;-
95 u_char *pkblob = NULL, *sig = NULL, have_sig;-
96 size_t blen, slen;-
97 int r, pktype;-
98 int authenticated = 0;-
99 struct sshauthopt *authopts = NULL;-
100-
101 if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0 ||
(r = sshpkt_ge...ave_sig)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
102 (r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
(r = sshpkt_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
103 (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0)
(r = sshpkt_ge..., &blen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
104 fatal("%s: parse request failed: %s", __func__, ssh_err(r));
never executed: fatal("%s: parse request failed: %s", __func__, ssh_err(r));
0
105 pktype = sshkey_type_from_name(pkalg);-
106 if (pktype == KEY_UNSPEC) {
pktype == KEY_UNSPECDescription
TRUEnever evaluated
FALSEnever evaluated
0
107 /* this is perfectly legal */-
108 verbose("%s: unsupported public key algorithm: %s",-
109 __func__, pkalg);-
110 goto done;
never executed: goto done;
0
111 }-
112 if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
(r = sshkey_fr...n, &key)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
113 error("%s: could not parse key: %s", __func__, ssh_err(r));-
114 goto done;
never executed: goto done;
0
115 }-
116 if (key == NULL) {
key == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
117 error("%s: cannot decode key: %s", __func__, pkalg);-
118 goto done;
never executed: goto done;
0
119 }-
120 if (key->type != pktype) {
key->type != pktypeDescription
TRUEnever evaluated
FALSEnever evaluated
0
121 error("%s: type mismatch for decoded key "-
122 "(received %d, expected %d)", __func__, key->type, pktype);-
123 goto done;
never executed: goto done;
0
124 }-
125 if (sshkey_type_plain(key->type) == KEY_RSA &&
sshkey_type_pl...pe) == KEY_RSADescription
TRUEnever evaluated
FALSEnever evaluated
0
126 (ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
(ssh->compat &...00002000) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
127 logit("Refusing RSA key because client uses unsafe "-
128 "signature scheme");-
129 goto done;
never executed: goto done;
0
130 }-
131 if (auth2_key_already_used(authctxt, key)) {
auth2_key_alre...authctxt, key)Description
TRUEnever evaluated
FALSEnever evaluated
0
132 logit("refusing previously-used %s key", sshkey_type(key));-
133 goto done;
never executed: goto done;
0
134 }-
135 if (match_pattern_list(pkalg, options.pubkey_key_types, 0) != 1) {
match_pattern_...types, 0) != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
136 logit("%s: key type %s not in PubkeyAcceptedKeyTypes",-
137 __func__, sshkey_ssh_name(key));-
138 goto done;
never executed: goto done;
0
139 }-
140 if ((r = sshkey_check_cert_sigtype(key,
(r = sshkey_ch...orithms)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
141 options.ca_sign_algorithms)) != 0) {
(r = sshkey_ch...orithms)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
142 logit("%s: certificate signature algorithm %s: %s", __func__,-
143 (key->cert == NULL || key->cert->signature_type == NULL) ?-
144 "(null)" : key->cert->signature_type, ssh_err(r));-
145 goto done;
never executed: goto done;
0
146 }-
147 key_s = format_key(key);-
148 if (sshkey_is_cert(key))
sshkey_is_cert(key)Description
TRUEnever evaluated
FALSEnever evaluated
0
149 ca_s = format_key(key->cert->signature_key);
never executed: ca_s = format_key(key->cert->signature_key);
0
150-
151 if (have_sig) {
have_sigDescription
TRUEnever evaluated
FALSEnever evaluated
0
152 debug3("%s: have %s signature for %s%s%s",-
153 __func__, pkalg, key_s,-
154 ca_s == NULL ? "" : " CA ",-
155 ca_s == NULL ? "" : ca_s);-
156 if ((r = sshpkt_get_string(ssh, &sig, &slen)) != 0 ||
(r = sshpkt_ge..., &slen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
157 (r = sshpkt_get_end(ssh)) != 0)
(r = sshpkt_get_end(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
158 fatal("%s: %s", __func__, ssh_err(r));
never executed: fatal("%s: %s", __func__, ssh_err(r));
0
159 if ((b = sshbuf_new()) == NULL)
(b = sshbuf_ne...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
160 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
161 if (ssh->compat & SSH_OLD_SESSIONID) {
ssh->compat & 0x00000010Description
TRUEnever evaluated
FALSEnever evaluated
0
162 if ((r = sshbuf_put(b, session_id2,
(r = sshbuf_pu...id2_len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
163 session_id2_len)) != 0)
(r = sshbuf_pu...id2_len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
164 fatal("%s: sshbuf_put session id: %s",
never executed: fatal("%s: sshbuf_put session id: %s", __func__, ssh_err(r));
0
165 __func__, ssh_err(r));
never executed: fatal("%s: sshbuf_put session id: %s", __func__, ssh_err(r));
0
166 } else {
never executed: end of block
0
167 if ((r = sshbuf_put_string(b, session_id2,
(r = sshbuf_pu...id2_len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
168 session_id2_len)) != 0)
(r = sshbuf_pu...id2_len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
169 fatal("%s: sshbuf_put_string session id: %s",
never executed: fatal("%s: sshbuf_put_string session id: %s", __func__, ssh_err(r));
0
170 __func__, ssh_err(r));
never executed: fatal("%s: sshbuf_put_string session id: %s", __func__, ssh_err(r));
0
171 }
never executed: end of block
0
172 if (!authctxt->valid || authctxt->user == NULL) {
!authctxt->validDescription
TRUEnever evaluated
FALSEnever evaluated
authctxt->user == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
173 debug2("%s: disabled because of invalid user",-
174 __func__);-
175 goto done;
never executed: goto done;
0
176 }-
177 /* reconstruct packet */-
178 xasprintf(&userstyle, "%s%s%s", authctxt->user,-
179 authctxt->style ? ":" : "",-
180 authctxt->style ? authctxt->style : "");-
181 if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshbuf_pu...8(b, 50)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
182 (r = sshbuf_put_cstring(b, userstyle)) != 0 ||
(r = sshbuf_pu...erstyle)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
183 (r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
(r = sshbuf_pu...service)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
184 (r = sshbuf_put_cstring(b, "publickey")) != 0 ||
(r = sshbuf_pu...lickey")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
185 (r = sshbuf_put_u8(b, have_sig)) != 0 ||
(r = sshbuf_pu...ave_sig)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
186 (r = sshbuf_put_cstring(b, pkalg)) != 0 ||
(r = sshbuf_pu..., pkalg)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
187 (r = sshbuf_put_string(b, pkblob, blen)) != 0)
(r = sshbuf_pu...b, blen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
188 fatal("%s: build packet failed: %s",
never executed: fatal("%s: build packet failed: %s", __func__, ssh_err(r));
0
189 __func__, ssh_err(r));
never executed: fatal("%s: build packet failed: %s", __func__, ssh_err(r));
0
190#ifdef DEBUG_PK-
191 sshbuf_dump(b, stderr);-
192#endif-
193 /* test for correct signature */-
194 authenticated = 0;-
195 if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) &&
use_privsepDescription
TRUEnever evaluated
FALSEnever evaluated
(use_privsep ?...1, &authopts))Description
TRUEnever evaluated
FALSEnever evaluated
0
196 PRIVSEP(sshkey_verify(key, sig, slen,
use_privsepDescription
TRUEnever evaluated
FALSEnever evaluated
(use_privsep ?...>compat)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
197 sshbuf_ptr(b), sshbuf_len(b),
(use_privsep ?...>compat)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
198 (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL,
(use_privsep ?...>compat)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
199 ssh->compat)) == 0) {
(use_privsep ?...>compat)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
200 authenticated = 1;-
201 }
never executed: end of block
0
202 auth2_record_key(authctxt, authenticated, key);-
203 } else {
never executed: end of block
0
204 debug("%s: test pkalg %s pkblob %s%s%s",-
205 __func__, pkalg, key_s,-
206 ca_s == NULL ? "" : " CA ",-
207 ca_s == NULL ? "" : ca_s);-
208-
209 if ((r = sshpkt_get_end(ssh)) != 0)
(r = sshpkt_get_end(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
210 fatal("%s: %s", __func__, ssh_err(r));
never executed: fatal("%s: %s", __func__, ssh_err(r));
0
211-
212 if (!authctxt->valid || authctxt->user == NULL) {
!authctxt->validDescription
TRUEnever evaluated
FALSEnever evaluated
authctxt->user == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
213 debug2("%s: disabled because of invalid user",-
214 __func__);-
215 goto done;
never executed: goto done;
0
216 }-
217 /* XXX fake reply and always send PK_OK ? */-
218 /*-
219 * XXX this allows testing whether a user is allowed-
220 * to login: if you happen to have a valid pubkey this-
221 * message is sent. the message is NEVER sent at all-
222 * if a user is not allowed to login. is this an-
223 * issue? -markus-
224 */-
225 if (PRIVSEP(user_key_allowed(ssh, pw, key, 0, NULL))) {
(use_privsep ?...((void *)0) ))Description
TRUEnever evaluated
FALSEnever evaluated
use_privsepDescription
TRUEnever evaluated
FALSEnever evaluated
0
226 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK))
(r = sshpkt_st...ssh, 60)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
227 != 0 ||
(r = sshpkt_st...ssh, 60)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
228 (r = sshpkt_put_cstring(ssh, pkalg)) != 0 ||
(r = sshpkt_pu..., pkalg)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
229 (r = sshpkt_put_string(ssh, pkblob, blen)) != 0 ||
(r = sshpkt_pu...b, blen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
230 (r = sshpkt_send(ssh)) != 0 ||
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
231 (r = ssh_packet_write_wait(ssh)) != 0)
(r = ssh_packe...ait(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
232 fatal("%s: %s", __func__, ssh_err(r));
never executed: fatal("%s: %s", __func__, ssh_err(r));
0
233 authctxt->postponed = 1;-
234 }
never executed: end of block
0
235 }
never executed: end of block
0
236done:
code before this statement never executed: done:
0
237 if (authenticated == 1 && auth_activate_options(ssh, authopts) != 0) {
authenticated == 1Description
TRUEnever evaluated
FALSEnever evaluated
auth_activate_...authopts) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
238 debug("%s: key options inconsistent with existing", __func__);-
239 authenticated = 0;-
240 }
never executed: end of block
0
241 debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg);-
242-
243 sshbuf_free(b);-
244 sshauthopt_free(authopts);-
245 sshkey_free(key);-
246 free(userstyle);-
247 free(pkalg);-
248 free(pkblob);-
249 free(key_s);-
250 free(ca_s);-
251 free(sig);-
252 return authenticated;
never executed: return authenticated;
0
253}-
254-
255static int-
256match_principals_option(const char *principal_list, struct sshkey_cert *cert)-
257{-
258 char *result;-
259 u_int i;-
260-
261 /* XXX percent_expand() sequences for authorized_principals? */-
262-
263 for (i = 0; i < cert->nprincipals; i++) {
i < cert->nprincipalsDescription
TRUEnever evaluated
FALSEnever evaluated
0
264 if ((result = match_list(cert->principals[i],
(result = matc...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
265 principal_list, NULL)) != NULL) {
(result = matc...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
266 debug3("matched principal from key options \"%.100s\"",-
267 result);-
268 free(result);-
269 return 1;
never executed: return 1;
0
270 }-
271 }
never executed: end of block
0
272 return 0;
never executed: return 0;
0
273}-
274-
275/*-
276 * Process a single authorized_principals format line. Returns 0 and sets-
277 * authoptsp is principal is authorised, -1 otherwise. "loc" is used as a-
278 * log preamble for file/line information.-
279 */-
280static int-
281check_principals_line(struct ssh *ssh, char *cp, const struct sshkey_cert *cert,-
282 const char *loc, struct sshauthopt **authoptsp)-
283{-
284 u_int i, found = 0;-
285 char *ep, *line_opts;-
286 const char *reason = NULL;-
287 struct sshauthopt *opts = NULL;-
288-
289 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
290 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
291-
292 /* Trim trailing whitespace. */-
293 ep = cp + strlen(cp) - 1;-
294 while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t'))
ep > cpDescription
TRUEnever evaluated
FALSEnever evaluated
*ep == '\n'Description
TRUEnever evaluated
FALSEnever evaluated
*ep == ' 'Description
TRUEnever evaluated
FALSEnever evaluated
*ep == '\t'Description
TRUEnever evaluated
FALSEnever evaluated
0
295 *ep-- = '\0';
never executed: *ep-- = '\0';
0
296-
297 /*-
298 * If the line has internal whitespace then assume it has-
299 * key options.-
300 */-
301 line_opts = NULL;-
302 if ((ep = strrchr(cp, ' ')) != NULL ||
(ep = strrchr(...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
303 (ep = strrchr(cp, '\t')) != NULL) {
(ep = strrchr(...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
304 for (; *ep == ' ' || *ep == '\t'; ep++)
*ep == ' 'Description
TRUEnever evaluated
FALSEnever evaluated
*ep == '\t'Description
TRUEnever evaluated
FALSEnever evaluated
0
305 ;
never executed: ;
0
306 line_opts = cp;-
307 cp = ep;-
308 }
never executed: end of block
0
309 if ((opts = sshauthopt_parse(line_opts, &reason)) == NULL) {
(opts = sshaut...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
310 debug("%s: bad principals options: %s", loc, reason);-
311 auth_debug_add("%s: bad principals options: %s", loc, reason);-
312 return -1;
never executed: return -1;
0
313 }-
314 /* Check principals in cert against those on line */-
315 for (i = 0; i < cert->nprincipals; i++) {
i < cert->nprincipalsDescription
TRUEnever evaluated
FALSEnever evaluated
0
316 if (strcmp(cp, cert->principals[i]) != 0)
never executed: __result = (((const unsigned char *) (const char *) ( cp ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( cert->principals[i] ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__extension__ ... )))); }) != 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
317 continue;
never executed: continue;
0
318 debug3("%s: matched principal \"%.100s\"",-
319 loc, cert->principals[i]);-
320 found = 1;-
321 }
never executed: end of block
0
322 if (found && authoptsp != NULL) {
foundDescription
TRUEnever evaluated
FALSEnever evaluated
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
323 *authoptsp = opts;-
324 opts = NULL;-
325 }
never executed: end of block
0
326 sshauthopt_free(opts);-
327 return found ? 0 : -1;
never executed: return found ? 0 : -1;
foundDescription
TRUEnever evaluated
FALSEnever evaluated
0
328}-
329-
330static int-
331process_principals(struct ssh *ssh, FILE *f, const char *file,-
332 const struct sshkey_cert *cert, struct sshauthopt **authoptsp)-
333{-
334 char loc[256], *line = NULL, *cp, *ep;-
335 size_t linesize = 0;-
336 u_long linenum = 0;-
337 u_int found_principal = 0;-
338-
339 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
340 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
341-
342 while (getline(&line, &linesize, f) != -1) {
getline(&line,...size, f) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
343 linenum++;-
344 /* Always consume entire input */-
345 if (found_principal)
found_principalDescription
TRUEnever evaluated
FALSEnever evaluated
0
346 continue;
never executed: continue;
0
347-
348 /* Skip leading whitespace. */-
349 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
*cp == ' 'Description
TRUEnever evaluated
FALSEnever evaluated
*cp == '\t'Description
TRUEnever evaluated
FALSEnever evaluated
0
350 ;
never executed: ;
0
351 /* Skip blank and comment lines. */-
352 if ((ep = strchr(cp, '#')) != NULL)
(ep = (__exten...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( '#' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( cp )Description
TRUEnever evaluated
FALSEnever evaluated
( '#' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
353 *ep = '\0';
never executed: *ep = '\0';
0
354 if (!*cp || *cp == '\n')
!*cpDescription
TRUEnever evaluated
FALSEnever evaluated
*cp == '\n'Description
TRUEnever evaluated
FALSEnever evaluated
0
355 continue;
never executed: continue;
0
356-
357 snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum);-
358 if (check_principals_line(ssh, cp, cert, loc, authoptsp) == 0)
check_principa...uthoptsp) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
359 found_principal = 1;
never executed: found_principal = 1;
0
360 }
never executed: end of block
0
361 free(line);-
362 return found_principal;
never executed: return found_principal;
0
363}-
364-
365/* XXX remove pw args here and elsewhere once ssh->authctxt is guaranteed */-
366-
367static int-
368match_principals_file(struct ssh *ssh, struct passwd *pw, char *file,-
369 struct sshkey_cert *cert, struct sshauthopt **authoptsp)-
370{-
371 FILE *f;-
372 int success;-
373-
374 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
375 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
376-
377 temporarily_use_uid(pw);-
378 debug("trying authorized principals file %s", file);-
379 if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) {
(f = auth_open...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
380 restore_uid();-
381 return 0;
never executed: return 0;
0
382 }-
383 success = process_principals(ssh, f, file, cert, authoptsp);-
384 fclose(f);-
385 restore_uid();-
386 return success;
never executed: return success;
0
387}-
388-
389/*-
390 * Checks whether principal is allowed in output of command.-
391 * returns 1 if the principal is allowed or 0 otherwise.-
392 */-
393static int-
394match_principals_command(struct ssh *ssh, struct passwd *user_pw,-
395 const struct sshkey *key, struct sshauthopt **authoptsp)-
396{-
397 struct passwd *runas_pw = NULL;-
398 const struct sshkey_cert *cert = key->cert;-
399 FILE *f = NULL;-
400 int r, ok, found_principal = 0;-
401 int i, ac = 0, uid_swapped = 0;-
402 pid_t pid;-
403 char *tmp, *username = NULL, *command = NULL, **av = NULL;-
404 char *ca_fp = NULL, *key_fp = NULL, *catext = NULL, *keytext = NULL;-
405 char serial_s[16], uidstr[32];-
406 void (*osigchld)(int);-
407-
408 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
409 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
410 if (options.authorized_principals_command == NULL)
options.author...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
411 return 0;
never executed: return 0;
0
412 if (options.authorized_principals_command_user == NULL) {
options.author...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
413 error("No user for AuthorizedPrincipalsCommand specified, "-
414 "skipping");-
415 return 0;
never executed: return 0;
0
416 }-
417-
418 /*-
419 * NB. all returns later this function should go via "out" to-
420 * ensure the original SIGCHLD handler is restored properly.-
421 */-
422 osigchld = signal(SIGCHLD, SIG_DFL);-
423-
424 /* Prepare and verify the user for the command */-
425 username = percent_expand(options.authorized_principals_command_user,-
426 "u", user_pw->pw_name, (char *)NULL);-
427 runas_pw = getpwnam(username);-
428 if (runas_pw == NULL) {
runas_pw == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
429 error("AuthorizedPrincipalsCommandUser \"%s\" not found: %s",-
430 username, strerror(errno));-
431 goto out;
never executed: goto out;
0
432 }-
433-
434 /* Turn the command into an argument vector */-
435 if (argv_split(options.authorized_principals_command, &ac, &av) != 0) {
argv_split(opt...&ac, &av) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
436 error("AuthorizedPrincipalsCommand \"%s\" contains "-
437 "invalid quotes", command);-
438 goto out;
never executed: goto out;
0
439 }-
440 if (ac == 0) {
ac == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
441 error("AuthorizedPrincipalsCommand \"%s\" yielded no arguments",-
442 command);-
443 goto out;
never executed: goto out;
0
444 }-
445 if ((ca_fp = sshkey_fingerprint(cert->signature_key,
(ca_fp = sshke...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
446 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
(ca_fp = sshke...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
447 error("%s: sshkey_fingerprint failed", __func__);-
448 goto out;
never executed: goto out;
0
449 }-
450 if ((key_fp = sshkey_fingerprint(key,
(key_fp = sshk...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
451 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
(key_fp = sshk...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
452 error("%s: sshkey_fingerprint failed", __func__);-
453 goto out;
never executed: goto out;
0
454 }-
455 if ((r = sshkey_to_base64(cert->signature_key, &catext)) != 0) {
(r = sshkey_to...&catext)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
456 error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));-
457 goto out;
never executed: goto out;
0
458 }-
459 if ((r = sshkey_to_base64(key, &keytext)) != 0) {
(r = sshkey_to...keytext)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
460 error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));-
461 goto out;
never executed: goto out;
0
462 }-
463 snprintf(serial_s, sizeof(serial_s), "%llu",-
464 (unsigned long long)cert->serial);-
465 snprintf(uidstr, sizeof(uidstr), "%llu",-
466 (unsigned long long)user_pw->pw_uid);-
467 for (i = 1; i < ac; i++) {
i < acDescription
TRUEnever evaluated
FALSEnever evaluated
0
468 tmp = percent_expand(av[i],-
469 "U", uidstr,-
470 "u", user_pw->pw_name,-
471 "h", user_pw->pw_dir,-
472 "t", sshkey_ssh_name(key),-
473 "T", sshkey_ssh_name(cert->signature_key),-
474 "f", key_fp,-
475 "F", ca_fp,-
476 "k", keytext,-
477 "K", catext,-
478 "i", cert->key_id,-
479 "s", serial_s,-
480 (char *)NULL);-
481 if (tmp == NULL)
tmp == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
482 fatal("%s: percent_expand failed", __func__);
never executed: fatal("%s: percent_expand failed", __func__);
0
483 free(av[i]);-
484 av[i] = tmp;-
485 }
never executed: end of block
0
486 /* Prepare a printable command for logs, etc. */-
487 command = argv_assemble(ac, av);-
488-
489 if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command,
(pid = subproc...|(1<<2))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
490 ac, av, &f,
(pid = subproc...|(1<<2))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
491 SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
(pid = subproc...|(1<<2))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
492 goto out;
never executed: goto out;
0
493-
494 uid_swapped = 1;-
495 temporarily_use_uid(runas_pw);-
496-
497 ok = process_principals(ssh, f, "(command)", cert, authoptsp);-
498-
499 fclose(f);-
500 f = NULL;-
501-
502 if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command, 0) != 0)
exited_cleanly...mmand, 0) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
503 goto out;
never executed: goto out;
0
504-
505 /* Read completed successfully */-
506 found_principal = ok;-
507 out:
code before this statement never executed: out:
0
508 if (f != NULL)
f != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
509 fclose(f);
never executed: fclose(f);
0
510 signal(SIGCHLD, osigchld);-
511 for (i = 0; i < ac; i++)
i < acDescription
TRUEnever evaluated
FALSEnever evaluated
0
512 free(av[i]);
never executed: free(av[i]);
0
513 free(av);-
514 if (uid_swapped)
uid_swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
515 restore_uid();
never executed: restore_uid();
0
516 free(command);-
517 free(username);-
518 free(ca_fp);-
519 free(key_fp);-
520 free(catext);-
521 free(keytext);-
522 return found_principal;
never executed: return found_principal;
0
523}-
524-
525static void-
526skip_space(char **cpp)-
527{-
528 char *cp;-
529-
530 for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
*cp == ' 'Description
TRUEnever evaluated
FALSEnever evaluated
*cp == '\t'Description
TRUEnever evaluated
FALSEnever evaluated
0
531 ;
never executed: ;
0
532 *cpp = cp;-
533}
never executed: end of block
0
534-
535/*-
536 * Advanced *cpp past the end of key options, defined as the first unquoted-
537 * whitespace character. Returns 0 on success or -1 on failure (e.g.-
538 * unterminated quotes).-
539 */-
540static int-
541advance_past_options(char **cpp)-
542{-
543 char *cp = *cpp;-
544 int quoted = 0;-
545-
546 for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
*cpDescription
TRUEnever evaluated
FALSEnever evaluated
quotedDescription
TRUEnever evaluated
FALSEnever evaluated
*cp != ' 'Description
TRUEnever evaluated
FALSEnever evaluated
*cp != '\t'Description
TRUEnever evaluated
FALSEnever evaluated
0
547 if (*cp == '\\' && cp[1] == '"')
*cp == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
cp[1] == '"'Description
TRUEnever evaluated
FALSEnever evaluated
0
548 cp++; /* Skip both */
never executed: cp++;
0
549 else if (*cp == '"')
*cp == '"'Description
TRUEnever evaluated
FALSEnever evaluated
0
550 quoted = !quoted;
never executed: quoted = !quoted;
0
551 }
never executed: end of block
0
552 *cpp = cp;-
553 /* return failure for unterminated quotes */-
554 return (*cp == '\0' && quoted) ? -1 : 0;
never executed: return (*cp == '\0' && quoted) ? -1 : 0;
*cp == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
quotedDescription
TRUEnever evaluated
FALSEnever evaluated
0
555}-
556-
557/*-
558 * Check a single line of an authorized_keys-format file. Returns 0 if key-
559 * matches, -1 otherwise. Will return key/cert options via *authoptsp-
560 * on success. "loc" is used as file/line location in log messages.-
561 */-
562static int-
563check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,-
564 char *cp, const char *loc, struct sshauthopt **authoptsp)-
565{-
566 int want_keytype = sshkey_is_cert(key) ? KEY_UNSPEC : key->type;
sshkey_is_cert(key)Description
TRUEnever evaluated
FALSEnever evaluated
0
567 struct sshkey *found = NULL;-
568 struct sshauthopt *keyopts = NULL, *certopts = NULL, *finalopts = NULL;-
569 char *key_options = NULL, *fp = NULL;-
570 const char *reason = NULL;-
571 int ret = -1;-
572-
573 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
574 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
575-
576 if ((found = sshkey_new(want_keytype)) == NULL) {
(found = sshke...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
577 debug3("%s: keytype %d failed", __func__, want_keytype);-
578 goto out;
never executed: goto out;
0
579 }-
580-
581 /* XXX djm: peek at key type in line and skip if unwanted */-
582-
583 if (sshkey_read(found, &cp) != 0) {
sshkey_read(found, &cp) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
584 /* no key? check for options */-
585 debug2("%s: check options: '%s'", loc, cp);-
586 key_options = cp;-
587 if (advance_past_options(&cp) != 0) {
advance_past_options(&cp) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
588 reason = "invalid key option string";-
589 goto fail_reason;
never executed: goto fail_reason;
0
590 }-
591 skip_space(&cp);-
592 if (sshkey_read(found, &cp) != 0) {
sshkey_read(found, &cp) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
593 /* still no key? advance to next line*/-
594 debug2("%s: advance: '%s'", loc, cp);-
595 goto out;
never executed: goto out;
0
596 }-
597 }
never executed: end of block
0
598 /* Parse key options now; we need to know if this is a CA key */-
599 if ((keyopts = sshauthopt_parse(key_options, &reason)) == NULL) {
(keyopts = ssh...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
600 debug("%s: bad key options: %s", loc, reason);-
601 auth_debug_add("%s: bad key options: %s", loc, reason);-
602 goto out;
never executed: goto out;
0
603 }-
604 /* Ignore keys that don't match or incorrectly marked as CAs */-
605 if (sshkey_is_cert(key)) {
sshkey_is_cert(key)Description
TRUEnever evaluated
FALSEnever evaluated
0
606 /* Certificate; check signature key against CA */-
607 if (!sshkey_equal(found, key->cert->signature_key) ||
!sshkey_equal(...signature_key)Description
TRUEnever evaluated
FALSEnever evaluated
0
608 !keyopts->cert_authority)
!keyopts->cert_authorityDescription
TRUEnever evaluated
FALSEnever evaluated
0
609 goto out;
never executed: goto out;
0
610 } else {
never executed: end of block
0
611 /* Plain key: check it against key found in file */-
612 if (!sshkey_equal(found, key) || keyopts->cert_authority)
!sshkey_equal(found, key)Description
TRUEnever evaluated
FALSEnever evaluated
keyopts->cert_authorityDescription
TRUEnever evaluated
FALSEnever evaluated
0
613 goto out;
never executed: goto out;
0
614 }
never executed: end of block
0
615-
616 /* We have a candidate key, perform authorisation checks */-
617 if ((fp = sshkey_fingerprint(found,
(fp = sshkey_f...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
618 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
(fp = sshkey_f...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
619 fatal("%s: fingerprint failed", __func__);
never executed: fatal("%s: fingerprint failed", __func__);
0
620-
621 debug("%s: matching %s found: %s %s", loc,-
622 sshkey_is_cert(key) ? "CA" : "key", sshkey_type(found), fp);-
623-
624 if (auth_authorise_keyopts(ssh, pw, keyopts,
auth_authorise...ey), loc) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
625 sshkey_is_cert(key), loc) != 0) {
auth_authorise...ey), loc) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
626 reason = "Refused by key options";-
627 goto fail_reason;
never executed: goto fail_reason;
0
628 }-
629 /* That's all we need for plain keys. */-
630 if (!sshkey_is_cert(key)) {
!sshkey_is_cert(key)Description
TRUEnever evaluated
FALSEnever evaluated
0
631 verbose("Accepted key %s %s found at %s",-
632 sshkey_type(found), fp, loc);-
633 finalopts = keyopts;-
634 keyopts = NULL;-
635 goto success;
never executed: goto success;
0
636 }-
637-
638 /*-
639 * Additional authorisation for certificates.-
640 */-
641-
642 /* Parse and check options present in certificate */-
643 if ((certopts = sshauthopt_from_cert(key)) == NULL) {
(certopts = ss...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
644 reason = "Invalid certificate options";-
645 goto fail_reason;
never executed: goto fail_reason;
0
646 }-
647 if (auth_authorise_keyopts(ssh, pw, certopts, 0, loc) != 0) {
auth_authorise..., 0, loc) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
648 reason = "Refused by certificate options";-
649 goto fail_reason;
never executed: goto fail_reason;
0
650 }-
651 if ((finalopts = sshauthopt_merge(keyopts, certopts, &reason)) == NULL)
(finalopts = s...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
652 goto fail_reason;
never executed: goto fail_reason;
0
653-
654 /*-
655 * If the user has specified a list of principals as-
656 * a key option, then prefer that list to matching-
657 * their username in the certificate principals list.-
658 */-
659 if (keyopts->cert_principals != NULL &&
keyopts->cert_...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
660 !match_principals_option(keyopts->cert_principals, key->cert)) {
!match_princip...ls, key->cert)Description
TRUEnever evaluated
FALSEnever evaluated
0
661 reason = "Certificate does not contain an authorized principal";-
662 goto fail_reason;
never executed: goto fail_reason;
0
663 }-
664 if (sshkey_cert_check_authority(key, 0, 0,
sshkey_cert_ch... &reason) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
665 keyopts->cert_principals == NULL ? pw->pw_name : NULL, &reason) != 0)
sshkey_cert_ch... &reason) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
666 goto fail_reason;
never executed: goto fail_reason;
0
667-
668 verbose("Accepted certificate ID \"%s\" (serial %llu) "-
669 "signed by CA %s %s found at %s",-
670 key->cert->key_id,-
671 (unsigned long long)key->cert->serial,-
672 sshkey_type(found), fp, loc);-
673-
674 success:
code before this statement never executed: success:
0
675 if (finalopts == NULL)
finalopts == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
676 fatal("%s: internal error: missing options", __func__);
never executed: fatal("%s: internal error: missing options", __func__);
0
677 if (authoptsp != NULL) {
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
678 *authoptsp = finalopts;-
679 finalopts = NULL;-
680 }
never executed: end of block
0
681 /* success */-
682 ret = 0;-
683 goto out;
never executed: goto out;
0
684-
685 fail_reason:-
686 error("%s", reason);-
687 auth_debug_add("%s", reason);-
688 out:
code before this statement never executed: out:
0
689 free(fp);-
690 sshauthopt_free(keyopts);-
691 sshauthopt_free(certopts);-
692 sshauthopt_free(finalopts);-
693 sshkey_free(found);-
694 return ret;
never executed: return ret;
0
695}-
696-
697/*-
698 * Checks whether key is allowed in authorized_keys-format file,-
699 * returns 1 if the key is allowed or 0 otherwise.-
700 */-
701static int-
702check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f,-
703 char *file, struct sshkey *key, struct sshauthopt **authoptsp)-
704{-
705 char *cp, *line = NULL, loc[256];-
706 size_t linesize = 0;-
707 int found_key = 0;-
708 u_long linenum = 0;-
709-
710 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
711 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
712-
713 while (getline(&line, &linesize, f) != -1) {
getline(&line,...size, f) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
714 linenum++;-
715 /* Always consume entire file */-
716 if (found_key)
found_keyDescription
TRUEnever evaluated
FALSEnever evaluated
0
717 continue;
never executed: continue;
0
718-
719 /* Skip leading whitespace, empty and comment lines. */-
720 cp = line;-
721 skip_space(&cp);-
722 if (!*cp || *cp == '\n' || *cp == '#')
!*cpDescription
TRUEnever evaluated
FALSEnever evaluated
*cp == '\n'Description
TRUEnever evaluated
FALSEnever evaluated
*cp == '#'Description
TRUEnever evaluated
FALSEnever evaluated
0
723 continue;
never executed: continue;
0
724 snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum);-
725 if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0)
check_authkey_...uthoptsp) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
726 found_key = 1;
never executed: found_key = 1;
0
727 }
never executed: end of block
0
728 free(line);-
729 return found_key;
never executed: return found_key;
0
730}-
731-
732/* Authenticate a certificate key against TrustedUserCAKeys */-
733static int-
734user_cert_trusted_ca(struct ssh *ssh, struct passwd *pw, struct sshkey *key,-
735 struct sshauthopt **authoptsp)-
736{-
737 char *ca_fp, *principals_file = NULL;-
738 const char *reason;-
739 struct sshauthopt *principals_opts = NULL, *cert_opts = NULL;-
740 struct sshauthopt *final_opts = NULL;-
741 int r, ret = 0, found_principal = 0, use_authorized_principals;-
742-
743 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
744 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
745-
746 if (!sshkey_is_cert(key) || options.trusted_user_ca_keys == NULL)
!sshkey_is_cert(key)Description
TRUEnever evaluated
FALSEnever evaluated
options.truste...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
747 return 0;
never executed: return 0;
0
748-
749 if ((ca_fp = sshkey_fingerprint(key->cert->signature_key,
(ca_fp = sshke...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
750 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
(ca_fp = sshke...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
751 return 0;
never executed: return 0;
0
752-
753 if ((r = sshkey_in_file(key->cert->signature_key,
(r = sshkey_in...s, 1, 0)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
754 options.trusted_user_ca_keys, 1, 0)) != 0) {
(r = sshkey_in...s, 1, 0)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
755 debug2("%s: CA %s %s is not listed in %s: %s", __func__,-
756 sshkey_type(key->cert->signature_key), ca_fp,-
757 options.trusted_user_ca_keys, ssh_err(r));-
758 goto out;
never executed: goto out;
0
759 }-
760 /*-
761 * If AuthorizedPrincipals is in use, then compare the certificate-
762 * principals against the names in that file rather than matching-
763 * against the username.-
764 */-
765 if ((principals_file = authorized_principals_file(pw)) != NULL) {
(principals_fi...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
766 if (match_principals_file(ssh, pw, principals_file,
match_principa...incipals_opts)Description
TRUEnever evaluated
FALSEnever evaluated
0
767 key->cert, &principals_opts))
match_principa...incipals_opts)Description
TRUEnever evaluated
FALSEnever evaluated
0
768 found_principal = 1;
never executed: found_principal = 1;
0
769 }
never executed: end of block
0
770 /* Try querying command if specified */-
771 if (!found_principal && match_principals_command(ssh, pw, key,
!found_principalDescription
TRUEnever evaluated
FALSEnever evaluated
match_principa...incipals_opts)Description
TRUEnever evaluated
FALSEnever evaluated
0
772 &principals_opts))
match_principa...incipals_opts)Description
TRUEnever evaluated
FALSEnever evaluated
0
773 found_principal = 1;
never executed: found_principal = 1;
0
774 /* If principals file or command is specified, then require a match */-
775 use_authorized_principals = principals_file != NULL ||
principals_file != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
776 options.authorized_principals_command != NULL;
options.author...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
777 if (!found_principal && use_authorized_principals) {
!found_principalDescription
TRUEnever evaluated
FALSEnever evaluated
use_authorized_principalsDescription
TRUEnever evaluated
FALSEnever evaluated
0
778 reason = "Certificate does not contain an authorized principal";-
779 goto fail_reason;
never executed: goto fail_reason;
0
780 }-
781 if (use_authorized_principals && principals_opts == NULL)
use_authorized_principalsDescription
TRUEnever evaluated
FALSEnever evaluated
principals_opts == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
782 fatal("%s: internal error: missing principals_opts", __func__);
never executed: fatal("%s: internal error: missing principals_opts", __func__);
0
783 if (sshkey_cert_check_authority(key, 0, 1,
sshkey_cert_ch... &reason) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
784 use_authorized_principals ? NULL : pw->pw_name, &reason) != 0)
sshkey_cert_ch... &reason) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
785 goto fail_reason;
never executed: goto fail_reason;
0
786-
787 /* Check authority from options in key and from principals file/cmd */-
788 if ((cert_opts = sshauthopt_from_cert(key)) == NULL) {
(cert_opts = s...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
789 reason = "Invalid certificate options";-
790 goto fail_reason;
never executed: goto fail_reason;
0
791 }-
792 if (auth_authorise_keyopts(ssh, pw, cert_opts, 0, "cert") != 0) {
auth_authorise..., "cert") != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
793 reason = "Refused by certificate options";-
794 goto fail_reason;
never executed: goto fail_reason;
0
795 }-
796 if (principals_opts == NULL) {
principals_opts == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
797 final_opts = cert_opts;-
798 cert_opts = NULL;-
799 } else {
never executed: end of block
0
800 if (auth_authorise_keyopts(ssh, pw, principals_opts, 0,
auth_authorise...ncipals") != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
801 "principals") != 0) {
auth_authorise...ncipals") != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
802 reason = "Refused by certificate principals options";-
803 goto fail_reason;
never executed: goto fail_reason;
0
804 }-
805 if ((final_opts = sshauthopt_merge(principals_opts,
(final_opts = ...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
806 cert_opts, &reason)) == NULL) {
(final_opts = ...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
807 fail_reason:-
808 error("%s", reason);-
809 auth_debug_add("%s", reason);-
810 goto out;
never executed: goto out;
0
811 }-
812 }
never executed: end of block
0
813-
814 /* Success */-
815 verbose("Accepted certificate ID \"%s\" (serial %llu) signed by "-
816 "%s CA %s via %s", key->cert->key_id,-
817 (unsigned long long)key->cert->serial,-
818 sshkey_type(key->cert->signature_key), ca_fp,-
819 options.trusted_user_ca_keys);-
820 if (authoptsp != NULL) {
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
821 *authoptsp = final_opts;-
822 final_opts = NULL;-
823 }
never executed: end of block
0
824 ret = 1;-
825 out:
code before this statement never executed: out:
0
826 sshauthopt_free(principals_opts);-
827 sshauthopt_free(cert_opts);-
828 sshauthopt_free(final_opts);-
829 free(principals_file);-
830 free(ca_fp);-
831 return ret;
never executed: return ret;
0
832}-
833-
834/*-
835 * Checks whether key is allowed in file.-
836 * returns 1 if the key is allowed or 0 otherwise.-
837 */-
838static int-
839user_key_allowed2(struct ssh *ssh, struct passwd *pw, struct sshkey *key,-
840 char *file, struct sshauthopt **authoptsp)-
841{-
842 FILE *f;-
843 int found_key = 0;-
844-
845 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
846 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
847-
848 /* Temporarily use the user's uid. */-
849 temporarily_use_uid(pw);-
850-
851 debug("trying public key file %s", file);-
852 if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) {
(f = auth_open...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
853 found_key = check_authkeys_file(ssh, pw, f, file,-
854 key, authoptsp);-
855 fclose(f);-
856 }
never executed: end of block
0
857-
858 restore_uid();-
859 return found_key;
never executed: return found_key;
0
860}-
861-
862/*-
863 * Checks whether key is allowed in output of command.-
864 * returns 1 if the key is allowed or 0 otherwise.-
865 */-
866static int-
867user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw,-
868 struct sshkey *key, struct sshauthopt **authoptsp)-
869{-
870 struct passwd *runas_pw = NULL;-
871 FILE *f = NULL;-
872 int r, ok, found_key = 0;-
873 int i, uid_swapped = 0, ac = 0;-
874 pid_t pid;-
875 char *username = NULL, *key_fp = NULL, *keytext = NULL;-
876 char uidstr[32], *tmp, *command = NULL, **av = NULL;-
877 void (*osigchld)(int);-
878-
879 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
880 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
881 if (options.authorized_keys_command == NULL)
options.author...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
882 return 0;
never executed: return 0;
0
883 if (options.authorized_keys_command_user == NULL) {
options.author...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
884 error("No user for AuthorizedKeysCommand specified, skipping");-
885 return 0;
never executed: return 0;
0
886 }-
887-
888 /*-
889 * NB. all returns later this function should go via "out" to-
890 * ensure the original SIGCHLD handler is restored properly.-
891 */-
892 osigchld = signal(SIGCHLD, SIG_DFL);-
893-
894 /* Prepare and verify the user for the command */-
895 username = percent_expand(options.authorized_keys_command_user,-
896 "u", user_pw->pw_name, (char *)NULL);-
897 runas_pw = getpwnam(username);-
898 if (runas_pw == NULL) {
runas_pw == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
899 error("AuthorizedKeysCommandUser \"%s\" not found: %s",-
900 username, strerror(errno));-
901 goto out;
never executed: goto out;
0
902 }-
903-
904 /* Prepare AuthorizedKeysCommand */-
905 if ((key_fp = sshkey_fingerprint(key, options.fingerprint_hash,
(key_fp = sshk...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
906 SSH_FP_DEFAULT)) == NULL) {
(key_fp = sshk...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
907 error("%s: sshkey_fingerprint failed", __func__);-
908 goto out;
never executed: goto out;
0
909 }-
910 if ((r = sshkey_to_base64(key, &keytext)) != 0) {
(r = sshkey_to...keytext)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
911 error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));-
912 goto out;
never executed: goto out;
0
913 }-
914-
915 /* Turn the command into an argument vector */-
916 if (argv_split(options.authorized_keys_command, &ac, &av) != 0) {
argv_split(opt...&ac, &av) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
917 error("AuthorizedKeysCommand \"%s\" contains invalid quotes",-
918 command);-
919 goto out;
never executed: goto out;
0
920 }-
921 if (ac == 0) {
ac == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
922 error("AuthorizedKeysCommand \"%s\" yielded no arguments",-
923 command);-
924 goto out;
never executed: goto out;
0
925 }-
926 snprintf(uidstr, sizeof(uidstr), "%llu",-
927 (unsigned long long)user_pw->pw_uid);-
928 for (i = 1; i < ac; i++) {
i < acDescription
TRUEnever evaluated
FALSEnever evaluated
0
929 tmp = percent_expand(av[i],-
930 "U", uidstr,-
931 "u", user_pw->pw_name,-
932 "h", user_pw->pw_dir,-
933 "t", sshkey_ssh_name(key),-
934 "f", key_fp,-
935 "k", keytext,-
936 (char *)NULL);-
937 if (tmp == NULL)
tmp == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
938 fatal("%s: percent_expand failed", __func__);
never executed: fatal("%s: percent_expand failed", __func__);
0
939 free(av[i]);-
940 av[i] = tmp;-
941 }
never executed: end of block
0
942 /* Prepare a printable command for logs, etc. */-
943 command = argv_assemble(ac, av);-
944-
945 /*-
946 * If AuthorizedKeysCommand was run without arguments-
947 * then fall back to the old behaviour of passing the-
948 * target username as a single argument.-
949 */-
950 if (ac == 1) {
ac == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
951 av = xreallocarray(av, ac + 2, sizeof(*av));-
952 av[1] = xstrdup(user_pw->pw_name);-
953 av[2] = NULL;-
954 /* Fix up command too, since it is used in log messages */-
955 free(command);-
956 xasprintf(&command, "%s %s", av[0], av[1]);-
957 }
never executed: end of block
0
958-
959 if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command,
(pid = subproc...|(1<<2))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
960 ac, av, &f,
(pid = subproc...|(1<<2))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
961 SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
(pid = subproc...|(1<<2))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
962 goto out;
never executed: goto out;
0
963-
964 uid_swapped = 1;-
965 temporarily_use_uid(runas_pw);-
966-
967 ok = check_authkeys_file(ssh, user_pw, f,-
968 options.authorized_keys_command, key, authoptsp);-
969-
970 fclose(f);-
971 f = NULL;-
972-
973 if (exited_cleanly(pid, "AuthorizedKeysCommand", command, 0) != 0)
exited_cleanly...mmand, 0) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
974 goto out;
never executed: goto out;
0
975-
976 /* Read completed successfully */-
977 found_key = ok;-
978 out:
code before this statement never executed: out:
0
979 if (f != NULL)
f != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
980 fclose(f);
never executed: fclose(f);
0
981 signal(SIGCHLD, osigchld);-
982 for (i = 0; i < ac; i++)
i < acDescription
TRUEnever evaluated
FALSEnever evaluated
0
983 free(av[i]);
never executed: free(av[i]);
0
984 free(av);-
985 if (uid_swapped)
uid_swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
986 restore_uid();
never executed: restore_uid();
0
987 free(command);-
988 free(username);-
989 free(key_fp);-
990 free(keytext);-
991 return found_key;
never executed: return found_key;
0
992}-
993-
994/*-
995 * Check whether key authenticates and authorises the user.-
996 */-
997int-
998user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,-
999 int auth_attempt, struct sshauthopt **authoptsp)-
1000{-
1001 u_int success, i;-
1002 char *file;-
1003 struct sshauthopt *opts = NULL;-
1004 if (authoptsp != NULL)
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1005 *authoptsp = NULL;
never executed: *authoptsp = ((void *)0) ;
0
1006-
1007 if (auth_key_is_revoked(key))
auth_key_is_revoked(key)Description
TRUEnever evaluated
FALSEnever evaluated
0
1008 return 0;
never executed: return 0;
0
1009 if (sshkey_is_cert(key) &&
sshkey_is_cert(key)Description
TRUEnever evaluated
FALSEnever evaluated
0
1010 auth_key_is_revoked(key->cert->signature_key))
auth_key_is_re...signature_key)Description
TRUEnever evaluated
FALSEnever evaluated
0
1011 return 0;
never executed: return 0;
0
1012-
1013 if ((success = user_cert_trusted_ca(ssh, pw, key, &opts)) != 0)
(success = use..., &opts)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1014 goto out;
never executed: goto out;
0
1015 sshauthopt_free(opts);-
1016 opts = NULL;-
1017-
1018 if ((success = user_key_command_allowed2(ssh, pw, key, &opts)) != 0)
(success = use..., &opts)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1019 goto out;
never executed: goto out;
0
1020 sshauthopt_free(opts);-
1021 opts = NULL;-
1022-
1023 for (i = 0; !success && i < options.num_authkeys_files; i++) {
!successDescription
TRUEnever evaluated
FALSEnever evaluated
i < options.num_authkeys_filesDescription
TRUEnever evaluated
FALSEnever evaluated
0
1024 if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
strcasecmp(opt..., "none") == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1025 continue;
never executed: continue;
0
1026 file = expand_authorized_keys(-
1027 options.authorized_keys_files[i], pw);-
1028 success = user_key_allowed2(ssh, pw, key, file, &opts);-
1029 free(file);-
1030 }
never executed: end of block
0
1031-
1032 out:
code before this statement never executed: out:
0
1033 if (success && authoptsp != NULL) {
successDescription
TRUEnever evaluated
FALSEnever evaluated
authoptsp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1034 *authoptsp = opts;-
1035 opts = NULL;-
1036 }
never executed: end of block
0
1037 sshauthopt_free(opts);-
1038 return success;
never executed: return success;
0
1039}-
1040-
1041Authmethod method_pubkey = {-
1042 "publickey",-
1043 userauth_pubkey,-
1044 &options.pubkey_authentication-
1045};-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2