#include "includes.h"
#include "openbsd-compat/sys-queue.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.108 2003/03/13 11:44:50 markus Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.117 2003/12/02 17:01:15 markus Exp $");
#include <openssl/evp.h>
#include <openssl/md5.h>
#include "scard.h"
#endif
+#if defined(HAVE_SYS_PRCTL_H)
+#include <sys/prctl.h> /* For prctl() and PR_SET_DUMPABLE */
+#endif
+
typedef enum {
AUTH_UNUSED,
AUTH_SOCKET,
p = read_passphrase(prompt, RP_ALLOW_EOF);
if (p != NULL) {
/*
- * Accept empty responses and responses consisting
+ * Accept empty responses and responses consisting
* of the word "yes" as affirmative.
*/
if (*p == '\0' || *p == '\n' || strcasecmp(p, "yes") == 0)
/* The response is MD5 of decrypted challenge plus session id. */
len = BN_num_bytes(challenge);
if (len <= 0 || len > 32) {
- log("process_authentication_challenge: bad challenge length %d", len);
+ logit("process_authentication_challenge: bad challenge length %d", len);
goto failure;
}
memset(buf, 0, 32);
buffer_get_bignum(&e->request, key->rsa->n);
if (bits != key_size(key))
- log("Warning: identity keysize mismatch: actual %u, announced %u",
+ logit("Warning: identity keysize mismatch: actual %u, announced %u",
key_size(key), bits);
break;
case 2:
process_add_smartcard_key (SocketEntry *e)
{
char *sc_reader_id = NULL, *pin;
- int i, version, success = 0;
+ int i, version, success = 0, death = 0, confirm = 0;
Key **keys, *k;
Identity *id;
Idtab *tab;
sc_reader_id = buffer_get_string(&e->request, NULL);
pin = buffer_get_string(&e->request, NULL);
+
+ while (buffer_len(&e->request)) {
+ switch (buffer_get_char(&e->request)) {
+ case SSH_AGENT_CONSTRAIN_LIFETIME:
+ death = time(NULL) + buffer_get_int(&e->request);
+ break;
+ case SSH_AGENT_CONSTRAIN_CONFIRM:
+ confirm = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ if (lifetime && !death)
+ death = time(NULL) + lifetime;
+
keys = sc_get_keys(sc_reader_id, pin);
xfree(sc_reader_id);
xfree(pin);
if (lookup_identity(k, version) == NULL) {
id = xmalloc(sizeof(Identity));
id->key = k;
- id->comment = xstrdup("smartcard key");
- id->death = 0;
- id->confirm = 0;
+ id->comment = sc_get_key_label(k);
+ id->death = death;
+ id->confirm = confirm;
TAILQ_INSERT_TAIL(&tab->idlist, id, next);
tab->nentries++;
success = 1;
break;
#ifdef SMARTCARD
case SSH_AGENTC_ADD_SMARTCARD_KEY:
+ case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
process_add_smartcard_key(e);
break;
case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
static void
new_socket(sock_type type, int fd)
{
- u_int i, old_alloc;
+ u_int i, old_alloc, new_alloc;
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
error("fcntl O_NONBLOCK: %s", strerror(errno));
for (i = 0; i < sockets_alloc; i++)
if (sockets[i].type == AUTH_UNUSED) {
sockets[i].fd = fd;
- sockets[i].type = type;
buffer_init(&sockets[i].input);
buffer_init(&sockets[i].output);
buffer_init(&sockets[i].request);
+ sockets[i].type = type;
return;
}
old_alloc = sockets_alloc;
- sockets_alloc += 10;
+ new_alloc = sockets_alloc + 10;
if (sockets)
- sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0]));
+ sockets = xrealloc(sockets, new_alloc * sizeof(sockets[0]));
else
- sockets = xmalloc(sockets_alloc * sizeof(sockets[0]));
- for (i = old_alloc; i < sockets_alloc; i++)
+ sockets = xmalloc(new_alloc * sizeof(sockets[0]));
+ for (i = old_alloc; i < new_alloc; i++)
sockets[i].type = AUTH_UNUSED;
- sockets[old_alloc].type = type;
+ sockets_alloc = new_alloc;
sockets[old_alloc].fd = fd;
buffer_init(&sockets[old_alloc].input);
buffer_init(&sockets[old_alloc].output);
buffer_init(&sockets[old_alloc].request);
+ sockets[old_alloc].type = type;
}
static int
}
static void
-cleanup_socket(void *p)
+cleanup_socket(void)
{
if (socket_name[0])
unlink(socket_name);
rmdir(socket_dir);
}
-static void
+void
cleanup_exit(int i)
{
- cleanup_socket(NULL);
- exit(i);
+ cleanup_socket();
+ _exit(i);
}
static void
cleanup_handler(int sig)
{
- cleanup_socket(NULL);
+ cleanup_socket();
_exit(2);
}
/* printf("Parent has died - Authentication agent exiting.\n"); */
cleanup_handler(sig); /* safe */
}
- signal(SIGALRM, check_parent_exists);
+ mysignal(SIGALRM, check_parent_exists);
alarm(10);
errno = save_errno;
}
setegid(getgid());
setgid(getgid());
+#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
+ /* Disable ptrace on Linux without sgid bit */
+ prctl(PR_SET_DUMPABLE, 0);
+#endif
+
SSLeay_add_all_algorithms();
- __progname = get_progname(av[0]);
+ __progname = ssh_get_progname(av[0]);
init_rng();
seed_rng();
if (agentsocket == NULL) {
/* Create private directory for agent socket */
- strlcpy(socket_dir, "/tmp/ssh-XXXXXXXX", sizeof socket_dir);
+ strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir);
if (mkdtemp(socket_dir) == NULL) {
perror("mkdtemp: private socket dir");
exit(1);
#ifdef HAVE_CYGWIN
umask(prev_mask);
#endif
- if (listen(sock, 128) < 0) {
+ if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
perror("listen");
cleanup_exit(1);
}
#endif
skip:
- fatal_add_cleanup(cleanup_socket, NULL);
new_socket(AUTH_SOCKET, sock);
if (ac > 0) {
- signal(SIGALRM, check_parent_exists);
+ mysignal(SIGALRM, check_parent_exists);
alarm(10);
}
idtab_init();