11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: ssh-agent.c,v 1.172 2011/06/03 01:37:40 dtucker Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Author: Tatu Ylonen <ylo@cs.hut.fi> 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * All rights reserved 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The authentication agent program. 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose. Any derived versions of this 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell". 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/param.h> 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/resource.h> 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/stat.h> 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h> 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_TIME_H 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <sys/time.h> 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_UN_H 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <sys/un.h> 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/sys-queue.h" 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/evp.h> 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/md5.h> 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/openssl-compat.h" 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <fcntl.h> 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PATHS_H 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <paths.h> 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h> 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h> 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <time.h> 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h> 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh.h" 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "rsa.h" 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h" 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "authfd.h" 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "compat.h" 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h" 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef ENABLE_PKCS11 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh-pkcs11.h" 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(HAVE_SYS_PRCTL_H) 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/prctl.h> /* For prctl() and PR_SET_DUMPABLE */ 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef enum { 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood AUTH_UNUSED, 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood AUTH_SOCKET, 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood AUTH_CONNECTION 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} sock_type; 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef struct { 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int fd; 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sock_type type; 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer input; 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer output; 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer request; 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} SocketEntry; 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int sockets_alloc = 0; 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodSocketEntry *sockets = NULL; 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef struct identity { 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_ENTRY(identity) next; 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *key; 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *comment; 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *provider; 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int death; 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int confirm; 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} Identity; 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef struct { 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int nentries; 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_HEAD(idqueue, identity) idlist; 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} Idtab; 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* private key table, one per protocol version */ 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodIdtab idtable[3]; 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint max_fd = 0; 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* pid of shell == parent of agent */ 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpid_t parent_pid = -1; 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int parent_alive_interval = 0; 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* pathname and directory for AUTH_SOCKET */ 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar socket_name[MAXPATHLEN]; 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar socket_dir[MAXPATHLEN]; 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* locking */ 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint locked = 0; 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar *lock_passwd = NULL; 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern char *__progname; 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Default lifetime (0 == forever) */ 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int lifetime = 0; 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclose_socket(SocketEntry *e) 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(e->fd); 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood e->fd = -1; 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood e->type = AUTH_UNUSED; 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&e->input); 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&e->output); 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&e->request); 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodidtab_init(void) 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i <=2; i++) { 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INIT(&idtable[i].idlist); 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idtable[i].nentries = 0; 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* return private key table for requested protocol version */ 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Idtab * 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodidtab_lookup(int version) 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (version < 1 || version > 2) 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("internal error, bad protocol version %d", version); 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return &idtable[version]; 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfree_identity(Identity *id) 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(id->key); 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->provider != NULL) 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(id->provider); 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(id->comment); 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(id); 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* return matching private key for given public key */ 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Identity * 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodlookup_identity(Key *key, int version) 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id; 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idtab *tab = idtab_lookup(version); 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_FOREACH(id, &tab->idlist, next) { 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_equal(key, id->key)) 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (id); 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (NULL); 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Check confirmation of keysign request */ 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconfirm_key(Identity *id) 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *p; 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret = -1; 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->comment, p)) 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = 0; 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(p); 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (ret); 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* send list of supported public keys to 'client' */ 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_request_identities(SocketEntry *e, int version) 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idtab *tab = idtab_lookup(version); 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id; 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer msg; 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&msg); 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&msg, (version == 1) ? 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&msg, tab->nentries); 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_FOREACH(id, &tab->idlist, next) { 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->key->type == KEY_RSA1) { 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum(&msg, id->key->rsa->e); 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum(&msg, id->key->rsa->n); 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *blob; 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int blen; 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_to_blob(id->key, &blob, &blen); 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&msg, blob, blen); 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&msg, id->comment); 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, buffer_len(&msg)); 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&msg); 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ssh1 only */ 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_authentication_challenge1(SocketEntry *e) 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char buf[32], mdbuf[16], session_id[16]; 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int response_type; 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *challenge; 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id; 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i, len; 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer msg; 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_CTX md; 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *key; 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&msg); 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_new(KEY_RSA1); 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((challenge = BN_new()) == NULL) 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("process_authentication_challenge1: BN_new failed"); 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void) buffer_get_int(&e->request); /* ignored */ 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, key->rsa->e); 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, key->rsa->n); 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, challenge); 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Only protocol 1.1 is supported */ 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&e->request) == 0) 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto failure; 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get(&e->request, session_id, 16); 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood response_type = buffer_get_int(&e->request); 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (response_type != 1) 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto failure; 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id = lookup_identity(key, 1); 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *private = id->key; 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Decrypt the challenge using the private key. */ 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto failure; 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* The response is MD5 of decrypted challenge plus session id. */ 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = BN_num_bytes(challenge); 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len <= 0 || len > 32) { 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("process_authentication_challenge: bad challenge length %d", len); 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto failure; 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(buf, 0, 32); 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_bn2bin(challenge, buf + 32 - len); 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Init(&md); 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&md, buf, 32); 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&md, session_id, 16); 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Final(mdbuf, &md); 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Send the response. */ 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < 16; i++) 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&msg, mdbuf[i]); 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto send; 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfailure: 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Unknown identity or protocol error. Send failure. */ 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&msg, SSH_AGENT_FAILURE); 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsend: 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, buffer_len(&msg)); 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(key); 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_clear_free(challenge); 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&msg); 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ssh2 only */ 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_sign_request2(SocketEntry *e) 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *blob, *data, *signature = NULL; 3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int blen, dlen, slen = 0; 3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood extern int datafellows; 3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int odatafellows; 3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ok = -1, flags; 3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer msg; 3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *key; 3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood datafellows = 0; 3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood blob = buffer_get_string(&e->request, &blen); 3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood data = buffer_get_string(&e->request, &dlen); 3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flags = buffer_get_int(&e->request); 3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood odatafellows = datafellows; 3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (flags & SSH_AGENT_OLD_SIGNATURE) 3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood datafellows = SSH_BUG_SIGBLOB; 3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_from_blob(blob, blen); 3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key != NULL) { 3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id = lookup_identity(key, 2); 3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id != NULL && (!id->confirm || confirm_key(id) == 0)) 3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ok = key_sign(id->key, &signature, &slen, data, dlen); 3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(key); 3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&msg); 3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ok == 0) { 3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); 3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&msg, signature, slen); 3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&msg, SSH_AGENT_FAILURE); 3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, buffer_len(&msg)); 3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&e->output, buffer_ptr(&msg), 3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&msg)); 3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&msg); 3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(data); 3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (signature != NULL) 3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(signature); 3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood datafellows = odatafellows; 3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* shared */ 3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_remove_identity(SocketEntry *e, int version) 3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int blen, bits; 3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int success = 0; 3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *key = NULL; 3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *blob; 3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (version) { 3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 1: 3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_new(KEY_RSA1); 3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bits = buffer_get_int(&e->request); 3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, key->rsa->e); 3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, key->rsa->n); 3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bits != key_size(key)) 3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Warning: identity keysize mismatch: actual %u, announced %u", 3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_size(key), bits); 3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 2: 3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood blob = buffer_get_string(&e->request, &blen); 3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_from_blob(blob, blen); 3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key != NULL) { 3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id = lookup_identity(key, version); 3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id != NULL) { 3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We have this key. Free the old key. Since we 3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * don't want to leave empty slots in the middle of 3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the array, we actually free the key there and move 3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * all the entries between the empty slot and the end 3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * of the array. 3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idtab *tab = idtab_lookup(version); 3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tab->nentries < 1) 3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("process_remove_identity: " 3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "internal error: tab->nentries %d", 3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab->nentries); 3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&tab->idlist, id, next); 4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free_identity(id); 4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab->nentries--; 4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(key); 4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, 1); 4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&e->output, 4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_remove_all_identities(SocketEntry *e, int version) 4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idtab *tab = idtab_lookup(version); 4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id; 4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Loop over all identities and clear the keys. */ 4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (id = TAILQ_FIRST(&tab->idlist); id; 4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id = TAILQ_FIRST(&tab->idlist)) { 4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&tab->idlist, id, next); 4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free_identity(id); 4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Mark that there are no identities. */ 4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab->nentries = 0; 4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Send success. */ 4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, 1); 4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&e->output, SSH_AGENT_SUCCESS); 4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* removes expired keys and returns number of seconds until the next expiry */ 4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic u_int 4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodreaper(void) 4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int deadline = 0, now = time(NULL); 4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id, *nxt; 4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int version; 4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idtab *tab; 4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (version = 1; version < 3; version++) { 4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab = idtab_lookup(version); 4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { 4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nxt = TAILQ_NEXT(id, next); 4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->death == 0) 4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (now >= id->death) { 4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("expiring key '%s'", id->comment); 4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&tab->idlist, id, next); 4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free_identity(id); 4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab->nentries--; 4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood deadline = (deadline == 0) ? id->death : 4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MIN(deadline, id->death); 4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (deadline == 0 || deadline <= now) 4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (deadline - now); 4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_add_identity(SocketEntry *e, int version) 4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idtab *tab = idtab_lookup(version); 4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id; 4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int type, success = 0, death = 0, confirm = 0; 4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *type_name, *comment; 4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *k = NULL; 4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *exponent; 4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_POINT *q; 4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *curve; 4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *cert; 4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len; 4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (version) { 4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 1: 4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k = key_new_private(KEY_RSA1); 4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void) buffer_get_int(&e->request); /* ignored */ 4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, k->rsa->n); 4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, k->rsa->e); 4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, k->rsa->d); 4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, k->rsa->iqmp); 4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* SSH and SSL have p and q swapped */ 4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, k->rsa->q); /* p */ 4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum(&e->request, k->rsa->p); /* q */ 4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Generate additional parameters */ 4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rsa_generate_additional_parameters(k->rsa); 4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 2: 4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood type_name = buffer_get_string(&e->request, NULL); 4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood type = key_type_from_name(type_name); 4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (type) { 4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k = key_new_private(type); 5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->dsa->p); 5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->dsa->q); 5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->dsa->g); 5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->dsa->pub_key); 5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->dsa->priv_key); 5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert = buffer_get_string(&e->request, &len); 5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k = key_from_blob(cert, len)) == NULL) 5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Certificate parse failed"); 5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(cert); 5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_add_private(k); 5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->dsa->priv_key); 5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k = key_new_private(type); 5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->ecdsa_nid = key_ecdsa_nid_from_name(type_name); 5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood curve = buffer_get_string(&e->request, NULL); 5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->ecdsa_nid != key_curve_name_to_nid(curve)) 5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: curve names mismatch", __func__); 5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(curve); 5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); 5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->ecdsa == NULL) 5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_new_by_curve_name failed", 5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa)); 5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (q == NULL) 5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_new failed", __func__); 5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((exponent = BN_new()) == NULL) 5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_new failed", __func__); 5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_ecpoint(&e->request, 5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_group(k->ecdsa), q); 5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, exponent); 5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_KEY_set_public_key(k->ecdsa, q) != 1) 5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_set_public_key failed", 5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) 5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_set_private_key failed", 5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), 5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(k->ecdsa)) != 0) 5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: bad ECDSA public key", __func__); 5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_ec_validate_private(k->ecdsa) != 0) 5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: bad ECDSA private key", __func__); 5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_clear_free(exponent); 5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_POINT_free(q); 5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert = buffer_get_string(&e->request, &len); 5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k = key_from_blob(cert, len)) == NULL) 5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Certificate parse failed"); 5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(cert); 5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_add_private(k); 5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((exponent = BN_new()) == NULL) 5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_new failed", __func__); 5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, exponent); 5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) 5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_set_private_key failed", 5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), 5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(k->ecdsa)) != 0 || 5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_ec_validate_private(k->ecdsa) != 0) 5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: bad ECDSA key", __func__); 5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_clear_free(exponent); 5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* OPENSSL_HAS_ECC */ 5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k = key_new_private(type); 5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->n); 5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->e); 5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->d); 5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->iqmp); 5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->p); 5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->q); 5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Generate additional parameters */ 5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rsa_generate_additional_parameters(k->rsa); 5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert = buffer_get_string(&e->request, &len); 5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k = key_from_blob(cert, len)) == NULL) 5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Certificate parse failed"); 5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(cert); 5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_add_private(k); 5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->d); 5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->iqmp); 5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->p); 5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2(&e->request, k->rsa->q); 5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(type_name); 5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&e->request); 5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto send; 5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(type_name); 5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* enable blinding */ 6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (RSA_blinding_on(k->rsa, NULL) != 1) { 6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("process_add_identity: RSA_blinding_on failed"); 6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(k); 6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto send; 6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood comment = buffer_get_string(&e->request, NULL); 6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k == NULL) { 6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(comment); 6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto send; 6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (buffer_len(&e->request)) { 6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch ((type = buffer_get_char(&e->request))) { 6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENT_CONSTRAIN_LIFETIME: 6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood death = time(NULL) + buffer_get_int(&e->request); 6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENT_CONSTRAIN_CONFIRM: 6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood confirm = 1; 6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("process_add_identity: " 6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Unknown constraint type %d", type); 6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(comment); 6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(k); 6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto send; 6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (lifetime && !death) 6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood death = time(NULL) + lifetime; 6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((id = lookup_identity(k, version)) == NULL) { 6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id = xcalloc(1, sizeof(Identity)); 6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->key = k; 6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INSERT_TAIL(&tab->idlist, id, next); 6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Increment the number of identities. */ 6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab->nentries++; 6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(k); 6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(id->comment); 6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->comment = comment; 6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->death = death; 6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->confirm = confirm; 6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsend: 6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, 1); 6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&e->output, 6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* XXX todo: encrypt sensitive data with passphrase */ 6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_lock_agent(SocketEntry *e, int lock) 6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int success = 0; 6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *passwd; 6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood passwd = buffer_get_string(&e->request, NULL); 6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { 6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood locked = 0; 6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(lock_passwd, 0, strlen(lock_passwd)); 6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(lock_passwd); 6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood lock_passwd = NULL; 6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (!locked && lock) { 6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood locked = 1; 6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood lock_passwd = xstrdup(passwd); 6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(passwd, 0, strlen(passwd)); 6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(passwd); 6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, 1); 6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&e->output, 6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodno_identities(SocketEntry *e, u_int type) 6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer msg; 6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&msg); 6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&msg, 6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? 6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); 6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&msg, 0); 6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, buffer_len(&msg)); 6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&msg); 6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef ENABLE_PKCS11 7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_add_smartcard_key(SocketEntry *e) 7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *provider = NULL, *pin; 7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i, type, version, count = 0, success = 0, death = 0, confirm = 0; 7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key **keys = NULL, *k; 7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id; 7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idtab *tab; 7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood provider = buffer_get_string(&e->request, NULL); 7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pin = buffer_get_string(&e->request, NULL); 7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (buffer_len(&e->request)) { 7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch ((type = buffer_get_char(&e->request))) { 7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENT_CONSTRAIN_LIFETIME: 7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood death = time(NULL) + buffer_get_int(&e->request); 7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENT_CONSTRAIN_CONFIRM: 7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood confirm = 1; 7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("process_add_smartcard_key: " 7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Unknown constraint type %d", type); 7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto send; 7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (lifetime && !death) 7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood death = time(NULL) + lifetime; 7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood count = pkcs11_add_provider(provider, pin, &keys); 7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < count; i++) { 7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k = keys[i]; 7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood version = k->type == KEY_RSA1 ? 1 : 2; 7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab = idtab_lookup(version); 7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (lookup_identity(k, version) == NULL) { 7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id = xcalloc(1, sizeof(Identity)); 7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->key = k; 7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->provider = xstrdup(provider); 7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->comment = xstrdup(provider); /* XXX */ 7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->death = death; 7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->confirm = confirm; 7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INSERT_TAIL(&tab->idlist, id, next); 7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab->nentries++; 7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(k); 7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood keys[i] = NULL; 7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsend: 7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pin) 7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(pin); 7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (provider) 7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(provider); 7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (keys) 7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(keys); 7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, 1); 7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&e->output, 7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_remove_smartcard_key(SocketEntry *e) 7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *provider = NULL, *pin = NULL; 7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int version, success = 0; 7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id, *nxt; 7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idtab *tab; 7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood provider = buffer_get_string(&e->request, NULL); 7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pin = buffer_get_string(&e->request, NULL); 7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(pin); 7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (version = 1; version < 3; version++) { 7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab = idtab_lookup(version); 7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { 7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nxt = TAILQ_NEXT(id, next); 7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!strcmp(provider, id->provider)) { 7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&tab->idlist, id, next); 7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free_identity(id); 7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tab->nentries--; 7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pkcs11_del_provider(provider) == 0) 7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("process_remove_smartcard_key:" 7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood " pkcs11_del_provider failed"); 7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(provider); 7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, 1); 7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&e->output, 7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* ENABLE_PKCS11 */ 7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* dispatch incoming messages */ 7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_message(SocketEntry *e) 8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int msg_len, type; 8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *cp; 8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&e->input) < 5) 8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; /* Incomplete message. */ 8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp = buffer_ptr(&e->input); 8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg_len = get_u32(cp); 8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (msg_len > 256 * 1024) { 8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close_socket(e); 8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&e->input) < msg_len + 4) 8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* move the current input to e->request */ 8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_consume(&e->input, 4); 8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&e->request); 8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&e->request, buffer_ptr(&e->input), msg_len); 8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_consume(&e->input, msg_len); 8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood type = buffer_get_char(&e->request); 8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* check wheter agent is locked */ 8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (locked && type != SSH_AGENTC_UNLOCK) { 8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&e->request); 8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (type) { 8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_REQUEST_RSA_IDENTITIES: 8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH2_AGENTC_REQUEST_IDENTITIES: 8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* send empty lists */ 8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood no_identities(e, type); 8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* send a fail message for all other request types */ 8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, 1); 8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&e->output, SSH_AGENT_FAILURE); 8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("type %d", type); 8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (type) { 8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_LOCK: 8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_UNLOCK: 8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_lock_agent(e, type == SSH_AGENTC_LOCK); 8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* ssh1 */ 8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_RSA_CHALLENGE: 8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_authentication_challenge1(e); 8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_REQUEST_RSA_IDENTITIES: 8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_request_identities(e, 1); 8511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_ADD_RSA_IDENTITY: 8531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_ADD_RSA_ID_CONSTRAINED: 8541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_add_identity(e, 1); 8551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_REMOVE_RSA_IDENTITY: 8571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_remove_identity(e, 1); 8581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: 8601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_remove_all_identities(e, 1); 8611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* ssh2 */ 8631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH2_AGENTC_SIGN_REQUEST: 8641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_sign_request2(e); 8651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH2_AGENTC_REQUEST_IDENTITIES: 8671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_request_identities(e, 2); 8681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH2_AGENTC_ADD_IDENTITY: 8701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH2_AGENTC_ADD_ID_CONSTRAINED: 8711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_add_identity(e, 2); 8721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH2_AGENTC_REMOVE_IDENTITY: 8741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_remove_identity(e, 2); 8751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: 8771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_remove_all_identities(e, 2); 8781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef ENABLE_PKCS11 8801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_ADD_SMARTCARD_KEY: 8811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: 8821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_add_smartcard_key(e); 8831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_AGENTC_REMOVE_SMARTCARD_KEY: 8851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_remove_smartcard_key(e); 8861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* ENABLE_PKCS11 */ 8881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 8891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Unknown message. Respond with failure. */ 8901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Unknown message %d", type); 8911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&e->request); 8921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&e->output, 1); 8931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&e->output, SSH_AGENT_FAILURE); 8941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 8991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodnew_socket(sock_type type, int fd) 9001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, old_alloc, new_alloc; 9021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood set_nonblock(fd); 9041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd > max_fd) 9061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max_fd = fd; 9071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sockets_alloc; i++) 9091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sockets[i].type == AUTH_UNUSED) { 9101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sockets[i].fd = fd; 9111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&sockets[i].input); 9121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&sockets[i].output); 9131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&sockets[i].request); 9141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sockets[i].type = type; 9151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 9161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood old_alloc = sockets_alloc; 9181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood new_alloc = sockets_alloc + 10; 9191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0])); 9201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = old_alloc; i < new_alloc; i++) 9211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sockets[i].type = AUTH_UNUSED; 9221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sockets_alloc = new_alloc; 9231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sockets[old_alloc].fd = fd; 9241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&sockets[old_alloc].input); 9251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&sockets[old_alloc].output); 9261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&sockets[old_alloc].request); 9271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sockets[old_alloc].type = type; 9281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 9311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, 9321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct timeval **tvpp) 9331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, sz, deadline; 9351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int n = 0; 9361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static struct timeval tv; 9371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sockets_alloc; i++) { 9391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (sockets[i].type) { 9401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case AUTH_SOCKET: 9411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case AUTH_CONNECTION: 9421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood n = MAX(n, sockets[i].fd); 9431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case AUTH_UNUSED: 9451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 9471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Unknown socket type %d", sockets[i].type); 9481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); 9531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*fdrp == NULL || sz > *nallocp) { 9541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*fdrp) 9551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(*fdrp); 9561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*fdwp) 9571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(*fdwp); 9581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *fdrp = xmalloc(sz); 9591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *fdwp = xmalloc(sz); 9601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *nallocp = sz; 9611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (n < *fdl) 9631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("XXX shrink: %d < %d", n, *fdl); 9641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *fdl = n; 9651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(*fdrp, 0, sz); 9661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(*fdwp, 0, sz); 9671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sockets_alloc; i++) { 9691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (sockets[i].type) { 9701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case AUTH_SOCKET: 9711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case AUTH_CONNECTION: 9721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(sockets[i].fd, *fdrp); 9731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&sockets[i].output) > 0) 9741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(sockets[i].fd, *fdwp); 9751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 9771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood deadline = reaper(); 9811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (parent_alive_interval != 0) 9821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood deadline = (deadline == 0) ? parent_alive_interval : 9831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MIN(deadline, parent_alive_interval); 9841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (deadline == 0) { 9851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *tvpp = NULL; 9861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 9871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tv.tv_sec = deadline; 9881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tv.tv_usec = 0; 9891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *tvpp = &tv; 9901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (1); 9921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 9951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodafter_select(fd_set *readset, fd_set *writeset) 9961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct sockaddr_un sunaddr; 9981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood socklen_t slen; 9991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[1024]; 10001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int len, sock; 10011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, orig_alloc; 10021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood uid_t euid; 10031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gid_t egid; 10041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++) 10061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (sockets[i].type) { 10071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case AUTH_UNUSED: 10081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 10091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case AUTH_SOCKET: 10101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(sockets[i].fd, readset)) { 10111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood slen = sizeof(sunaddr); 10121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sock = accept(sockets[i].fd, 10131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (struct sockaddr *)&sunaddr, &slen); 10141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sock < 0) { 10151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("accept from AUTH_SOCKET: %s", 10161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 10171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 10181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (getpeereid(sock, &euid, &egid) < 0) { 10201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("getpeereid %d failed: %s", 10211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sock, strerror(errno)); 10221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(sock); 10231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 10241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((euid != 0) && (getuid() != euid)) { 10261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("uid mismatch: " 10271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "peer euid %u != uid %u", 10281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (u_int) euid, (u_int) getuid()); 10291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(sock); 10301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 10311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood new_socket(AUTH_CONNECTION, sock); 10331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 10351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case AUTH_CONNECTION: 10361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&sockets[i].output) > 0 && 10371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_ISSET(sockets[i].fd, writeset)) { 10381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = write(sockets[i].fd, 10391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&sockets[i].output), 10401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&sockets[i].output)); 10411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len == -1 && (errno == EAGAIN || 10421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno == EWOULDBLOCK || 10431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno == EINTR)) 10441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 10451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len <= 0) { 10461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close_socket(&sockets[i]); 10471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 10481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_consume(&sockets[i].output, len); 10501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(sockets[i].fd, readset)) { 10521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = read(sockets[i].fd, buf, sizeof(buf)); 10531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len == -1 && (errno == EAGAIN || 10541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno == EWOULDBLOCK || 10551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno == EINTR)) 10561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 10571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len <= 0) { 10581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close_socket(&sockets[i]); 10591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 10601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&sockets[i].input, buf, len); 10621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_message(&sockets[i]); 10631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 10651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 10661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Unknown type %d", sockets[i].type); 10671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 10711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcleanup_socket(void) 10721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (socket_name[0]) 10741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unlink(socket_name); 10751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (socket_dir[0]) 10761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rmdir(socket_dir); 10771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 10801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcleanup_exit(int i) 10811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_socket(); 10831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood _exit(i); 10841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*ARGSUSED*/ 10871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 10881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcleanup_handler(int sig) 10891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_socket(); 10911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef ENABLE_PKCS11 10921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pkcs11_terminate(); 10931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 10941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood _exit(2); 10951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 10981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcheck_parent_exists(void) 10991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 11011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If our parent has exited then getppid() will return (pid_t)1, 11021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * so testing for that should be safe. 11031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 11041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (parent_pid != -1 && getppid() != parent_pid) { 11051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* printf("Parent has died - Authentication agent exiting.\n"); */ 11061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_socket(); 11071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood _exit(2); 11081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 11121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodusage(void) 11131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "usage: %s [options] [command [arg ...]]\n", 11151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __progname); 11161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Options:\n"); 11171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, " -c Generate C-shell commands on stdout.\n"); 11181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, " -s Generate Bourne shell commands on stdout.\n"); 11191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, " -k Kill the current agent.\n"); 11201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, " -d Debug mode.\n"); 11211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, " -a socket Bind agent socket to given name.\n"); 11221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, " -t life Default identity lifetime (seconds).\n"); 11231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 11241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 11271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmain(int ac, char **av) 11281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; 11301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int sock, fd, ch, result, saved_errno; 11311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int nalloc; 11321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *shell, *format, *pidstr, *agentsocket = NULL; 11331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd_set *readsetp = NULL, *writesetp = NULL; 11341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct sockaddr_un sunaddr; 11351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SETRLIMIT 11361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct rlimit rlim; 11371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 11381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int prev_mask; 11391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood extern int optind; 11401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood extern char *optarg; 11411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid_t pid; 11421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char pidstrbuf[1 + 3 * sizeof pid]; 11431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct timeval *tvp = NULL; 11441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood size_t len; 11451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 11471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sanitise_stdfd(); 11481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* drop */ 11501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setegid(getgid()); 11511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setgid(getgid()); 11521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) 11541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Disable ptrace on Linux without sgid bit */ 11551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood prctl(PR_SET_DUMPABLE, 0); 11561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 11571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood OpenSSL_add_all_algorithms(); 11591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __progname = ssh_get_progname(av[0]); 11611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood seed_rng(); 11621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while ((ch = getopt(ac, av, "cdksa:t:")) != -1) { 11641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (ch) { 11651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'c': 11661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s_flag) 11671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood usage(); 11681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c_flag++; 11691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'k': 11711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k_flag++; 11721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 's': 11741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c_flag) 11751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood usage(); 11761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s_flag++; 11771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'd': 11791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (d_flag) 11801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood usage(); 11811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood d_flag++; 11821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'a': 11841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood agentsocket = optarg; 11851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 't': 11871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((lifetime = convtime(optarg)) == -1) { 11881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Invalid lifetime\n"); 11891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood usage(); 11901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 11931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood usage(); 11941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ac -= optind; 11971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood av += optind; 11981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ac > 0 && (c_flag || k_flag || s_flag || d_flag)) 12001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood usage(); 12011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ac == 0 && !c_flag && !s_flag) { 12031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shell = getenv("SHELL"); 12041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (shell != NULL && (len = strlen(shell)) > 2 && 12051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strncmp(shell + len - 3, "csh", 3) == 0) 12061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c_flag = 1; 12071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k_flag) { 12091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *errstr = NULL; 12101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pidstr = getenv(SSH_AGENTPID_ENV_NAME); 12121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pidstr == NULL) { 12131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "%s not set, cannot kill agent\n", 12141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_AGENTPID_ENV_NAME); 12151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 12161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr); 12181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errstr) { 12191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, 12201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%s=\"%s\", which is not a good PID: %s\n", 12211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_AGENTPID_ENV_NAME, pidstr, errstr); 12221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 12231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kill(pid, SIGTERM) == -1) { 12251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("kill"); 12261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 12271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood format = c_flag ? "unsetenv %s;\n" : "unset %s;\n"; 12291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf(format, SSH_AUTHSOCKET_ENV_NAME); 12301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf(format, SSH_AGENTPID_ENV_NAME); 12311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf("echo Agent pid %ld killed;\n", (long)pid); 12321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(0); 12331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood parent_pid = getpid(); 12351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (agentsocket == NULL) { 12371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Create private directory for agent socket */ 12381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mktemp_proto(socket_dir, sizeof(socket_dir)); 12391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (mkdtemp(socket_dir) == NULL) { 12401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("mkdtemp: private socket dir"); 12411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 12421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, 12441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (long)parent_pid); 12451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 12461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Try to use specified agent socket */ 12471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood socket_dir[0] = '\0'; 12481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcpy(socket_name, agentsocket, sizeof socket_name); 12491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 12521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Create socket early so it will exist before command gets run from 12531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the parent. 12541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 12551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sock = socket(AF_UNIX, SOCK_STREAM, 0); 12561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sock < 0) { 12571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("socket"); 12581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *socket_name = '\0'; /* Don't unlink any existing file */ 12591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_exit(1); 12601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&sunaddr, 0, sizeof(sunaddr)); 12621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sunaddr.sun_family = AF_UNIX; 12631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); 12641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood prev_mask = umask(0177); 12651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) { 12661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("bind"); 12671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *socket_name = '\0'; /* Don't unlink any existing file */ 12681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood umask(prev_mask); 12691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_exit(1); 12701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood umask(prev_mask); 12721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { 12731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("listen"); 12741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_exit(1); 12751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 12781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Fork, and have the parent execute the command, if any, or present 12791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the socket data. The child continues as the authentication agent. 12801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 12811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (d_flag) { 12821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1); 12831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; 12841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, 12851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_AUTHSOCKET_ENV_NAME); 12861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf("echo Agent pid %ld;\n", (long)parent_pid); 12871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto skip; 12881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid = fork(); 12901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pid == -1) { 12911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("fork"); 12921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_exit(1); 12931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pid != 0) { /* Parent - execute the given command. */ 12951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(sock); 12961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid); 12971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ac == 0) { 12981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; 12991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, 13001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_AUTHSOCKET_ENV_NAME); 13011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, 13021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_AGENTPID_ENV_NAME); 13031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf("echo Agent pid %ld;\n", (long)pid); 13041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(0); 13051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 || 13071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) { 13081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("setenv"); 13091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 13101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood execvp(av[0], av); 13121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror(av[0]); 13131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 13141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* child */ 13161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0); 13171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setsid() == -1) { 13191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("setsid: %s", strerror(errno)); 13201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_exit(1); 13211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)chdir("/"); 13241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 13251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* XXX might close listen socket */ 13261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)dup2(fd, STDIN_FILENO); 13271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)dup2(fd, STDOUT_FILENO); 13281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)dup2(fd, STDERR_FILENO); 13291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd > 2) 13301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fd); 13311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SETRLIMIT 13341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* deny core dumps, since memory contains unencrypted private keys */ 13351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rlim.rlim_cur = rlim.rlim_max = 0; 13361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setrlimit(RLIMIT_CORE, &rlim) < 0) { 13371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("setrlimit RLIMIT_CORE: %s", strerror(errno)); 13381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_exit(1); 13391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 13411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodskip: 13431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef ENABLE_PKCS11 13451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pkcs11_init(0); 13461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 13471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood new_socket(AUTH_SOCKET, sock); 13481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ac > 0) 13491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood parent_alive_interval = 10; 13501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idtab_init(); 13511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!d_flag) 13521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGINT, SIG_IGN); 13531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGPIPE, SIG_IGN); 13541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGHUP, cleanup_handler); 13551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGTERM, cleanup_handler); 13561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nalloc = 0; 13571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (1) { 13591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp); 13601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood result = select(max_fd + 1, readsetp, writesetp, NULL, tvp); 13611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood saved_errno = errno; 13621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (parent_alive_interval != 0) 13631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood check_parent_exists(); 13641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void) reaper(); /* remove expired keys */ 13651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (result < 0) { 13661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (saved_errno == EINTR) 13671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 13681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("select: %s", strerror(saved_errno)); 13691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (result > 0) 13701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood after_select(readsetp, writesetp); 13711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* NOTREACHED */ 13731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1374