OpenCoverage

ssh-agent.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/ssh-agent.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: ssh-agent.c,v 1.231 2018/05/11 03:38:51 djm Exp $ */-
2/*-
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>-
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland-
5 * All rights reserved-
6 * The authentication agent program.-
7 *-
8 * As far as I am concerned, the code I have written for this software-
9 * can be used freely for any purpose. Any derived versions of this-
10 * software must be clearly marked as such, and if the derived work is-
11 * incompatible with the protocol description in the RFC file, it must be-
12 * called by a name other than "ssh" or "Secure Shell".-
13 *-
14 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.-
15 *-
16 * Redistribution and use in source and binary forms, with or without-
17 * modification, are permitted provided that the following conditions-
18 * are met:-
19 * 1. Redistributions of source code must retain the above copyright-
20 * notice, this list of conditions and the following disclaimer.-
21 * 2. Redistributions in binary form must reproduce the above copyright-
22 * notice, this list of conditions and the following disclaimer in the-
23 * documentation and/or other materials provided with the distribution.-
24 *-
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR-
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES-
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.-
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,-
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT-
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF-
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-
35 */-
36-
37#include "includes.h"-
38-
39#include <sys/types.h>-
40#include <sys/param.h>-
41#include <sys/resource.h>-
42#include <sys/stat.h>-
43#include <sys/socket.h>-
44#ifdef HAVE_SYS_TIME_H-
45# include <sys/time.h>-
46#endif-
47#ifdef HAVE_SYS_UN_H-
48# include <sys/un.h>-
49#endif-
50#include "openbsd-compat/sys-queue.h"-
51-
52#ifdef WITH_OPENSSL-
53#include <openssl/evp.h>-
54#include "openbsd-compat/openssl-compat.h"-
55#endif-
56-
57#include <errno.h>-
58#include <fcntl.h>-
59#include <limits.h>-
60#ifdef HAVE_PATHS_H-
61# include <paths.h>-
62#endif-
63#ifdef HAVE_POLL_H-
64# include <poll.h>-
65#endif-
66#include <signal.h>-
67#include <stdarg.h>-
68#include <stdio.h>-
69#include <stdlib.h>-
70#include <time.h>-
71#include <string.h>-
72#include <unistd.h>-
73#ifdef HAVE_UTIL_H-
74# include <util.h>-
75#endif-
76-
77#include "xmalloc.h"-
78#include "ssh.h"-
79#include "sshbuf.h"-
80#include "sshkey.h"-
81#include "authfd.h"-
82#include "compat.h"-
83#include "log.h"-
84#include "misc.h"-
85#include "digest.h"-
86#include "ssherr.h"-
87#include "match.h"-
88-
89#ifdef ENABLE_PKCS11-
90#include "ssh-pkcs11.h"-
91#endif-
92-
93#ifndef DEFAULT_PKCS11_WHITELIST-
94# define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"-
95#endif-
96-
97/* Maximum accepted message length */-
98#define AGENT_MAX_LEN (256*1024)-
99-
100typedef enum {-
101 AUTH_UNUSED,-
102 AUTH_SOCKET,-
103 AUTH_CONNECTION-
104} sock_type;-
105-
106typedef struct {-
107 int fd;-
108 sock_type type;-
109 struct sshbuf *input;-
110 struct sshbuf *output;-
111 struct sshbuf *request;-
112} SocketEntry;-
113-
114u_int sockets_alloc = 0;-
115SocketEntry *sockets = NULL;-
116-
117typedef struct identity {-
118 TAILQ_ENTRY(identity) next;-
119 struct sshkey *key;-
120 char *comment;-
121 char *provider;-
122 time_t death;-
123 u_int confirm;-
124} Identity;-
125-
126struct idtable {-
127 int nentries;-
128 TAILQ_HEAD(idqueue, identity) idlist;-
129};-
130-
131/* private key table */-
132struct idtable *idtab;-
133-
134int max_fd = 0;-
135-
136/* pid of shell == parent of agent */-
137pid_t parent_pid = -1;-
138time_t parent_alive_interval = 0;-
139-
140/* pid of process for which cleanup_socket is applicable */-
141pid_t cleanup_pid = 0;-
142-
143/* pathname and directory for AUTH_SOCKET */-
144char socket_name[PATH_MAX];-
145char socket_dir[PATH_MAX];-
146-
147/* PKCS#11 path whitelist */-
148static char *pkcs11_whitelist;-
149-
150/* locking */-
151#define LOCK_SIZE 32-
152#define LOCK_SALT_SIZE 16-
153#define LOCK_ROUNDS 1-
154int locked = 0;-
155u_char lock_pwhash[LOCK_SIZE];-
156u_char lock_salt[LOCK_SALT_SIZE];-
157-
158extern char *__progname;-
159-
160/* Default lifetime in seconds (0 == forever) */-
161static long lifetime = 0;-
162-
163static int fingerprint_hash = SSH_FP_HASH_DEFAULT;-
164-
165static void-
166close_socket(SocketEntry *e)-
167{-
168 close(e->fd);-
169 e->fd = -1;-
170 e->type = AUTH_UNUSED;-
171 sshbuf_free(e->input);-
172 sshbuf_free(e->output);-
173 sshbuf_free(e->request);-
174}
never executed: end of block
0
175-
176static void-
177idtab_init(void)-
178{-
179 idtab = xcalloc(1, sizeof(*idtab));-
180 TAILQ_INIT(&idtab->idlist);-
181 idtab->nentries = 0;-
182}
never executed: end of block
0
183-
184static void-
185free_identity(Identity *id)-
186{-
187 sshkey_free(id->key);-
188 free(id->provider);-
189 free(id->comment);-
190 free(id);-
191}
never executed: end of block
0
192-
193/* return matching private key for given public key */-
194static Identity *-
195lookup_identity(struct sshkey *key)-
196{-
197 Identity *id;-
198-
199 TAILQ_FOREACH(id, &idtab->idlist, next) {
(id) != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
200 if (sshkey_equal(key, id->key))
sshkey_equal(key, id->key)Description
TRUEnever evaluated
FALSEnever evaluated
0
201 return (id);
never executed: return (id);
0
202 }
never executed: end of block
0
203 return (NULL);
never executed: return ( ((void *)0) );
0
204}-
205-
206/* Check confirmation of keysign request */-
207static int-
208confirm_key(Identity *id)-
209{-
210 char *p;-
211 int ret = -1;-
212-
213 p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);-
214 if (p != NULL &&
p != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
215 ask_permission("Allow use of key %s?\nKey fingerprint %s.",
ask_permission...d->comment, p)Description
TRUEnever evaluated
FALSEnever evaluated
0
216 id->comment, p))
ask_permission...d->comment, p)Description
TRUEnever evaluated
FALSEnever evaluated
0
217 ret = 0;
never executed: ret = 0;
0
218 free(p);-
219-
220 return (ret);
never executed: return (ret);
0
221}-
222-
223static void-
224send_status(SocketEntry *e, int success)-
225{-
226 int r;-
227-
228 if ((r = sshbuf_put_u32(e->output, 1)) != 0 ||
(r = sshbuf_pu...tput, 1)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
229 (r = sshbuf_put_u8(e->output, success ?
(r = sshbuf_pu...? 6 : 5)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
230 SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
(r = sshbuf_pu...? 6 : 5)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
231 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
232}
never executed: end of block
0
233-
234/* send list of supported public keys to 'client' */-
235static void-
236process_request_identities(SocketEntry *e)-
237{-
238 Identity *id;-
239 struct sshbuf *msg;-
240 int r;-
241-
242 if ((msg = sshbuf_new()) == NULL)
(msg = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
243 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
244 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
(r = sshbuf_pu...msg, 12)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
245 (r = sshbuf_put_u32(msg, idtab->nentries)) != 0)
(r = sshbuf_pu...entries)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
246 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
247 TAILQ_FOREACH(id, &idtab->idlist, next) {
(id) != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
248 if ((r = sshkey_puts_opts(id->key, msg, SSHKEY_SERIALIZE_INFO))
(r = sshkey_pu...ZE_INFO)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
249 != 0 ||
(r = sshkey_pu...ZE_INFO)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
250 (r = sshbuf_put_cstring(msg, id->comment)) != 0) {
(r = sshbuf_pu...comment)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
251 error("%s: put key/comment: %s", __func__,-
252 ssh_err(r));-
253 continue;
never executed: continue;
0
254 }-
255 }
never executed: end of block
0
256 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
(r = sshbuf_pu...ut, msg)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
257 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
258 sshbuf_free(msg);-
259}
never executed: end of block
0
260-
261-
262static char *-
263agent_decode_alg(struct sshkey *key, u_int flags)-
264{-
265 if (key->type == KEY_RSA) {
key->type == KEY_RSADescription
TRUEnever evaluated
FALSEnever evaluated
0
266 if (flags & SSH_AGENT_RSA_SHA2_256)
flags & 0x02Description
TRUEnever evaluated
FALSEnever evaluated
0
267 return "rsa-sha2-256";
never executed: return "rsa-sha2-256";
0
268 else if (flags & SSH_AGENT_RSA_SHA2_512)
flags & 0x04Description
TRUEnever evaluated
FALSEnever evaluated
0
269 return "rsa-sha2-512";
never executed: return "rsa-sha2-512";
0
270 }
never executed: end of block
0
271 return NULL;
never executed: return ((void *)0) ;
0
272}-
273-
274/* ssh2 only */-
275static void-
276process_sign_request2(SocketEntry *e)-
277{-
278 const u_char *data;-
279 u_char *signature = NULL;-
280 size_t dlen, slen = 0;-
281 u_int compat = 0, flags;-
282 int r, ok = -1;-
283 struct sshbuf *msg;-
284 struct sshkey *key = NULL;-
285 struct identity *id;-
286-
287 if ((msg = sshbuf_new()) == NULL)
(msg = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
288 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
289 if ((r = sshkey_froms(e->request, &key)) != 0 ||
(r = sshkey_fr...t, &key)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
290 (r = sshbuf_get_string_direct(e->request, &data, &dlen)) != 0 ||
(r = sshbuf_ge..., &dlen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
291 (r = sshbuf_get_u32(e->request, &flags)) != 0) {
(r = sshbuf_ge... &flags)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
292 error("%s: couldn't parse request: %s", __func__, ssh_err(r));-
293 goto send;
never executed: goto send;
0
294 }-
295-
296 if ((id = lookup_identity(key)) == NULL) {
(id = lookup_i...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
297 verbose("%s: %s key not found", __func__, sshkey_type(key));-
298 goto send;
never executed: goto send;
0
299 }-
300 if (id->confirm && confirm_key(id) != 0) {
id->confirmDescription
TRUEnever evaluated
FALSEnever evaluated
confirm_key(id) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
301 verbose("%s: user refused key", __func__);-
302 goto send;
never executed: goto send;
0
303 }-
304 if ((r = sshkey_sign(id->key, &signature, &slen,
(r = sshkey_si... compat)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
305 data, dlen, agent_decode_alg(key, flags), compat)) != 0) {
(r = sshkey_si... compat)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
306 error("%s: sshkey_sign: %s", __func__, ssh_err(r));-
307 goto send;
never executed: goto send;
0
308 }-
309 /* Success */-
310 ok = 0;-
311 send:
code before this statement never executed: send:
0
312 sshkey_free(key);-
313 if (ok == 0) {
ok == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
314 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
(r = sshbuf_pu...msg, 14)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
315 (r = sshbuf_put_string(msg, signature, slen)) != 0)
(r = sshbuf_pu...e, slen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
316 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
317 } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
never executed: end of block
(r = sshbuf_pu...(msg, 5)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
318 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
319-
320 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
(r = sshbuf_pu...ut, msg)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
321 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
322-
323 sshbuf_free(msg);-
324 free(signature);-
325}
never executed: end of block
0
326-
327/* shared */-
328static void-
329process_remove_identity(SocketEntry *e)-
330{-
331 int r, success = 0;-
332 struct sshkey *key = NULL;-
333 Identity *id;-
334-
335 if ((r = sshkey_froms(e->request, &key)) != 0) {
(r = sshkey_fr...t, &key)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
336 error("%s: get key: %s", __func__, ssh_err(r));-
337 goto done;
never executed: goto done;
0
338 }-
339 if ((id = lookup_identity(key)) == NULL) {
(id = lookup_i...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
340 debug("%s: key not found", __func__);-
341 goto done;
never executed: goto done;
0
342 }-
343 /* We have this key, free it. */-
344 if (idtab->nentries < 1)
idtab->nentries < 1Description
TRUEnever evaluated
FALSEnever evaluated
0
345 fatal("%s: internal error: nentries %d",
never executed: fatal("%s: internal error: nentries %d", __func__, idtab->nentries);
0
346 __func__, idtab->nentries);
never executed: fatal("%s: internal error: nentries %d", __func__, idtab->nentries);
0
347 TAILQ_REMOVE(&idtab->idlist, id, next);
never executed: (id)->next.tqe_next->next.tqe_prev = (id)->next.tqe_prev;
never executed: (&idtab->idlist)->tqh_last = (id)->next.tqe_prev;
((id)->next.tq...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
348 free_identity(id);-
349 idtab->nentries--;-
350 sshkey_free(key);-
351 success = 1;-
352 done:
code before this statement never executed: done:
0
353 send_status(e, success);-
354}
never executed: end of block
0
355-
356static void-
357process_remove_all_identities(SocketEntry *e)-
358{-
359 Identity *id;-
360-
361 /* Loop over all identities and clear the keys. */-
362 for (id = TAILQ_FIRST(&idtab->idlist); id;
idDescription
TRUEnever evaluated
FALSEnever evaluated
0
363 id = TAILQ_FIRST(&idtab->idlist)) {-
364 TAILQ_REMOVE(&idtab->idlist, id, next);
never executed: (id)->next.tqe_next->next.tqe_prev = (id)->next.tqe_prev;
never executed: (&idtab->idlist)->tqh_last = (id)->next.tqe_prev;
((id)->next.tq...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
365 free_identity(id);-
366 }
never executed: end of block
0
367-
368 /* Mark that there are no identities. */-
369 idtab->nentries = 0;-
370-
371 /* Send success. */-
372 send_status(e, 1);-
373}
never executed: end of block
0
374-
375/* removes expired keys and returns number of seconds until the next expiry */-
376static time_t-
377reaper(void)-
378{-
379 time_t deadline = 0, now = monotime();-
380 Identity *id, *nxt;-
381-
382 for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) {
idDescription
TRUEnever evaluated
FALSEnever evaluated
0
383 nxt = TAILQ_NEXT(id, next);-
384 if (id->death == 0)
id->death == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
385 continue;
never executed: continue;
0
386 if (now >= id->death) {
now >= id->deathDescription
TRUEnever evaluated
FALSEnever evaluated
0
387 debug("expiring key '%s'", id->comment);-
388 TAILQ_REMOVE(&idtab->idlist, id, next);
never executed: (id)->next.tqe_next->next.tqe_prev = (id)->next.tqe_prev;
never executed: (&idtab->idlist)->tqh_last = (id)->next.tqe_prev;
((id)->next.tq...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
389 free_identity(id);-
390 idtab->nentries--;-
391 } else
never executed: end of block
0
392 deadline = (deadline == 0) ? id->death :
never executed: deadline = (deadline == 0) ? id->death : (((deadline) < (id->death)) ? (deadline) : (id->death));
(deadline == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
393 MINIMUM(deadline, id->death);
never executed: deadline = (deadline == 0) ? id->death : (((deadline) < (id->death)) ? (deadline) : (id->death));
((deadline) < (id->death))Description
TRUEnever evaluated
FALSEnever evaluated
0
394 }-
395 if (deadline == 0 || deadline <= now)
deadline == 0Description
TRUEnever evaluated
FALSEnever evaluated
deadline <= nowDescription
TRUEnever evaluated
FALSEnever evaluated
0
396 return 0;
never executed: return 0;
0
397 else-
398 return (deadline - now);
never executed: return (deadline - now);
0
399}-
400-
401static void-
402process_add_identity(SocketEntry *e)-
403{-
404 Identity *id;-
405 int success = 0, confirm = 0;-
406 u_int seconds, maxsign;-
407 char *comment = NULL;-
408 time_t death = 0;-
409 struct sshkey *k = NULL;-
410 u_char ctype;-
411 int r = SSH_ERR_INTERNAL_ERROR;-
412-
413 if ((r = sshkey_private_deserialize(e->request, &k)) != 0 ||
(r = sshkey_pr...est, &k)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
414 k == NULL ||
k == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
415 (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
416 error("%s: decode private key: %s", __func__, ssh_err(r));-
417 goto err;
never executed: goto err;
0
418 }-
419-
420 while (sshbuf_len(e->request)) {
sshbuf_len(e->request)Description
TRUEnever evaluated
FALSEnever evaluated
0
421 if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) {
(r = sshbuf_ge... &ctype)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
422 error("%s: buffer error: %s", __func__, ssh_err(r));-
423 goto err;
never executed: goto err;
0
424 }-
425 switch (ctype) {-
426 case SSH_AGENT_CONSTRAIN_LIFETIME:
never executed: case 1:
0
427 if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) {
(r = sshbuf_ge...seconds)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
428 error("%s: bad lifetime constraint: %s",-
429 __func__, ssh_err(r));-
430 goto err;
never executed: goto err;
0
431 }-
432 death = monotime() + seconds;-
433 break;
never executed: break;
0
434 case SSH_AGENT_CONSTRAIN_CONFIRM:
never executed: case 2:
0
435 confirm = 1;-
436 break;
never executed: break;
0
437 case SSH_AGENT_CONSTRAIN_MAXSIGN:
never executed: case 3:
0
438 if ((r = sshbuf_get_u32(e->request, &maxsign)) != 0) {
(r = sshbuf_ge...maxsign)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
439 error("%s: bad maxsign constraint: %s",-
440 __func__, ssh_err(r));-
441 goto err;
never executed: goto err;
0
442 }-
443 if ((r = sshkey_enable_maxsign(k, maxsign)) != 0) {
(r = sshkey_en...maxsign)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
444 error("%s: cannot enable maxsign: %s",-
445 __func__, ssh_err(r));-
446 goto err;
never executed: goto err;
0
447 }-
448 break;
never executed: break;
0
449 default:
never executed: default:
0
450 error("%s: Unknown constraint %d", __func__, ctype);-
451 err:
code before this statement never executed: err:
0
452 sshbuf_reset(e->request);-
453 free(comment);-
454 sshkey_free(k);-
455 goto send;
never executed: goto send;
0
456 }-
457 }-
458-
459 success = 1;-
460 if (lifetime && !death)
lifetimeDescription
TRUEnever evaluated
FALSEnever evaluated
!deathDescription
TRUEnever evaluated
FALSEnever evaluated
0
461 death = monotime() + lifetime;
never executed: death = monotime() + lifetime;
0
462 if ((id = lookup_identity(k)) == NULL) {
(id = lookup_i...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
463 id = xcalloc(1, sizeof(Identity));-
464 TAILQ_INSERT_TAIL(&idtab->idlist, id, next);-
465 /* Increment the number of identities. */-
466 idtab->nentries++;-
467 } else {
never executed: end of block
0
468 /* key state might have been updated */-
469 sshkey_free(id->key);-
470 free(id->comment);-
471 }
never executed: end of block
0
472 id->key = k;-
473 id->comment = comment;-
474 id->death = death;-
475 id->confirm = confirm;-
476send:
code before this statement never executed: send:
0
477 send_status(e, success);-
478}
never executed: end of block
0
479-
480/* XXX todo: encrypt sensitive data with passphrase */-
481static void-
482process_lock_agent(SocketEntry *e, int lock)-
483{-
484 int r, success = 0, delay;-
485 char *passwd;-
486 u_char passwdhash[LOCK_SIZE];-
487 static u_int fail_count = 0;-
488 size_t pwlen;-
489-
490 /*-
491 * This is deliberately fatal: the user has requested that we lock,-
492 * but we can't parse their request properly. The only safe thing to-
493 * do is abort.-
494 */-
495 if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0)
(r = sshbuf_ge... &pwlen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
496 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
497 if (pwlen == 0) {
pwlen == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
498 debug("empty password not supported");-
499 } else if (locked && !lock) {
never executed: end of block
lockedDescription
TRUEnever evaluated
FALSEnever evaluated
!lockDescription
TRUEnever evaluated
FALSEnever evaluated
0
500 if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
bcrypt_pbkdf(p...dhash), 1) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
501 passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0)
bcrypt_pbkdf(p...dhash), 1) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
502 fatal("bcrypt_pbkdf");
never executed: fatal("bcrypt_pbkdf");
0
503 if (timingsafe_bcmp(passwdhash, lock_pwhash, LOCK_SIZE) == 0) {
timingsafe_bcm...hash, 32) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
504 debug("agent unlocked");-
505 locked = 0;-
506 fail_count = 0;-
507 explicit_bzero(lock_pwhash, sizeof(lock_pwhash));-
508 success = 1;-
509 } else {
never executed: end of block
0
510 /* delay in 0.1s increments up to 10s */-
511 if (fail_count < 100)
fail_count < 100Description
TRUEnever evaluated
FALSEnever evaluated
0
512 fail_count++;
never executed: fail_count++;
0
513 delay = 100000 * fail_count;-
514 debug("unlock failed, delaying %0.1lf seconds",-
515 (double)delay/1000000);-
516 usleep(delay);-
517 }
never executed: end of block
0
518 explicit_bzero(passwdhash, sizeof(passwdhash));-
519 } else if (!locked && lock) {
never executed: end of block
!lockedDescription
TRUEnever evaluated
FALSEnever evaluated
lockDescription
TRUEnever evaluated
FALSEnever evaluated
0
520 debug("agent locked");-
521 locked = 1;-
522 arc4random_buf(lock_salt, sizeof(lock_salt));-
523 if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
bcrypt_pbkdf(p...whash), 1) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
524 lock_pwhash, sizeof(lock_pwhash), LOCK_ROUNDS) < 0)
bcrypt_pbkdf(p...whash), 1) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
525 fatal("bcrypt_pbkdf");
never executed: fatal("bcrypt_pbkdf");
0
526 success = 1;-
527 }
never executed: end of block
0
528 explicit_bzero(passwd, pwlen);-
529 free(passwd);-
530 send_status(e, success);-
531}
never executed: end of block
0
532-
533static void-
534no_identities(SocketEntry *e)-
535{-
536 struct sshbuf *msg;-
537 int r;-
538-
539 if ((msg = sshbuf_new()) == NULL)
(msg = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
540 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
541 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
(r = sshbuf_pu...msg, 12)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
542 (r = sshbuf_put_u32(msg, 0)) != 0 ||
(r = sshbuf_pu...(msg, 0)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
543 (r = sshbuf_put_stringb(e->output, msg)) != 0)
(r = sshbuf_pu...ut, msg)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
544 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
545 sshbuf_free(msg);-
546}
never executed: end of block
0
547-
548#ifdef ENABLE_PKCS11-
549static void-
550process_add_smartcard_key(SocketEntry *e)-
551{-
552 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];-
553 int r, i, count = 0, success = 0, confirm = 0;-
554 u_int seconds;-
555 time_t death = 0;-
556 u_char type;-
557 struct sshkey **keys = NULL, *k;-
558 Identity *id;-
559-
560 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
561 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
562 error("%s: buffer error: %s", __func__, ssh_err(r));-
563 goto send;
never executed: goto send;
0
564 }-
565-
566 while (sshbuf_len(e->request)) {
sshbuf_len(e->request)Description
TRUEnever evaluated
FALSEnever evaluated
0
567 if ((r = sshbuf_get_u8(e->request, &type)) != 0) {
(r = sshbuf_ge..., &type)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
568 error("%s: buffer error: %s", __func__, ssh_err(r));-
569 goto send;
never executed: goto send;
0
570 }-
571 switch (type) {-
572 case SSH_AGENT_CONSTRAIN_LIFETIME:
never executed: case 1:
0
573 if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) {
(r = sshbuf_ge...seconds)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
574 error("%s: buffer error: %s",-
575 __func__, ssh_err(r));-
576 goto send;
never executed: goto send;
0
577 }-
578 death = monotime() + seconds;-
579 break;
never executed: break;
0
580 case SSH_AGENT_CONSTRAIN_CONFIRM:
never executed: case 2:
0
581 confirm = 1;-
582 break;
never executed: break;
0
583 default:
never executed: default:
0
584 error("%s: Unknown constraint type %d", __func__, type);-
585 goto send;
never executed: goto send;
0
586 }-
587 }-
588 if (realpath(provider, canonical_provider) == NULL) {
_ssh_compat_re...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
589 verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",-
590 provider, strerror(errno));-
591 goto send;
never executed: goto send;
0
592 }-
593 if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) {
match_pattern_...elist, 0) != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
594 verbose("refusing PKCS#11 add of \"%.100s\": "-
595 "provider not whitelisted", canonical_provider);-
596 goto send;
never executed: goto send;
0
597 }-
598 debug("%s: add %.100s", __func__, canonical_provider);-
599 if (lifetime && !death)
lifetimeDescription
TRUEnever evaluated
FALSEnever evaluated
!deathDescription
TRUEnever evaluated
FALSEnever evaluated
0
600 death = monotime() + lifetime;
never executed: death = monotime() + lifetime;
0
601-
602 count = pkcs11_add_provider(canonical_provider, pin, &keys);-
603 for (i = 0; i < count; i++) {
i < countDescription
TRUEnever evaluated
FALSEnever evaluated
0
604 k = keys[i];-
605 if (lookup_identity(k) == NULL) {
lookup_identit...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
606 id = xcalloc(1, sizeof(Identity));-
607 id->key = k;-
608 id->provider = xstrdup(canonical_provider);-
609 id->comment = xstrdup(canonical_provider); /* XXX */-
610 id->death = death;-
611 id->confirm = confirm;-
612 TAILQ_INSERT_TAIL(&idtab->idlist, id, next);-
613 idtab->nentries++;-
614 success = 1;-
615 } else {
never executed: end of block
0
616 sshkey_free(k);-
617 }
never executed: end of block
0
618 keys[i] = NULL;-
619 }
never executed: end of block
0
620send:
code before this statement never executed: send:
0
621 free(pin);-
622 free(provider);-
623 free(keys);-
624 send_status(e, success);-
625}
never executed: end of block
0
626-
627static void-
628process_remove_smartcard_key(SocketEntry *e)-
629{-
630 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];-
631 int r, success = 0;-
632 Identity *id, *nxt;-
633-
634 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
635 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
636 error("%s: buffer error: %s", __func__, ssh_err(r));-
637 goto send;
never executed: goto send;
0
638 }-
639 free(pin);-
640-
641 if (realpath(provider, canonical_provider) == NULL) {
_ssh_compat_re...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
642 verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",-
643 provider, strerror(errno));-
644 goto send;
never executed: goto send;
0
645 }-
646-
647 debug("%s: remove %.100s", __func__, canonical_provider);-
648 for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) {
idDescription
TRUEnever evaluated
FALSEnever evaluated
0
649 nxt = TAILQ_NEXT(id, next);-
650 /* Skip file--based keys */-
651 if (id->provider == NULL)
id->provider == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
652 continue;
never executed: continue;
0
653 if (!strcmp(canonical_provider, id->provider)) {
never executed: __result = (((const unsigned char *) (const char *) ( canonical_provider ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( id->provider ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
! __extension_...vider )))); })Description
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
654 TAILQ_REMOVE(&idtab->idlist, id, next);
never executed: (id)->next.tqe_next->next.tqe_prev = (id)->next.tqe_prev;
never executed: (&idtab->idlist)->tqh_last = (id)->next.tqe_prev;
((id)->next.tq...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
655 free_identity(id);-
656 idtab->nentries--;-
657 }
never executed: end of block
0
658 }
never executed: end of block
0
659 if (pkcs11_del_provider(canonical_provider) == 0)
pkcs11_del_pro...provider) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
660 success = 1;
never executed: success = 1;
0
661 else-
662 error("%s: pkcs11_del_provider failed", __func__);
never executed: error("%s: pkcs11_del_provider failed", __func__);
0
663send:
code before this statement never executed: send:
0
664 free(provider);-
665 send_status(e, success);-
666}
never executed: end of block
0
667#endif /* ENABLE_PKCS11 */-
668-
669/* dispatch incoming messages */-
670-
671static int-
672process_message(u_int socknum)-
673{-
674 u_int msg_len;-
675 u_char type;-
676 const u_char *cp;-
677 int r;-
678 SocketEntry *e;-
679-
680 if (socknum >= sockets_alloc) {
socknum >= sockets_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
681 fatal("%s: socket number %u >= allocated %u",-
682 __func__, socknum, sockets_alloc);-
683 }
never executed: end of block
0
684 e = &sockets[socknum];-
685-
686 if (sshbuf_len(e->input) < 5)
sshbuf_len(e->input) < 5Description
TRUEnever evaluated
FALSEnever evaluated
0
687 return 0; /* Incomplete message header. */
never executed: return 0;
0
688 cp = sshbuf_ptr(e->input);-
689 msg_len = PEEK_U32(cp);-
690 if (msg_len > AGENT_MAX_LEN) {
msg_len > (256*1024)Description
TRUEnever evaluated
FALSEnever evaluated
0
691 debug("%s: socket %u (fd=%d) message too long %u > %u",-
692 __func__, socknum, e->fd, msg_len, AGENT_MAX_LEN);-
693 return -1;
never executed: return -1;
0
694 }-
695 if (sshbuf_len(e->input) < msg_len + 4)
sshbuf_len(e->... < msg_len + 4Description
TRUEnever evaluated
FALSEnever evaluated
0
696 return 0; /* Incomplete message body. */
never executed: return 0;
0
697-
698 /* move the current input to e->request */-
699 sshbuf_reset(e->request);-
700 if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 ||
(r = sshbuf_ge...request)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
701 (r = sshbuf_get_u8(e->request, &type)) != 0) {
(r = sshbuf_ge..., &type)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
702 if (r == SSH_ERR_MESSAGE_INCOMPLETE ||
r == -3Description
TRUEnever evaluated
FALSEnever evaluated
0
703 r == SSH_ERR_STRING_TOO_LARGE) {
r == -6Description
TRUEnever evaluated
FALSEnever evaluated
0
704 debug("%s: buffer error: %s", __func__, ssh_err(r));-
705 return -1;
never executed: return -1;
0
706 }-
707 fatal("%s: buffer error: %s", __func__, ssh_err(r));-
708 }
never executed: end of block
0
709-
710 debug("%s: socket %u (fd=%d) type %d", __func__, socknum, e->fd, type);-
711-
712 /* check whether agent is locked */-
713 if (locked && type != SSH_AGENTC_UNLOCK) {
lockedDescription
TRUEnever evaluated
FALSEnever evaluated
type != 23Description
TRUEnever evaluated
FALSEnever evaluated
0
714 sshbuf_reset(e->request);-
715 switch (type) {-
716 case SSH2_AGENTC_REQUEST_IDENTITIES:
never executed: case 11:
0
717 /* send empty lists */-
718 no_identities(e);-
719 break;
never executed: break;
0
720 default:
never executed: default:
0
721 /* send a fail message for all other request types */-
722 send_status(e, 0);-
723 }
never executed: end of block
0
724 return 0;
never executed: return 0;
0
725 }-
726-
727 switch (type) {-
728 case SSH_AGENTC_LOCK:
never executed: case 22:
0
729 case SSH_AGENTC_UNLOCK:
never executed: case 23:
0
730 process_lock_agent(e, type == SSH_AGENTC_LOCK);-
731 break;
never executed: break;
0
732 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
never executed: case 9:
0
733 process_remove_all_identities(e); /* safe for !WITH_SSH1 */-
734 break;
never executed: break;
0
735 /* ssh2 */-
736 case SSH2_AGENTC_SIGN_REQUEST:
never executed: case 13:
0
737 process_sign_request2(e);-
738 break;
never executed: break;
0
739 case SSH2_AGENTC_REQUEST_IDENTITIES:
never executed: case 11:
0
740 process_request_identities(e);-
741 break;
never executed: break;
0
742 case SSH2_AGENTC_ADD_IDENTITY:
never executed: case 17:
0
743 case SSH2_AGENTC_ADD_ID_CONSTRAINED:
never executed: case 25:
0
744 process_add_identity(e);-
745 break;
never executed: break;
0
746 case SSH2_AGENTC_REMOVE_IDENTITY:
never executed: case 18:
0
747 process_remove_identity(e);-
748 break;
never executed: break;
0
749 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
never executed: case 19:
0
750 process_remove_all_identities(e);-
751 break;
never executed: break;
0
752#ifdef ENABLE_PKCS11-
753 case SSH_AGENTC_ADD_SMARTCARD_KEY:
never executed: case 20:
0
754 case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
never executed: case 26:
0
755 process_add_smartcard_key(e);-
756 break;
never executed: break;
0
757 case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
never executed: case 21:
0
758 process_remove_smartcard_key(e);-
759 break;
never executed: break;
0
760#endif /* ENABLE_PKCS11 */-
761 default:
never executed: default:
0
762 /* Unknown message. Respond with failure. */-
763 error("Unknown message %d", type);-
764 sshbuf_reset(e->request);-
765 send_status(e, 0);-
766 break;
never executed: break;
0
767 }-
768 return 0;
never executed: return 0;
0
769}-
770-
771static void-
772new_socket(sock_type type, int fd)-
773{-
774 u_int i, old_alloc, new_alloc;-
775-
776 set_nonblock(fd);-
777-
778 if (fd > max_fd)
fd > max_fdDescription
TRUEnever evaluated
FALSEnever evaluated
0
779 max_fd = fd;
never executed: max_fd = fd;
0
780-
781 for (i = 0; i < sockets_alloc; i++)
i < sockets_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
782 if (sockets[i].type == AUTH_UNUSED) {
sockets[i].type == AUTH_UNUSEDDescription
TRUEnever evaluated
FALSEnever evaluated
0
783 sockets[i].fd = fd;-
784 if ((sockets[i].input = sshbuf_new()) == NULL)
(sockets[i].in...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
785 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
786 if ((sockets[i].output = sshbuf_new()) == NULL)
(sockets[i].ou...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
787 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
788 if ((sockets[i].request = sshbuf_new()) == NULL)
(sockets[i].re...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
789 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
790 sockets[i].type = type;-
791 return;
never executed: return;
0
792 }-
793 old_alloc = sockets_alloc;-
794 new_alloc = sockets_alloc + 10;-
795 sockets = xreallocarray(sockets, new_alloc, sizeof(sockets[0]));-
796 for (i = old_alloc; i < new_alloc; i++)
i < new_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
797 sockets[i].type = AUTH_UNUSED;
never executed: sockets[i].type = AUTH_UNUSED;
0
798 sockets_alloc = new_alloc;-
799 sockets[old_alloc].fd = fd;-
800 if ((sockets[old_alloc].input = sshbuf_new()) == NULL)
(sockets[old_a...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
801 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
802 if ((sockets[old_alloc].output = sshbuf_new()) == NULL)
(sockets[old_a...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
803 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
804 if ((sockets[old_alloc].request = sshbuf_new()) == NULL)
(sockets[old_a...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
805 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
806 sockets[old_alloc].type = type;-
807}
never executed: end of block
0
808-
809static int-
810handle_socket_read(u_int socknum)-
811{-
812 struct sockaddr_un sunaddr;-
813 socklen_t slen;-
814 uid_t euid;-
815 gid_t egid;-
816 int fd;-
817-
818 slen = sizeof(sunaddr);-
819 fd = accept(sockets[socknum].fd, (struct sockaddr *)&sunaddr, &slen);-
820 if (fd < 0) {
fd < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
821 error("accept from AUTH_SOCKET: %s", strerror(errno));-
822 return -1;
never executed: return -1;
0
823 }-
824 if (getpeereid(fd, &euid, &egid) < 0) {
getpeereid(fd,...id, &egid) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
825 error("getpeereid %d failed: %s", fd, strerror(errno));-
826 close(fd);-
827 return -1;
never executed: return -1;
0
828 }-
829 if ((euid != 0) && (getuid() != euid)) {
(euid != 0)Description
TRUEnever evaluated
FALSEnever evaluated
(getuid() != euid)Description
TRUEnever evaluated
FALSEnever evaluated
0
830 error("uid mismatch: peer euid %u != uid %u",-
831 (u_int) euid, (u_int) getuid());-
832 close(fd);-
833 return -1;
never executed: return -1;
0
834 }-
835 new_socket(AUTH_CONNECTION, fd);-
836 return 0;
never executed: return 0;
0
837}-
838-
839static int-
840handle_conn_read(u_int socknum)-
841{-
842 char buf[1024];-
843 ssize_t len;-
844 int r;-
845-
846 if ((len = read(sockets[socknum].fd, buf, sizeof(buf))) <= 0) {
(len = read(so...of(buf))) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
847 if (len == -1) {
len == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
848 if (errno == EAGAIN || errno == EINTR)
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
849 return 0;
never executed: return 0;
0
850 error("%s: read error on socket %u (fd %d): %s",-
851 __func__, socknum, sockets[socknum].fd,-
852 strerror(errno));-
853 }
never executed: end of block
0
854 return -1;
never executed: return -1;
0
855 }-
856 if ((r = sshbuf_put(sockets[socknum].input, buf, len)) != 0)
(r = sshbuf_pu...uf, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
857 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
858 explicit_bzero(buf, sizeof(buf));-
859 process_message(socknum);-
860 return 0;
never executed: return 0;
0
861}-
862-
863static int-
864handle_conn_write(u_int socknum)-
865{-
866 ssize_t len;-
867 int r;-
868-
869 if (sshbuf_len(sockets[socknum].output) == 0)
sshbuf_len(soc...].output) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
870 return 0; /* shouldn't happen */
never executed: return 0;
0
871 if ((len = write(sockets[socknum].fd,
(len = write(s...output))) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
872 sshbuf_ptr(sockets[socknum].output),
(len = write(s...output))) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
873 sshbuf_len(sockets[socknum].output))) <= 0) {
(len = write(s...output))) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
874 if (len == -1) {
len == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
875 if (errno == EAGAIN || errno == EINTR)
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
876 return 0;
never executed: return 0;
0
877 error("%s: read error on socket %u (fd %d): %s",-
878 __func__, socknum, sockets[socknum].fd,-
879 strerror(errno));-
880 }
never executed: end of block
0
881 return -1;
never executed: return -1;
0
882 }-
883 if ((r = sshbuf_consume(sockets[socknum].output, len)) != 0)
(r = sshbuf_co...ut, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
884 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
885 return 0;
never executed: return 0;
0
886}-
887-
888static void-
889after_poll(struct pollfd *pfd, size_t npfd, u_int maxfds)-
890{-
891 size_t i;-
892 u_int socknum, activefds = npfd;-
893-
894 for (i = 0; i < npfd; i++) {
i < npfdDescription
TRUEnever evaluated
FALSEnever evaluated
0
895 if (pfd[i].revents == 0)
pfd[i].revents == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
896 continue;
never executed: continue;
0
897 /* Find sockets entry */-
898 for (socknum = 0; socknum < sockets_alloc; socknum++) {
socknum < sockets_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
899 if (sockets[socknum].type != AUTH_SOCKET &&
sockets[socknu...!= AUTH_SOCKETDescription
TRUEnever evaluated
FALSEnever evaluated
0
900 sockets[socknum].type != AUTH_CONNECTION)
sockets[socknu...UTH_CONNECTIONDescription
TRUEnever evaluated
FALSEnever evaluated
0
901 continue;
never executed: continue;
0
902 if (pfd[i].fd == sockets[socknum].fd)
pfd[i].fd == s...ts[socknum].fdDescription
TRUEnever evaluated
FALSEnever evaluated
0
903 break;
never executed: break;
0
904 }
never executed: end of block
0
905 if (socknum >= sockets_alloc) {
socknum >= sockets_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
906 error("%s: no socket for fd %d", __func__, pfd[i].fd);-
907 continue;
never executed: continue;
0
908 }-
909 /* Process events */-
910 switch (sockets[socknum].type) {-
911 case AUTH_SOCKET:
never executed: case AUTH_SOCKET:
0
912 if ((pfd[i].revents & (POLLIN|POLLERR)) == 0)
(pfd[i].revent... 0x008 )) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
913 break;
never executed: break;
0
914 if (npfd > maxfds) {
npfd > maxfdsDescription
TRUEnever evaluated
FALSEnever evaluated
0
915 debug3("out of fds (active %u >= limit %u); "-
916 "skipping accept", activefds, maxfds);-
917 break;
never executed: break;
0
918 }-
919 if (handle_socket_read(socknum) == 0)
handle_socket_...(socknum) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
920 activefds++;
never executed: activefds++;
0
921 break;
never executed: break;
0
922 case AUTH_CONNECTION:
never executed: case AUTH_CONNECTION:
0
923 if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 &&
(pfd[i].revent... 0x008 )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
924 handle_conn_read(socknum) != 0) {
handle_conn_read(socknum) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
925 goto close_sock;
never executed: goto close_sock;
0
926 }-
927 if ((pfd[i].revents & (POLLOUT|POLLHUP)) != 0 &&
(pfd[i].revent... 0x010 )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
928 handle_conn_write(socknum) != 0) {
handle_conn_wr...(socknum) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
929 close_sock:-
930 if (activefds == 0)
activefds == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
931 fatal("activefds == 0 at close_sock");
never executed: fatal("activefds == 0 at close_sock");
0
932 close_socket(&sockets[socknum]);-
933 activefds--;-
934 break;
never executed: break;
0
935 }-
936 break;
never executed: break;
0
937 default:
never executed: default:
0
938 break;
never executed: break;
0
939 }-
940 }-
941}
never executed: end of block
0
942-
943static int-
944prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds)-
945{-
946 struct pollfd *pfd = *pfdp;-
947 size_t i, j, npfd = 0;-
948 time_t deadline;-
949-
950 /* Count active sockets */-
951 for (i = 0; i < sockets_alloc; i++) {
i < sockets_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
952 switch (sockets[i].type) {-
953 case AUTH_SOCKET:
never executed: case AUTH_SOCKET:
0
954 case AUTH_CONNECTION:
never executed: case AUTH_CONNECTION:
0
955 npfd++;-
956 break;
never executed: break;
0
957 case AUTH_UNUSED:
never executed: case AUTH_UNUSED:
0
958 break;
never executed: break;
0
959 default:
never executed: default:
0
960 fatal("Unknown socket type %d", sockets[i].type);-
961 break;
never executed: break;
0
962 }-
963 }-
964 if (npfd != *npfdp &&
npfd != *npfdpDescription
TRUEnever evaluated
FALSEnever evaluated
0
965 (pfd = recallocarray(pfd, *npfdp, npfd, sizeof(*pfd))) == NULL)
(pfd = recallo...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
966 fatal("%s: recallocarray failed", __func__);
never executed: fatal("%s: recallocarray failed", __func__);
0
967 *pfdp = pfd;-
968 *npfdp = npfd;-
969-
970 for (i = j = 0; i < sockets_alloc; i++) {
i < sockets_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
971 switch (sockets[i].type) {-
972 case AUTH_SOCKET:
never executed: case AUTH_SOCKET:
0
973 if (npfd > maxfds) {
npfd > maxfdsDescription
TRUEnever evaluated
FALSEnever evaluated
0
974 debug3("out of fds (active %zu >= limit %u); "-
975 "skipping arming listener", npfd, maxfds);-
976 break;
never executed: break;
0
977 }-
978 pfd[j].fd = sockets[i].fd;-
979 pfd[j].revents = 0;-
980 pfd[j].events = POLLIN;-
981 j++;-
982 break;
never executed: break;
0
983 case AUTH_CONNECTION:
never executed: case AUTH_CONNECTION:
0
984 pfd[j].fd = sockets[i].fd;-
985 pfd[j].revents = 0;-
986 /* XXX backoff when input buffer full */-
987 pfd[j].events = POLLIN;-
988 if (sshbuf_len(sockets[i].output) > 0)
sshbuf_len(soc...i].output) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
989 pfd[j].events |= POLLOUT;
never executed: pfd[j].events |= 0x004 ;
0
990 j++;-
991 break;
never executed: break;
0
992 default:
never executed: default:
0
993 break;
never executed: break;
0
994 }-
995 }-
996 deadline = reaper();-
997 if (parent_alive_interval != 0)
parent_alive_interval != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
998 deadline = (deadline == 0) ? parent_alive_interval :
never executed: deadline = (deadline == 0) ? parent_alive_interval : (((deadline) < (parent_alive_interval)) ? (deadline) : (parent_alive_interval));
(deadline == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
999 MINIMUM(deadline, parent_alive_interval);
never executed: deadline = (deadline == 0) ? parent_alive_interval : (((deadline) < (parent_alive_interval)) ? (deadline) : (parent_alive_interval));
((deadline) < ...ive_interval))Description
TRUEnever evaluated
FALSEnever evaluated
0
1000 if (deadline == 0) {
deadline == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1001 *timeoutp = -1; /* INFTIM */-
1002 } else {
never executed: end of block
0
1003 if (deadline > INT_MAX / 1000)
deadline > 0x7fffffff / 1000Description
TRUEnever evaluated
FALSEnever evaluated
0
1004 *timeoutp = INT_MAX / 1000;
never executed: *timeoutp = 0x7fffffff / 1000;
0
1005 else-
1006 *timeoutp = deadline * 1000;
never executed: *timeoutp = deadline * 1000;
0
1007 }-
1008 return (1);
never executed: return (1);
0
1009}-
1010-
1011static void-
1012cleanup_socket(void)-
1013{-
1014 if (cleanup_pid != 0 && getpid() != cleanup_pid)
cleanup_pid != 0Description
TRUEnever evaluated
FALSEnever evaluated
getpid() != cleanup_pidDescription
TRUEnever evaluated
FALSEnever evaluated
0
1015 return;
never executed: return;
0
1016 debug("%s: cleanup", __func__);-
1017 if (socket_name[0])
socket_name[0]Description
TRUEnever evaluated
FALSEnever evaluated
0
1018 unlink(socket_name);
never executed: unlink(socket_name);
0
1019 if (socket_dir[0])
socket_dir[0]Description
TRUEnever evaluated
FALSEnever evaluated
0
1020 rmdir(socket_dir);
never executed: rmdir(socket_dir);
0
1021}
never executed: end of block
0
1022-
1023void-
1024cleanup_exit(int i)-
1025{-
1026 cleanup_socket();-
1027 _exit(i);-
1028}
never executed: end of block
0
1029-
1030/*ARGSUSED*/-
1031static void-
1032cleanup_handler(int sig)-
1033{-
1034 cleanup_socket();-
1035#ifdef ENABLE_PKCS11-
1036 pkcs11_terminate();-
1037#endif-
1038 _exit(2);-
1039}
never executed: end of block
0
1040-
1041static void-
1042check_parent_exists(void)-
1043{-
1044 /*-
1045 * If our parent has exited then getppid() will return (pid_t)1,-
1046 * so testing for that should be safe.-
1047 */-
1048 if (parent_pid != -1 && getppid() != parent_pid) {
parent_pid != -1Description
TRUEnever evaluated
FALSEnever evaluated
getppid() != parent_pidDescription
TRUEnever evaluated
FALSEnever evaluated
0
1049 /* printf("Parent has died - Authentication agent exiting.\n"); */-
1050 cleanup_socket();-
1051 _exit(2);-
1052 }
never executed: end of block
0
1053}
never executed: end of block
0
1054-
1055static void-
1056usage(void)-
1057{-
1058 fprintf(stderr,-
1059 "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"-
1060 " [-P pkcs11_whitelist] [-t life] [command [arg ...]]\n"-
1061 " ssh-agent [-c | -s] -k\n");-
1062 exit(1);
never executed: exit(1);
0
1063}-
1064-
1065int-
1066main(int ac, char **av)-
1067{-
1068 int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;-
1069 int sock, fd, ch, result, saved_errno;-
1070 char *shell, *format, *pidstr, *agentsocket = NULL;-
1071#ifdef HAVE_SETRLIMIT-
1072 struct rlimit rlim;-
1073#endif-
1074 extern int optind;-
1075 extern char *optarg;-
1076 pid_t pid;-
1077 char pidstrbuf[1 + 3 * sizeof pid];-
1078 size_t len;-
1079 mode_t prev_mask;-
1080 int timeout = -1; /* INFTIM */-
1081 struct pollfd *pfd = NULL;-
1082 size_t npfd = 0;-
1083 u_int maxfds;-
1084-
1085 ssh_malloc_init(); /* must be called before any mallocs */-
1086 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */-
1087 sanitise_stdfd();-
1088-
1089 /* drop */-
1090 setegid(getgid());-
1091 setgid(getgid());-
1092-
1093 platform_disable_tracing(0); /* strict=no */-
1094-
1095 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
getrlimit( RLI..., &rlim) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1096 fatal("%s: getrlimit: %s", __progname, strerror(errno));
never executed: fatal("%s: getrlimit: %s", __progname, strerror( (*__errno_location ()) ));
0
1097-
1098#ifdef WITH_OPENSSL-
1099 OpenSSL_add_all_algorithms();-
1100#endif-
1101-
1102 __progname = ssh_get_progname(av[0]);-
1103 seed_rng();-
1104-
1105 while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {
(ch = BSDgetop...:P:t:")) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1106 switch (ch) {-
1107 case 'E':
never executed: case 'E':
0
1108 fingerprint_hash = ssh_digest_alg_by_name(optarg);-
1109 if (fingerprint_hash == -1)
fingerprint_hash == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1110 fatal("Invalid hash algorithm \"%s\"", optarg);
never executed: fatal("Invalid hash algorithm \"%s\"", BSDoptarg);
0
1111 break;
never executed: break;
0
1112 case 'c':
never executed: case 'c':
0
1113 if (s_flag)
s_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1114 usage();
never executed: usage();
0
1115 c_flag++;-
1116 break;
never executed: break;
0
1117 case 'k':
never executed: case 'k':
0
1118 k_flag++;-
1119 break;
never executed: break;
0
1120 case 'P':
never executed: case 'P':
0
1121 if (pkcs11_whitelist != NULL)
pkcs11_whiteli...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1122 fatal("-P option already specified");
never executed: fatal("-P option already specified");
0
1123 pkcs11_whitelist = xstrdup(optarg);-
1124 break;
never executed: break;
0
1125 case 's':
never executed: case 's':
0
1126 if (c_flag)
c_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1127 usage();
never executed: usage();
0
1128 s_flag++;-
1129 break;
never executed: break;
0
1130 case 'd':
never executed: case 'd':
0
1131 if (d_flag || D_flag)
d_flagDescription
TRUEnever evaluated
FALSEnever evaluated
D_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1132 usage();
never executed: usage();
0
1133 d_flag++;-
1134 break;
never executed: break;
0
1135 case 'D':
never executed: case 'D':
0
1136 if (d_flag || D_flag)
d_flagDescription
TRUEnever evaluated
FALSEnever evaluated
D_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1137 usage();
never executed: usage();
0
1138 D_flag++;-
1139 break;
never executed: break;
0
1140 case 'a':
never executed: case 'a':
0
1141 agentsocket = optarg;-
1142 break;
never executed: break;
0
1143 case 't':
never executed: case 't':
0
1144 if ((lifetime = convtime(optarg)) == -1) {
(lifetime = co...optarg)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1145 fprintf(stderr, "Invalid lifetime\n");-
1146 usage();-
1147 }
never executed: end of block
0
1148 break;
never executed: break;
0
1149 default:
never executed: default:
0
1150 usage();-
1151 }
never executed: end of block
0
1152 }-
1153 ac -= optind;-
1154 av += optind;-
1155-
1156 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
ac > 0Description
TRUEnever evaluated
FALSEnever evaluated
c_flagDescription
TRUEnever evaluated
FALSEnever evaluated
k_flagDescription
TRUEnever evaluated
FALSEnever evaluated
s_flagDescription
TRUEnever evaluated
FALSEnever evaluated
d_flagDescription
TRUEnever evaluated
FALSEnever evaluated
D_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1157 usage();
never executed: usage();
0
1158-
1159 if (pkcs11_whitelist == NULL)
pkcs11_whiteli...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1160 pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST);
never executed: pkcs11_whitelist = xstrdup("/usr/lib*/*,/usr/local/lib*/*");
0
1161-
1162 if (ac == 0 && !c_flag && !s_flag) {
ac == 0Description
TRUEnever evaluated
FALSEnever evaluated
!c_flagDescription
TRUEnever evaluated
FALSEnever evaluated
!s_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1163 shell = getenv("SHELL");-
1164 if (shell != NULL && (len = strlen(shell)) > 2 &&
shell != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
(len = strlen(shell)) > 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1165 strncmp(shell + len - 3, "csh", 3) == 0)
never executed: __result = (((const unsigned char *) (const char *) ( shell + len - 3 ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "csh" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
(__extension__..." , 3 ))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( 3 )Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons...ll + len - 3 )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( shell...size_t) ( 3 ))Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( "csh" )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( "csh"...size_t) ( 3 ))Description
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
1166 c_flag = 1;
never executed: c_flag = 1;
0
1167 }
never executed: end of block
0
1168 if (k_flag) {
k_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1169 const char *errstr = NULL;-
1170-
1171 pidstr = getenv(SSH_AGENTPID_ENV_NAME);-
1172 if (pidstr == NULL) {
pidstr == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1173 fprintf(stderr, "%s not set, cannot kill agent\n",-
1174 SSH_AGENTPID_ENV_NAME);-
1175 exit(1);
never executed: exit(1);
0
1176 }-
1177 pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr);-
1178 if (errstr) {
errstrDescription
TRUEnever evaluated
FALSEnever evaluated
0
1179 fprintf(stderr,-
1180 "%s=\"%s\", which is not a good PID: %s\n",-
1181 SSH_AGENTPID_ENV_NAME, pidstr, errstr);-
1182 exit(1);
never executed: exit(1);
0
1183 }-
1184 if (kill(pid, SIGTERM) == -1) {
kill(pid, 15 ) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1185 perror("kill");-
1186 exit(1);
never executed: exit(1);
0
1187 }-
1188 format = c_flag ? "unsetenv %s;\n" : "unset %s;\n";
c_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1189 printf(format, SSH_AUTHSOCKET_ENV_NAME);-
1190 printf(format, SSH_AGENTPID_ENV_NAME);-
1191 printf("echo Agent pid %ld killed;\n", (long)pid);-
1192 exit(0);
never executed: exit(0);
0
1193 }-
1194-
1195 /*-
1196 * Minimum file descriptors:-
1197 * stdio (3) + listener (1) + syslog (1 maybe) + connection (1) +-
1198 * a few spare for libc / stack protectors / sanitisers, etc.-
1199 */-
1200#define SSH_AGENT_MIN_FDS (3+1+1+1+4)-
1201 if (rlim.rlim_cur < SSH_AGENT_MIN_FDS)
rlim.rlim_cur < (3+1+1+1+4)Description
TRUEnever evaluated
FALSEnever evaluated
0
1202 fatal("%s: file descriptior rlimit %lld too low (minimum %u)",
never executed: fatal("%s: file descriptior rlimit %lld too low (minimum %u)", __progname, (long long)rlim.rlim_cur, (3+1+1+1+4));
0
1203 __progname, (long long)rlim.rlim_cur, SSH_AGENT_MIN_FDS);
never executed: fatal("%s: file descriptior rlimit %lld too low (minimum %u)", __progname, (long long)rlim.rlim_cur, (3+1+1+1+4));
0
1204 maxfds = rlim.rlim_cur - SSH_AGENT_MIN_FDS;-
1205-
1206 parent_pid = getpid();-
1207-
1208 if (agentsocket == NULL) {
agentsocket == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1209 /* Create private directory for agent socket */-
1210 mktemp_proto(socket_dir, sizeof(socket_dir));-
1211 if (mkdtemp(socket_dir) == NULL) {
mkdtemp(socket...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1212 perror("mkdtemp: private socket dir");-
1213 exit(1);
never executed: exit(1);
0
1214 }-
1215 snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,-
1216 (long)parent_pid);-
1217 } else {
never executed: end of block
0
1218 /* Try to use specified agent socket */-
1219 socket_dir[0] = '\0';-
1220 strlcpy(socket_name, agentsocket, sizeof socket_name);-
1221 }
never executed: end of block
0
1222-
1223 /*-
1224 * Create socket early so it will exist before command gets run from-
1225 * the parent.-
1226 */-
1227 prev_mask = umask(0177);-
1228 sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0);-
1229 if (sock < 0) {
sock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1230 /* XXX - unix_listener() calls error() not perror() */-
1231 *socket_name = '\0'; /* Don't unlink any existing file */-
1232 cleanup_exit(1);-
1233 }
never executed: end of block
0
1234 umask(prev_mask);-
1235-
1236 /*-
1237 * Fork, and have the parent execute the command, if any, or present-
1238 * the socket data. The child continues as the authentication agent.-
1239 */-
1240 if (D_flag || d_flag) {
D_flagDescription
TRUEnever evaluated
FALSEnever evaluated
d_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1241 log_init(__progname,-
1242 d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,-
1243 SYSLOG_FACILITY_AUTH, 1);-
1244 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
c_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1245 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,-
1246 SSH_AUTHSOCKET_ENV_NAME);-
1247 printf("echo Agent pid %ld;\n", (long)parent_pid);-
1248 fflush(stdout);-
1249 goto skip;
never executed: goto skip;
0
1250 }-
1251 pid = fork();-
1252 if (pid == -1) {
pid == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1253 perror("fork");-
1254 cleanup_exit(1);-
1255 }
never executed: end of block
0
1256 if (pid != 0) { /* Parent - execute the given command. */
pid != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1257 close(sock);-
1258 snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid);-
1259 if (ac == 0) {
ac == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1260 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
c_flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1261 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,-
1262 SSH_AUTHSOCKET_ENV_NAME);-
1263 printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf,-
1264 SSH_AGENTPID_ENV_NAME);-
1265 printf("echo Agent pid %ld;\n", (long)pid);-
1266 exit(0);
never executed: exit(0);
0
1267 }-
1268 if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 ||
setenv("SSH_AU...name, 1) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1269 setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) {
setenv("SSH_AG...rbuf, 1) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1270 perror("setenv");-
1271 exit(1);
never executed: exit(1);
0
1272 }-
1273 execvp(av[0], av);-
1274 perror(av[0]);-
1275 exit(1);
never executed: exit(1);
0
1276 }-
1277 /* child */-
1278 log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0);-
1279-
1280 if (setsid() == -1) {
setsid() == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1281 error("setsid: %s", strerror(errno));-
1282 cleanup_exit(1);-
1283 }
never executed: end of block
0
1284-
1285 (void)chdir("/");-
1286 if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
(fd = open( "/...02 , 0)) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1287 /* XXX might close listen socket */-
1288 (void)dup2(fd, STDIN_FILENO);-
1289 (void)dup2(fd, STDOUT_FILENO);-
1290 (void)dup2(fd, STDERR_FILENO);-
1291 if (fd > 2)
fd > 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1292 close(fd);
never executed: close(fd);
0
1293 }
never executed: end of block
0
1294-
1295#ifdef HAVE_SETRLIMIT-
1296 /* deny core dumps, since memory contains unencrypted private keys */-
1297 rlim.rlim_cur = rlim.rlim_max = 0;-
1298 if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
setrlimit( RLI...E , &rlim) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1299 error("setrlimit RLIMIT_CORE: %s", strerror(errno));-
1300 cleanup_exit(1);-
1301 }
never executed: end of block
0
1302#endif-
1303-
1304skip:
code before this statement never executed: skip:
0
1305-
1306 cleanup_pid = getpid();-
1307-
1308#ifdef ENABLE_PKCS11-
1309 pkcs11_init(0);-
1310#endif-
1311 new_socket(AUTH_SOCKET, sock);-
1312 if (ac > 0)
ac > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1313 parent_alive_interval = 10;
never executed: parent_alive_interval = 10;
0
1314 idtab_init();-
1315 signal(SIGPIPE, SIG_IGN);-
1316 signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);-
1317 signal(SIGHUP, cleanup_handler);-
1318 signal(SIGTERM, cleanup_handler);-
1319-
1320 if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1)
pledge("stdio ...d *)0) ) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1321 fatal("%s: pledge: %s", __progname, strerror(errno));
never executed: fatal("%s: pledge: %s", __progname, strerror( (*__errno_location ()) ));
0
1322 platform_pledge_agent();-
1323-
1324 while (1) {-
1325 prepare_poll(&pfd, &npfd, &timeout, maxfds);-
1326 result = poll(pfd, npfd, timeout);-
1327 saved_errno = errno;-
1328 if (parent_alive_interval != 0)
parent_alive_interval != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1329 check_parent_exists();
never executed: check_parent_exists();
0
1330 (void) reaper(); /* remove expired keys */-
1331 if (result < 0) {
result < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1332 if (saved_errno == EINTR)
saved_errno == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1333 continue;
never executed: continue;
0
1334 fatal("poll: %s", strerror(saved_errno));-
1335 } else if (result > 0)
never executed: end of block
result > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1336 after_poll(pfd, npfd, maxfds);
never executed: after_poll(pfd, npfd, maxfds);
0
1337 }
never executed: end of block
0
1338 /* NOTREACHED */-
1339}
never executed: end of block
0
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2