]> andersk Git - openssh.git/blobdiff - ssh-agent.c
- deraadt@cvs.openbsd.org 2006/08/03 03:34:42
[openssh.git] / ssh-agent.c
index f5fce6b2aa016d7f2dd4d9621d2efce583ee73c8..e43faae42b244d4ee242c69ab5322882b57a19b5 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: ssh-agent.c,v 1.151 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
 #include "openbsd-compat/sys-queue.h"
-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 <errno.h>
+#include <fcntl.h>
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
 #include "rsa.h"
 #include "buffer.h"
-#include "bufaux.h"
-#include "xmalloc.h"
-#include "getput.h"
 #include "key.h"
 #include "authfd.h"
 #include "compat.h"
 #include "log.h"
-#include "readpass.h"
 #include "misc.h"
 
 #ifdef SMARTCARD
@@ -100,18 +121,14 @@ int max_fd = 0;
 pid_t parent_pid = -1;
 
 /* pathname and directory for AUTH_SOCKET */
-char socket_name[1024];
-char socket_dir[1024];
+char socket_name[MAXPATHLEN];
+char socket_dir[MAXPATHLEN];
 
 /* locking */
 int locked = 0;
 char *lock_passwd = NULL;
 
-#ifdef HAVE___PROGNAME
 extern char *__progname;
-#else
-char *__progname;
-#endif
 
 /* Default lifetime (0 == forever) */
 static int lifetime = 0;
@@ -173,23 +190,15 @@ lookup_identity(Key *key, int version)
 static int
 confirm_key(Identity *id)
 {
-       char *p, prompt[1024];
+       char *p;
        int ret = -1;
 
        p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
-       snprintf(prompt, sizeof(prompt), "Allow use of key %s?\n"
-           "Key fingerprint %s.", id->comment, p);
+       if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
+           id->comment, p))
+               ret = 0;
        xfree(p);
-       p = read_passphrase(prompt, RP_ALLOW_EOF);
-       if (p != NULL) {
-               /*
-                * Accept empty responses and responses consisting
-                * of the word "yes" as affirmative.
-                */
-               if (*p == '\0' || *p == '\n' || strcasecmp(p, "yes") == 0)
-                       ret = 0;
-               xfree(p);
-       }
+
        return (ret);
 }
 
@@ -318,8 +327,8 @@ process_sign_request2(SocketEntry *e)
                Identity *id = lookup_identity(key, 2);
                if (id != NULL && (!id->confirm || confirm_key(id) == 0))
                        ok = key_sign(id->key, &signature, &slen, data, dlen);
+               key_free(key);
        }
-       key_free(key);
        buffer_init(&msg);
        if (ok == 0) {
                buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE);
@@ -368,7 +377,7 @@ process_remove_identity(SocketEntry *e, int version)
                if (id != NULL) {
                        /*
                         * We have this key.  Free the old key.  Since we
-                        * don\'t want to leave empty slots in the middle of
+                        * don't want to leave empty slots in the middle of
                         * the array, we actually free the key there and move
                         * all the entries between the empty slot and the end
                         * of the array.
@@ -694,7 +703,7 @@ process_message(SocketEntry *e)
        if (buffer_len(&e->input) < 5)
                return;         /* Incomplete message. */
        cp = buffer_ptr(&e->input);
-       msg_len = GET_32BIT(cp);
+       msg_len = get_u32(cp);
        if (msg_len > 256 * 1024) {
                close_socket(e);
                return;
@@ -790,8 +799,7 @@ new_socket(sock_type type, int fd)
 {
        u_int i, old_alloc, new_alloc;
 
-       if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
-               error("fcntl O_NONBLOCK: %s", strerror(errno));
+       set_nonblock(fd);
 
        if (fd > max_fd)
                max_fd = fd;
@@ -807,10 +815,7 @@ new_socket(sock_type type, int fd)
                }
        old_alloc = sockets_alloc;
        new_alloc = sockets_alloc + 10;
-       if (sockets)
-               sockets = xrealloc(sockets, new_alloc * sizeof(sockets[0]));
-       else
-               sockets = xmalloc(new_alloc * sizeof(sockets[0]));
+       sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0]));
        for (i = old_alloc; i < new_alloc; i++)
                sockets[i].type = AUTH_UNUSED;
        sockets_alloc = new_alloc;
@@ -822,7 +827,7 @@ new_socket(sock_type type, int fd)
 }
 
 static int
-prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, int *nallocp)
+prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp)
 {
        u_int i, sz;
        int n = 0;
@@ -891,7 +896,7 @@ after_select(fd_set *readset, fd_set *writeset)
                        if (FD_ISSET(sockets[i].fd, readset)) {
                                slen = sizeof(sunaddr);
                                sock = accept(sockets[i].fd,
-                                   (struct sockaddr *) &sunaddr, &slen);
+                                   (struct sockaddr *)&sunaddr, &slen);
                                if (sock < 0) {
                                        error("accept from AUTH_SOCKET: %s",
                                            strerror(errno));
@@ -968,6 +973,7 @@ cleanup_exit(int i)
        _exit(i);
 }
 
+/*ARGSUSED*/
 static void
 cleanup_handler(int sig)
 {
@@ -975,6 +981,7 @@ cleanup_handler(int sig)
        _exit(2);
 }
 
+/*ARGSUSED*/
 static void
 check_parent_exists(int sig)
 {
@@ -1008,21 +1015,23 @@ int
 main(int ac, char **av)
 {
        int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
-       int sock, fd,  ch, nalloc;
+       int sock, fd,  ch;
+       u_int nalloc;
        char *shell, *format, *pidstr, *agentsocket = NULL;
        fd_set *readsetp = NULL, *writesetp = NULL;
        struct sockaddr_un sunaddr;
 #ifdef HAVE_SETRLIMIT
        struct rlimit rlim;
 #endif
-#ifdef HAVE_CYGWIN
        int prev_mask;
-#endif
        extern int optind;
        extern char *optarg;
        pid_t pid;
        char pidstrbuf[1 + 3 * sizeof pid];
 
+       /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
+       sanitise_stdfd();
+
        /* drop */
        setegid(getgid());
        setgid(getgid());
@@ -1079,20 +1088,24 @@ main(int ac, char **av)
 
        if (ac == 0 && !c_flag && !s_flag) {
                shell = getenv("SHELL");
-               if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
+               if (shell != NULL &&
+                   strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
                        c_flag = 1;
        }
        if (k_flag) {
+               const char *errstr = NULL;
+
                pidstr = getenv(SSH_AGENTPID_ENV_NAME);
                if (pidstr == NULL) {
                        fprintf(stderr, "%s not set, cannot kill agent\n",
                            SSH_AGENTPID_ENV_NAME);
                        exit(1);
                }
-               pid = atoi(pidstr);
-               if (pid < 1) {
-                       fprintf(stderr, "%s=\"%s\", which is not a good PID\n",
-                           SSH_AGENTPID_ENV_NAME, pidstr);
+               pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr);
+               if (errstr) {
+                       fprintf(stderr,
+                           "%s=\"%s\", which is not a good PID: %s\n",
+                           SSH_AGENTPID_ENV_NAME, pidstr, errstr);
                        exit(1);
                }
                if (kill(pid, SIGTERM) == -1) {
@@ -1129,24 +1142,20 @@ main(int ac, char **av)
        sock = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sock < 0) {
                perror("socket");
+               *socket_name = '\0'; /* Don't unlink any existing file */
                cleanup_exit(1);
        }
        memset(&sunaddr, 0, sizeof(sunaddr));
        sunaddr.sun_family = AF_UNIX;
        strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
-#ifdef HAVE_CYGWIN
        prev_mask = umask(0177);
-#endif
-       if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) {
+       if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) {
                perror("bind");
-#ifdef HAVE_CYGWIN
+               *socket_name = '\0'; /* Don't unlink any existing file */
                umask(prev_mask);
-#endif
                cleanup_exit(1);
        }
-#ifdef HAVE_CYGWIN
        umask(prev_mask);
-#endif
        if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
                perror("listen");
                cleanup_exit(1);
This page took 0.04531 seconds and 4 git commands to generate.