]> andersk Git - openssh.git/commitdiff
- Merged more OpenBSD changes:
authordamien <damien>
Tue, 7 Dec 1999 04:38:31 +0000 (04:38 +0000)
committerdamien <damien>
Tue, 7 Dec 1999 04:38:31 +0000 (04:38 +0000)
   - [atomicio.c authfd.c scp.c serverloop.c ssh.h sshconnect.c sshd.c]
     move atomicio into it's own file.  wrap all socket write()s which
     were doing write(sock, buf, len) != len, with atomicio() calls.
   - [auth-skey.c]
     fd leak
   - [authfile.c]
     properly name fd variable
   - [channels.c]
     display great hatred towards strcpy
   - [pty.c pty.h sshd.c]
     use openpty() if it exists (it does on BSD4_4)
   - [tildexpand.c]
     check for ~ expansion past MAXPATHLEN
 - Modified helper.c to use new atomicio function.
 - Reformat Makefile a little
 - Moved RC4 routines from rc4.[ch] into helper.c
 - Added autoconf code to detect /dev/ptmx (Solaris) and /dev/ptc (AIX)

21 files changed:
ChangeLog
Makefile.in
acconfig.h
atomicio.c [new file with mode: 0644]
auth-skey.c
authfd.c
authfile.c
channels.c
clientloop.c
configure.in
helper.c
pty.c
pty.h
rc4.c [deleted file]
rc4.h [deleted file]
scp.c
serverloop.c
ssh.h
sshconnect.c
sshd.c
tildexpand.c

index f475f188d60d5810389389329e11141f132ebdf7..fc6b3f37b7810ac4b79547db94ccdf1c278cbb9e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,24 @@
  - Fixed default SSH_ASKPASS
  - Fix PAM account and session being called multiple times. Problem 
    reported by Adrian Baugh <adrian@merlin.keble.ox.ac.uk>
+ - Merged more OpenBSD changes:
+   - [atomicio.c authfd.c scp.c serverloop.c ssh.h sshconnect.c sshd.c]
+     move atomicio into it's own file.  wrap all socket write()s which 
+     were doing write(sock, buf, len) != len, with atomicio() calls.
+   - [auth-skey.c]
+     fd leak
+   - [authfile.c]
+     properly name fd variable
+   - [channels.c]
+     display great hatred towards strcpy
+   - [pty.c pty.h sshd.c]
+     use openpty() if it exists (it does on BSD4_4)
+   - [tildexpand.c]
+     check for ~ expansion past MAXPATHLEN
+ - Modified helper.c to use new atomicio function.
+ - Reformat Makefile a little
+ - Moved RC4 routines from rc4.[ch] into helper.c
+ - Added autoconf code to detect /dev/ptmx (Solaris) and /dev/ptc (AIX)
 
 19991204
  - Small cleanup of PAM code in sshd.c
index c2c3261b515911e2c56f6708ef6e885500d27f5d..80b0a6d4290a64c6a30a2d659efce3c3b6c36b93 100644 (file)
@@ -23,25 +23,31 @@ LFLAGS=@LDFLAGS@
 GNOME_CFLAGS=`gnome-config --cflags gnome gnomeui`
 GNOME_LIBS=`gnome-config --libs gnome gnomeui`
 
-OBJS=  authfd.o authfile.o auth-passwd.o auth-rhosts.o auth-rh-rsa.o \
-               auth-rsa.o auth-skey.o bufaux.o buffer.o canohost.o channels.o \
-               cipher.o clientloop.o compress.o crc32.o deattack.o helper.o \
-               hostfile.o log-client.o login.o log-server.o match.o mpaux.o \
-               packet.o pty.o readconf.o readpass.o rsa.o servconf.o serverloop.o \
-               sshconnect.o tildexpand.o ttymodes.o uidswap.o xmalloc.o \
-               helper.o bsd-mktemp.o bsd-strlcpy.o bsd-strlcat.o bsd-daemon.o \
-               bsd-login.o bsd-snprintf.o rc4.o md5crypt.o
-
+OBJS= atomicio.o authfd.o authfile.o auth-passwd.o auth-rhosts.o \
+  auth-rh-rsa.o auth-rsa.o auth-skey.o bsd-daemon.o bsd-login.o \
+  bsd-mktemp.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o \
+  buffer.o canohost.o channels.o cipher.o clientloop.o compress.o \
+  crc32.o deattack.o helper.o helper.o hostfile.o log-client.o \
+  login.o log-server.o match.o md5crypt.o mpaux.o packet.o pty.o \
+  readconf.o readpass.o rsa.o servconf.o serverloop.o \
+  sshconnect.o tildexpand.o ttymodes.o uidswap.o xmalloc.o 
 all: $(OBJS) $(TARGETS)
 
-libssh.a: authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o hostfile.o match.o mpaux.o nchan.o packet.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o helper.o rc4.o bsd-mktemp.o bsd-strlcpy.o bsd-strlcat.o bsd-snprintf.o bsd-daemon.o log.o fingerprint.o
+libssh.a: atomicio.o authfd.o authfile.o bsd-daemon.o bsd-mktemp.o \
+  bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o \
+  buffer.o canohost.o channels.o cipher.o compat.o \
+  compress.o crc32.o deattack.o fingerprint.o helper.o \
+  hostfile.o log.o match.o mpaux.o nchan.o packet.o \
+  readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o 
        $(AR) rv $@ $^
        $(RANLIB) $@
 
 ssh: ssh.o sshconnect.o log-client.o readconf.o clientloop.o libssh.a
        $(CC) -o $@ $^ $(LFLAGS) $(LIBS) 
 
-sshd:  sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o servconf.o serverloop.o bsd-login.o md5crypt.o libssh.a
+sshd:  sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
+  pty.o log-server.o login.o servconf.o serverloop.o bsd-login.o \
+  md5crypt.o libssh.a
        $(CC) -o $@ $^ $(LFLAGS) $(LIBS) 
 
 scp:   scp.o libssh.a
index 25f49141409cb9a34d9ce95487027f6fbc3cc119..29ec07821c66ba125f6ca477e66afb5d69d24ade 100644 (file)
 #undef HAVE_U_INTXX_T
 #undef HAVE_UINTXX_T
 
+/* Define if you have /dev/ptmx */
+#undef HAVE_DEV_PTMX
+
+/* Define if you have /dev/ptc */
+#undef HAVE_DEV_PTS_AND_PTC
+
 @BOTTOM@
 
 /* ******************* Shouldn't need to edit below this line ************** */
diff --git a/atomicio.c b/atomicio.c
new file mode 100644 (file)
index 0000000..1b960e5
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1999 Theo de Raadt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$Id$");
+
+#include "xmalloc.h"
+#include "ssh.h"
+
+/*
+ * ensure all of data on socket comes through. f==read || f==write
+ */
+int
+atomicio(f, fd, s, n)
+       int (*f) ();
+       int fd;
+       void *s;
+       size_t n;
+{
+       int res, pos = 0;
+
+       while (n > pos) {
+               res = (f) (fd, s + pos, n - pos);
+               switch (res) {
+               case -1:
+                       if (errno == EINTR || errno == EAGAIN)
+                               continue;
+               case 0:
+                       return (res);
+               default:
+                       pos += res;
+               }
+       }
+       return (pos);
+}
index ebe0483d60958621ed1f5f50a8643d8c9e007f5b..55f0780d8217a060d1a9ff6f07ed15e95e70416c 100644 (file)
@@ -114,6 +114,7 @@ skey_fake_keyinfo(char *username)
                    SEEK_SET) != -1 && read(fd, hseed,
                    SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) {
                        close(fd);
+                       fd = -1;
                        secret = hseed;
                        secretlen = SKEY_MAX_SEED_LEN;
                        flg = 0;
@@ -123,6 +124,8 @@ skey_fake_keyinfo(char *username)
                        secretlen = strlen(secret);
                        flg = 0;
                }
+               if (fd != -1)
+                       close(fd);
        }
 
        /* Put that in your pipe and smoke it */
index df5b16f67ae0ae3f2577ab96b6789cfea756065c..e30eab8b9ccef1cb3bdc65e7c2d82746240bc357 100644 (file)
--- a/authfd.c
+++ b/authfd.c
@@ -145,7 +145,7 @@ ssh_get_first_identity(AuthenticationConnection *auth,
        msg[2] = 0;
        msg[3] = 1;
        msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
-       if (write(auth->fd, msg, 5) != 5) {
+       if (atomicio(write, auth->fd, msg, 5) != 5) {
                error("write auth->fd: %.100s", strerror(errno));
                return 0;
        }
@@ -270,9 +270,9 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
        PUT_32BIT(buf, len);
 
        /* Send the length and then the packet to the agent. */
-       if (write(auth->fd, buf, 4) != 4 ||
-           write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
-           buffer_len(&buffer)) {
+       if (atomicio(write, auth->fd, buf, 4) != 4 ||
+           atomicio(write, auth->fd, buffer_ptr(&buffer),
+           buffer_len(&buffer)) != buffer_len(&buffer)) {
                error("Error writing to authentication socket.");
 error_cleanup:
                buffer_free(&buffer);
@@ -369,9 +369,9 @@ ssh_add_identity(AuthenticationConnection *auth,
        PUT_32BIT(buf, len);
 
        /* Send the length and then the packet to the agent. */
-       if (write(auth->fd, buf, 4) != 4 ||
-           write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
-           buffer_len(&buffer)) {
+       if (atomicio(write, auth->fd, buf, 4) != 4 ||
+           atomicio(write, auth->fd, buffer_ptr(&buffer),
+           buffer_len(&buffer)) != buffer_len(&buffer)) {
                error("Error writing to authentication socket.");
 error_cleanup:
                buffer_free(&buffer);
@@ -450,9 +450,9 @@ ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
        PUT_32BIT(buf, len);
 
        /* Send the length and then the packet to the agent. */
-       if (write(auth->fd, buf, 4) != 4 ||
-           write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
-           buffer_len(&buffer)) {
+       if (atomicio(write, auth->fd, buf, 4) != 4 ||
+           atomicio(write, auth->fd, buffer_ptr(&buffer),
+           buffer_len(&buffer)) != buffer_len(&buffer)) {
                error("Error writing to authentication socket.");
 error_cleanup:
                buffer_free(&buffer);
@@ -526,7 +526,7 @@ ssh_remove_all_identities(AuthenticationConnection *auth)
        buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES;
 
        /* Send the length and then the packet to the agent. */
-       if (write(auth->fd, buf, 5) != 5) {
+       if (atomicio(write, auth->fd, buf, 5) != 5) {
                error("Error writing to authentication socket.");
                return 0;
        }
index e26b8440a276e40516e203cbf16c695661de7b19..f2699708f32ea2bddddf8d0be067b4d3af64b2b2 100644 (file)
@@ -46,7 +46,7 @@ save_private_key(const char *filename, const char *passphrase,
 {
        Buffer buffer, encrypted;
        char buf[100], *cp;
-       int f, i;
+       int fd, i;
        CipherContext cipher;
        int cipher_type;
        u_int32_t rand;
@@ -117,19 +117,19 @@ save_private_key(const char *filename, const char *passphrase,
        memset(buf, 0, sizeof(buf));
        buffer_free(&buffer);
 
-       f = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-       if (f < 0)
+       fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+       if (fd < 0)
                return 0;
-       if (write(f, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
+       if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
            buffer_len(&encrypted)) {
                debug("Write to key file %.200s failed: %.100s", filename,
                      strerror(errno));
                buffer_free(&encrypted);
-               close(f);
+               close(fd);
                remove(filename);
                return 0;
        }
-       close(f);
+       close(fd);
        buffer_free(&encrypted);
        return 1;
 }
@@ -144,28 +144,28 @@ int
 load_public_key(const char *filename, RSA * pub,
                char **comment_return)
 {
-       int f, i;
+       int fd, i;
        off_t len;
        Buffer buffer;
        char *cp;
 
-       f = open(filename, O_RDONLY);
-       if (f < 0)
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
                return 0;
-       len = lseek(f, (off_t) 0, SEEK_END);
-       lseek(f, (off_t) 0, SEEK_SET);
+       len = lseek(fd, (off_t) 0, SEEK_END);
+       lseek(fd, (off_t) 0, SEEK_SET);
 
        buffer_init(&buffer);
        buffer_append_space(&buffer, &cp, len);
 
-       if (read(f, cp, (size_t) len) != (size_t) len) {
+       if (read(fd, cp, (size_t) len) != (size_t) len) {
                debug("Read from key file %.200s failed: %.100s", filename,
                      strerror(errno));
                buffer_free(&buffer);
-               close(f);
+               close(fd);
                return 0;
        }
-       close(f);
+       close(fd);
 
        /* Check that it is at least big enought to contain the ID string. */
        if (len < strlen(AUTHFILE_ID_STRING) + 1) {
@@ -178,7 +178,7 @@ load_public_key(const char *filename, RSA * pub,
         * from the buffer.
         */
        for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
-               if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) {
+               if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
                        debug("Bad key file %.200s.", filename);
                        buffer_free(&buffer);
                        return 0;
@@ -213,7 +213,7 @@ int
 load_private_key(const char *filename, const char *passphrase,
                 RSA * prv, char **comment_return)
 {
-       int f, i, check1, check2, cipher_type;
+       int fd, i, check1, check2, cipher_type;
        off_t len;
        Buffer buffer, decrypted;
        char *cp;
@@ -222,14 +222,15 @@ load_private_key(const char *filename, const char *passphrase,
        BIGNUM *aux;
        struct stat st;
 
-       f = open(filename, O_RDONLY);
-       if (f < 0)
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
                return 0;
 
        /* check owner and modes */
-       if (fstat(f, &st) < 0 ||
+       if (fstat(fd, &st) < 0 ||
            (st.st_uid != 0 && st.st_uid != getuid()) ||
            (st.st_mode & 077) != 0) {
+               close(fd);
                error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");
                error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
@@ -238,20 +239,20 @@ load_private_key(const char *filename, const char *passphrase,
                error("It is recommended that your private key files are NOT accessible by others.");
                return 0;
        }
-       len = lseek(f, (off_t) 0, SEEK_END);
-       lseek(f, (off_t) 0, SEEK_SET);
+       len = lseek(fd, (off_t) 0, SEEK_END);
+       lseek(fd, (off_t) 0, SEEK_SET);
 
        buffer_init(&buffer);
        buffer_append_space(&buffer, &cp, len);
 
-       if (read(f, cp, (size_t) len) != (size_t) len) {
+       if (read(fd, cp, (size_t) len) != (size_t) len) {
                debug("Read from key file %.200s failed: %.100s", filename,
                      strerror(errno));
                buffer_free(&buffer);
-               close(f);
+               close(fd);
                return 0;
        }
-       close(f);
+       close(fd);
 
        /* Check that it is at least big enought to contain the ID string. */
        if (len < strlen(AUTHFILE_ID_STRING) + 1) {
index 8fe9c716c8ecdfe8be795168525b11e926735184..ad79515274b4b5995118a88fba08611f26c9cb98 100644 (file)
@@ -921,7 +921,7 @@ channel_request_local_forwarding(u_short port, const char *host,
        /* Allocate a channel number for the socket. */
        ch = channel_allocate(SSH_CHANNEL_PORT_LISTENER, sock,
                              xstrdup("port listener"));
-       strcpy(channels[ch].path, host);
+       strlcpy(channels[ch].path, host, sizeof(channels[ch].path));
        channels[ch].host_port = host_port;
        channels[ch].listening_port = port;
 }
@@ -1498,7 +1498,8 @@ auth_input_request_forwarding(struct passwd * pw)
        /* Allocate a channel for the authentication agent socket. */
        newch = channel_allocate(SSH_CHANNEL_AUTH_SOCKET, sock,
                                 xstrdup("auth socket"));
-       strcpy(channels[newch].path, channel_forwarded_auth_socket_name);
+       strlcpy(channels[newch].path, channel_forwarded_auth_socket_name,
+           sizeof(channels[newch].path));
 }
 
 /* This is called to process an SSH_SMSG_AGENT_OPEN message. */
index 3eaad15a4ce3e5ec99ec0c301be47a11cec463a7..6ae3c673624f8d3e627827ac1ac6e2fcbbdac1d0 100644 (file)
@@ -466,13 +466,11 @@ client_suspend_self()
 
        /* Flush stdout and stderr buffers. */
        if (buffer_len(&stdout_buffer) > 0)
-               write(fileno(stdout),
-                     buffer_ptr(&stdout_buffer),
-                     buffer_len(&stdout_buffer));
+               atomicio(write, fileno(stdout), buffer_ptr(&stdout_buffer),
+                   buffer_len(&stdout_buffer));
        if (buffer_len(&stderr_buffer) > 0)
-               write(fileno(stderr),
-                     buffer_ptr(&stderr_buffer),
-                     buffer_len(&stderr_buffer));
+               atomicio(write, fileno(stderr), buffer_ptr(&stderr_buffer),
+                   buffer_len(&stderr_buffer));
 
        leave_raw_mode();
 
@@ -739,7 +737,7 @@ client_process_output(fd_set * writeset)
        if (FD_ISSET(fileno(stdout), writeset)) {
                /* Write as much data as possible. */
                len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
-                           buffer_len(&stdout_buffer));
+                   buffer_len(&stdout_buffer));
                if (len <= 0) {
                        if (errno == EAGAIN)
                                len = 0;
@@ -762,7 +760,7 @@ client_process_output(fd_set * writeset)
        if (FD_ISSET(fileno(stderr), writeset)) {
                /* Write as much data as possible. */
                len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
-                           buffer_len(&stderr_buffer));
+                   buffer_len(&stderr_buffer));
                if (len <= 0) {
                        if (errno == EAGAIN)
                                len = 0;
@@ -911,7 +909,7 @@ client_loop(int have_pty, int escape_char_arg)
        /* Output any buffered data for stdout. */
        while (buffer_len(&stdout_buffer) > 0) {
                len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
-                           buffer_len(&stdout_buffer));
+                   buffer_len(&stdout_buffer));
                if (len <= 0) {
                        error("Write failed flushing stdout buffer.");
                        break;
@@ -922,7 +920,7 @@ client_loop(int have_pty, int escape_char_arg)
        /* Output any buffered data for stderr. */
        while (buffer_len(&stderr_buffer) > 0) {
                len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
-                           buffer_len(&stderr_buffer));
+                   buffer_len(&stderr_buffer));
                if (len <= 0) {
                        error("Write failed flushing stderr buffer.");
                        break;
index 86f2dde7c95206ef9669cef4fc1cacbef995a24d..62e68317e5b3978a76df2b794a90f91e0db55f03 100644 (file)
@@ -59,7 +59,7 @@ dnl Checks for header files.
 AC_CHECK_HEADERS(endian.h lastlog.h login.h maillock.h netgroup.h paths.h pty.h shadow.h util.h utmp.h sys/select.h sys/time.h)
 
 dnl Checks for library functions.
-AC_CHECK_FUNCS(arc4random mkdtemp openpty setenv setlogin setproctitle snprintf strlcat strlcpy vsnprintf)
+AC_CHECK_FUNCS(arc4random mkdtemp openpty _getpty setenv setlogin setproctitle snprintf strlcat strlcpy vsnprintf)
 
 AC_CHECK_FUNC(login, 
        [AC_DEFINE(HAVE_LOGIN)],
@@ -221,6 +221,9 @@ else
        AC_DEFINE_UNQUOTED(LASTLOG_LOCATION, "$lastlog")
 fi     
 
+AC_CHECK_FILE("/dev/ptmx", AC_DEFINE_UNQUOTED(HAVE_DEV_PTMX))
+AC_CHECK_FILE("/dev/ptc", AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC))
+
 AC_MSG_CHECKING([whether libc defines __progname])
 AC_TRY_LINK([], 
        [extern char *__progname; printf("%s", __progname);], 
index 91a78b5776d48f6fcc3b08d721cc7b3994977270..bf4e145b27a0630d475764c72275723800b4015b 100644 (file)
--- a/helper.c
+++ b/helper.c
@@ -45,7 +45,6 @@
 #include <sys/un.h>
 #include <fcntl.h>
 
-#include "rc4.h"
 #include "xmalloc.h"
 #include "ssh.h"
 #include "config.h"
 
 #ifndef HAVE_ARC4RANDOM
 
+typedef struct
+{
+       unsigned int s[256];
+       int i;
+       int j;
+} rc4_t;
+
 void get_random_bytes(unsigned char *buf, int len);
+void rc4_key(rc4_t *r, unsigned char *key, int len);
+void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len);
 
 static rc4_t *rc4 = NULL;
 
+void rc4_key(rc4_t *r, unsigned char *key, int len)
+{
+       int t;
+       
+       for(r->i = 0; r->i < 256; r->i++)
+               r->s[r->i] = r->i;
+
+       r->j = 0;
+       for(r->i = 0; r->i < 256; r->i++)
+       {
+               r->j = (r->j + r->s[r->i] + key[r->i % len]) % 256;
+               t = r->s[r->i];
+               r->s[r->i] = r->s[r->j];
+               r->s[r->j] = t;
+       }
+       r->i = r->j = 0;
+}
+
+void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len)
+{
+       int t;
+       int c;
+
+       c = 0;  
+       while(c < len)
+       {
+               r->i = (r->i + 1) % 256;
+               r->j = (r->j + r->s[r->i]) % 256;
+               t = r->s[r->i];
+               r->s[r->i] = r->s[r->j];
+               r->s[r->j] = t;
+
+               t = (r->s[r->i] + r->s[r->j]) % 256;
+               
+               buffer[c] = r->s[t];
+               c++;
+       }
+}
+
 unsigned int arc4random(void)
 {
        unsigned int r;
@@ -117,7 +164,8 @@ void get_random_bytes(unsigned char *buf, int len)
        
        /* Send blocking read request to EGD */
        egd_message[1] = len;
-       c = write(random_pool, egd_message, sizeof(egd_message));
+
+       c = atomicio(write, random_pool, egd_message, sizeof(egd_message));
        if (c == -1)
                fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno));
 
@@ -129,15 +177,9 @@ void get_random_bytes(unsigned char *buf, int len)
 
 #endif /* HAVE_EGD */
 
-       do {
-               c = read(random_pool, buf, len);
-
-               if ((c == -1) && (errno != EINTR))
-                       fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
-       } while (c == -1);
-
-       if (c != len)
-               fatal("Short read from random pool \"%s\"", RANDOM_POOL);
+       c = atomicio(read, random_pool, buf, len);
+       if (c <= 0)
+               fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
        
        close(random_pool);
 }
diff --git a/pty.c b/pty.c
index 0675583dcf3ab2288c19a7f0180071e92376cb87..455d441614c5fed3d9a556ff950caa1d7af3d696 100644 (file)
--- a/pty.c
+++ b/pty.c
@@ -40,17 +40,19 @@ RCSID("$Id$");
  */
 
 int 
-pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
+pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
 {
-#ifdef HAVE_OPENPTY
+#if defined(HAVE_OPENPTY) || defined(BSD4_4)
        /* openpty(3) exists in OSF/1 and some other os'es */
+       char buf[64];
        int i;
 
-       i = openpty(ptyfd, ttyfd, namebuf, NULL, NULL);
+       i = openpty(ptyfd, ttyfd, buf, NULL, NULL);
        if (i < 0) {
                error("openpty: %.100s", strerror(errno));
                return 0;
        }
+       strlcpy(namebuf, buf, namebuflen);      /* possible truncation */
        return 1;
 #else /* HAVE_OPENPTY */
 #ifdef HAVE__GETPTY
@@ -65,7 +67,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
                error("_getpty: %.100s", strerror(errno));
                return 0;
        }
-       strcpy(namebuf, slave);
+       strlcpy(namebuf, slave, namebuflen);
        /* Open the slave side. */
        *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
        if (*ttyfd < 0) {
@@ -99,7 +101,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
        pts = ptsname(ptm);
        if (pts == NULL)
                error("Slave pty side name could not be obtained.");
-       strcpy(namebuf, pts);
+       strlcpy(namebuf, pts, namebuflen);
        *ptyfd = ptm;
 
        /* Open the slave side. */
@@ -130,7 +132,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
        name = ttyname(*ptyfd);
        if (!name)
                fatal("Open of /dev/ptc returns device for which ttyname fails.");
-       strcpy(namebuf, name);
+       strlcpy(namebuf, name, namebuflen);
        *ttyfd = open(name, O_RDWR | O_NOCTTY);
        if (*ttyfd < 0) {
                error("Could not open pty slave side %.100s: %.100s",
@@ -154,8 +156,8 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
                *ptyfd = open(buf, O_RDWR | O_NOCTTY);
                if (*ptyfd < 0)
                        continue;
-               snprintf(namebuf, sizeof buf, "/dev/tty%c%c", ptymajors[i / num_minors],
-                        ptyminors[i % num_minors]);
+               snprintf(namebuf, sizeof namebuflen, "/dev/tty%c%c",
+                   ptymajors[i / num_minors], ptyminors[i % num_minors]);
 
                /* Open the slave side. */
                *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
diff --git a/pty.h b/pty.h
index 6d02121ea5572ed90c6c7bdb8be0a53b7498e090..25668f01ffeb8749db43bd8be982955e028ca7fb 100644 (file)
--- a/pty.h
+++ b/pty.h
@@ -24,7 +24,7 @@
  * descriptors for the pty and tty sides and the name of the tty side are
  * returned (the buffer must be able to hold at least 64 characters).
  */
-int     pty_allocate(int *ptyfd, int *ttyfd, char *ttyname);
+int     pty_allocate(int *ptyfd, int *ttyfd, char *ttyname, int ttynamelen);
 
 /*
  * Releases the tty.  Its ownership is returned to root, and permissions to
diff --git a/rc4.c b/rc4.c
deleted file mode 100644 (file)
index 2ff6f37..0000000
--- a/rc4.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*! \file rc4.c
-    \brief Source file for RC4 stream cipher routines
-        \author Damien Miller <djm@mindrot.org>
-        \version 0.0.0
-        \date 1999
-        
-        A simple implementation of the RC4 stream cipher, based on the
-        description given in _Bruce Schneier's_ "Applied Cryptography"
-        2nd edition.
-
-        Copyright 1999 Damien Miller
-
-        Permission is hereby granted, free of charge, to any person
-        obtaining a copy of this software and associated documentation
-        files (the "Software"), to deal in the Software without
-        restriction, including without limitation the rights to use, copy,
-        modify, merge, publish, distribute, sublicense, and/or sell copies
-        of the Software, and to permit persons to whom the Software is
-        furnished to do so, subject to the following conditions:
-
-        The above copyright notice and this permission notice shall be
-        included in all copies or substantial portions of the Software.
-
-        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-        KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-        WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
-        AND NONINFRINGEMENT.  IN NO EVENT SHALL DAMIEN MILLER BE LIABLE
-        FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-        CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-        WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-        \warning None of these functions clears its memory after use. It
-        \warning is the responsability of the calling routines to ensure
-        \warning that any sensitive data (keystream, key or plaintext) is
-        \warning properly erased after use.
-        
-        \warning The name "RC4" is trademarked in the United States, 
-        \warning you may need to use "RC4 compatible" or "ARC4" 
-        \warning (Alleged RC4).
-*/
-
-/* $Id$ */
-
-#include "config.h"
-
-#ifndef HAVE_ARC4RANDOM
-#include "rc4.h"
-
-
-void rc4_key(rc4_t *r, unsigned char *key, int len)
-{
-       int t;
-       
-       for(r->i = 0; r->i < 256; r->i++)
-               r->s[r->i] = r->i;
-
-       r->j = 0;
-       for(r->i = 0; r->i < 256; r->i++)
-       {
-               r->j = (r->j + r->s[r->i] + key[r->i % len]) % 256;
-               t = r->s[r->i];
-               r->s[r->i] = r->s[r->j];
-               r->s[r->j] = t;
-       }
-       r->i = r->j = 0;
-}
-
-void rc4_crypt(rc4_t *r, unsigned char *plaintext, int len)
-{
-       int t;
-       int c;
-
-       c = 0;  
-       while(c < len)
-       {
-               r->i = (r->i + 1) % 256;
-               r->j = (r->j + r->s[r->i]) % 256;
-               t = r->s[r->i];
-               r->s[r->i] = r->s[r->j];
-               r->s[r->j] = t;
-
-               t = (r->s[r->i] + r->s[r->j]) % 256;
-
-               plaintext[c] ^= r->s[t];
-               c++;
-       }
-}
-
-void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len)
-{
-       int t;
-       int c;
-
-       c = 0;  
-       while(c < len)
-       {
-               r->i = (r->i + 1) % 256;
-               r->j = (r->j + r->s[r->i]) % 256;
-               t = r->s[r->i];
-               r->s[r->i] = r->s[r->j];
-               r->s[r->j] = t;
-
-               t = (r->s[r->i] + r->s[r->j]) % 256;
-               
-               buffer[c] = r->s[t];
-               c++;
-       }
-}
-#endif /* !HAVE_ARC4RANDOM */
diff --git a/rc4.h b/rc4.h
deleted file mode 100644 (file)
index 680936a..0000000
--- a/rc4.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*! \file rc4.h
-    \brief Header file for RC4 stream cipher routines
-        \author Damien Miller <djm@mindrot.org>
-        \version 0.0.0
-        \date 1999
-        
-        A simple implementation of the RC4 stream cipher, based on the
-        description given in _Bruce Schneier's_ "Applied Cryptography"
-        2nd edition.
-
-        Copyright 1999 Damien Miller
-
-        Permission is hereby granted, free of charge, to any person
-        obtaining a copy of this software and associated documentation
-        files (the "Software"), to deal in the Software without
-        restriction, including without limitation the rights to use, copy,
-        modify, merge, publish, distribute, sublicense, and/or sell copies
-        of the Software, and to permit persons to whom the Software is
-        furnished to do so, subject to the following conditions:
-
-        The above copyright notice and this permission notice shall be
-        included in all copies or substantial portions of the Software.
-
-        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-        KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-        WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
-        AND NONINFRINGEMENT.  IN NO EVENT SHALL DAMIEN MILLER BE LIABLE
-        FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-        CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-        WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-        \warning None of these functions clears its memory after use. It
-        \warning is the responsability of the calling routines to ensure
-        \warning that any sensitive data (keystream, key or plaintext) is
-        \warning properly erased after use.
-        
-        \warning The name "RC4" is trademarked in the United States, 
-        \warning you may need to use "RC4 compatible" or "ARC4" 
-        \warning (Alleged RC4).
-*/
-
-/* $Id$ */
-
-#ifndef _RC4_H
-#define _RC4_H
-
-#include "config.h"
-#ifndef HAVE_ARC4RANDOM
-
-/*! \struct rc4_t
-    \brief RC4 stream cipher state object
-        \var s State array
-        \var i Monotonic index
-        \var j Randomised index
-        
-        \warning This structure should not be accessed directly. To
-        \warning initialise a rc4_t object, you should use the rc4_key()
-        \warning function
-        
-        This structure holds the current state of the RC4 algorithm.
-*/
-typedef struct
-{
-       unsigned int s[256];
-       int i;
-       int j;
-} rc4_t;
-
-/*! \fn void rc4_key(rc4_t *r, unsigned char *key, int len);
-    \brief Set up key structure of RC4 stream cipher
-        \param r pointer to RC4 structure to be seeded
-        \param key pointer to buffer containing raw key
-        \param len length of key
-        
-        This function set the internal state of the RC4 data structure
-        pointed to by \a r using the specified \a key of length \a len.
-        
-        This function can use up to 256 bytes of key, any more are ignored.
-        
-        \warning Stream ciphers (such as RC4) can be insecure if the same
-        \warning key is used repeatedly. Ensure that any key specified has
-        \warning an reasonably sized Initialisation Vector component.
-*/
-void rc4_key(rc4_t *r, unsigned char *key, int len);
-
-/*! \fn rc4_crypt(rc4_t *r, unsigned char *plaintext, int len);
-    \brief Crypt bytes using RC4 algorithm
-        \param r pointer to RC4 structure to be used
-        \param plaintext Pointer to bytes to encrypt
-        \param len number of bytes to crypt
-
-        This function encrypts one or more bytes (pointed to by \a plaintext)
-        using the RC4 algorithm. \a r is a state structure that must be 
-        initialiased using the rc4_key() function prior to use.
-        
-        Since RC4 XORs each byte of plaintext with a byte of keystream,
-        this function can be used for both encryption and decryption.
-*/
-void rc4_crypt(rc4_t *r, unsigned char *plaintext, int len);
-
-/*! \fn rc4_getbytes(rc4_t *r, unsigned char *buffer, int len);
-    \brief Generate key stream using the RC4 stream cipher
-        \param r pointer to RC4 structure to be used
-        \param buffer pointer to buffer in which to deposit keystream
-        \param len number of bytes to deposit
-
-        This function gives access to the raw RC4 key stream. In this 
-        consiguration RC4 can be used as a fast, strong pseudo-random 
-        number generator with a very long period.
-*/
-void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len);
-
-#endif /* !HAVE_ARC4RANDOM */
-
-#endif /* _RC4_H */
diff --git a/scp.c b/scp.c
index dc2bb4eda1ce7be0a1083ff41691dde473b6f43a..593954d0fad8d1be0325cef0a2126c755afbba5a 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -1065,30 +1065,6 @@ lostconn(signo)
        exit(1);
 }
 
-/*
- * ensure all of data on socket comes through. f==read || f==write
- */
-int
-atomicio(f, fd, s, n)
-       int (*f) ();
-       char *s;
-{
-       int res, pos = 0;
-
-       while (n > pos) {
-               res = (f) (fd, s + pos, n - pos);
-               switch (res) {
-               case -1:
-                       if (errno == EINTR || errno == EAGAIN)
-                               continue;
-               case 0:
-                       return (res);
-               default:
-                       pos += res;
-               }
-       }
-       return (pos);
-}
 
 void
 alarmtimer(int wait)
index 94c2115710dcecb1cc03721aea1c6034c878fd10..a5ecfe97d5d7cde64aa147a7bdfb80918f0f8320 100644 (file)
@@ -170,7 +170,7 @@ make_packets_from_stderr_data()
 
        /* Send buffered stderr data to the client. */
        while (buffer_len(&stderr_buffer) > 0 &&
-              packet_not_very_much_data_to_write()) {
+           packet_not_very_much_data_to_write()) {
                len = buffer_len(&stderr_buffer);
                if (packet_is_interactive()) {
                        if (len > 512)
@@ -199,7 +199,7 @@ make_packets_from_stdout_data()
 
        /* Send buffered stdout data to the client. */
        while (buffer_len(&stdout_buffer) > 0 &&
-              packet_not_very_much_data_to_write()) {
+           packet_not_very_much_data_to_write()) {
                len = buffer_len(&stdout_buffer);
                if (packet_is_interactive()) {
                        if (len > 512)
@@ -364,7 +364,7 @@ process_output(fd_set * writeset)
        /* Write buffered data to program stdin. */
        if (fdin != -1 && FD_ISSET(fdin, writeset)) {
                len = write(fdin, buffer_ptr(&stdin_buffer),
-                           buffer_len(&stdin_buffer));
+                   buffer_len(&stdin_buffer));
                if (len <= 0) {
 #ifdef USE_PIPES
                        close(fdin);
diff --git a/ssh.h b/ssh.h
index d72dcb4ead0c9e37c70c1f6d18681c7afb8c526d..0ec608f0b89e363ca169c6638b42ce8099ad935e 100644 (file)
--- a/ssh.h
+++ b/ssh.h
@@ -702,9 +702,14 @@ struct envstring {
        struct envstring *next;
        char   *s;
 };
+
+/*
+ * Ensure all of data on socket comes through. f==read || f==write
+ */
+int    atomicio(int (*f)(), int fd, void *s, size_t n);
+
 #ifdef KRB4
 #include <krb.h>
-
 /*
  * Performs Kerberos v4 mutual authentication with the client. This returns 0
  * if the client could not be authenticated, and 1 if authentication was
index d64eafd90e0977c12d033b77d136d53469fa1755..3526ccccae43d4771f24dc7afcd16cdb156ee2e6 100644 (file)
@@ -537,7 +537,7 @@ try_rsa_authentication(const char *authfile)
        if (!load_private_key(authfile, "", private_key, NULL)) {
                char buf[300];
                snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
-                        comment);
+                   comment);
                if (!options.batch_mode)
                        passphrase = read_passphrase(buf, 0);
                else {
@@ -1036,8 +1036,8 @@ ssh_exchange_identification()
 
        /* Send our own protocol version identification. */
        snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
-                PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
-       if (write(connection_out, buf, strlen(buf)) != strlen(buf))
+           PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
+       if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
                fatal("write: %.100s", strerror(errno));
 }
 
@@ -1292,10 +1292,10 @@ ssh_login(int host_key_valid,
                        char prompt[1024];
                        char *fp = fingerprint(host_key->e, host_key->n);
                        snprintf(prompt, sizeof(prompt),
-                                "The authenticity of host '%.200s' can't be established.\n"
-                                "Key fingerprint is %d %s.\n"
-                                "Are you sure you want to continue connecting (yes/no)? ",
-                                host, BN_num_bits(host_key->n), fp);
+                           "The authenticity of host '%.200s' can't be established.\n"
+                           "Key fingerprint is %d %s.\n"
+                           "Are you sure you want to continue connecting (yes/no)? ",
+                           host, BN_num_bits(host_key->n), fp);
                        if (!read_yes_or_no(prompt, -1))
                                fatal("Aborted by user!\n");
                }
@@ -1599,8 +1599,9 @@ ssh_login(int host_key_valid,
        if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
            options.password_authentication && !options.batch_mode) {
                char prompt[80];
+
                snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
-                        server_user, host);
+                   server_user, host);
                if (try_password_authentication(prompt))
                        return;
        }
diff --git a/sshd.c b/sshd.c
index 9b067770cbbdb0002a2a001fe542320aee44169d..1252f760c97e69b4fb5f028193cc881ccc3d1376 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -812,7 +812,7 @@ main(int ac, char **av)
                /* Send our protocol version identification. */
                snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
                         PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
-               if (write(sock_out, buf, strlen(buf)) != strlen(buf))
+               if (atomicio(write, sock_out, buf, strlen(buf)) != strlen(buf))
                        fatal("Could not write ident string to %s.", get_remote_ipaddr());
 
                /* Read other side\'s version identification. */
@@ -838,9 +838,10 @@ main(int ac, char **av)
         * several versions and set appropriate flags to handle them.
         */
        if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
-                  remote_version) != 3) {
-               const char *s = "Protocol mismatch.\n";
-               (void) write(sock_out, s, strlen(s));
+           remote_version) != 3) {
+               char *s = "Protocol mismatch.\n";
+
+               (void) atomicio(write, sock_out, s, strlen(s));
                close(sock_in);
                close(sock_out);
                fatal("Bad protocol version identification '%.100s' from %s",
@@ -849,8 +850,9 @@ main(int ac, char **av)
        debug("Client protocol version %d.%d; client software version %.100s",
              remote_major, remote_minor, remote_version);
        if (remote_major != PROTOCOL_MAJOR) {
-               const char *s = "Protocol major versions differ.\n";
-               (void) write(sock_out, s, strlen(s));
+               char *s = "Protocol major versions differ.\n";
+
+               (void) atomicio(write, sock_out, s, strlen(s));
                close(sock_in);
                close(sock_out);
                fatal("Protocol major versions differ for %s: %d vs. %d",
@@ -1737,7 +1739,8 @@ do_authenticated(struct passwd * pw)
                        debug("Allocating pty.");
 
                        /* Allocate a pty and open it. */
-                       if (!pty_allocate(&ptyfd, &ttyfd, ttyname)) {
+                       if (!pty_allocate(&ptyfd, &ttyfd, ttyname,
+                           sizeof(ttyname))) {
                                error("Failed to allocate pty.");
                                goto fail;
                        }
index 06f397c1a7a41d393bbfd5e3280c09b2784ae80c..9fd430bd40b93bfb5a7ad0ea5a5cd5eab3562940 100644 (file)
@@ -23,6 +23,7 @@ tilde_expand_filename(const char *filename, uid_t my_uid)
        char *expanded;
        struct passwd *pw;
        char user[100];
+       int len;
 
        /* Return immediately if no tilde. */
        if (filename[0] != '~')
@@ -56,7 +57,10 @@ tilde_expand_filename(const char *filename, uid_t my_uid)
                return xstrdup(pw->pw_dir);
        }
        /* Build a path combining the specified directory and path. */
-       expanded = xmalloc(strlen(pw->pw_dir) + strlen(cp + 1) + 2);
-       sprintf(expanded, "%s/%s", pw->pw_dir, cp + 1);
+       len = strlen(pw->pw_dir) + strlen(cp + 1) + 2;
+       if (len > MAXPATHLEN)
+               fatal("Home directory too long (%d > %d", len-1, MAXPATHLEN-1);
+       expanded = xmalloc(len);
+       snprintf(expanded, len, "%s/%s", pw->pw_dir, cp + 1);
        return expanded;
 }
This page took 0.104235 seconds and 5 git commands to generate.