diff options
author | Damien Miller <djm@mindrot.org> | 1999-12-07 15:38:31 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 1999-12-07 15:38:31 +1100 |
commit | 037a0dc0835bb5a442bdcbeecdd5baed723f0b45 (patch) | |
tree | d02954d57ac437fd036e3e9544f24559ca8f0f0f | |
parent | eabf3417bc73ca9546a3ed489cd809ffdf303853 (diff) |
- 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)
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | Makefile.in | 28 | ||||
-rw-r--r-- | acconfig.h | 6 | ||||
-rw-r--r-- | atomicio.c | 57 | ||||
-rw-r--r-- | auth-skey.c | 5 | ||||
-rw-r--r-- | authfd.c | 24 | ||||
-rw-r--r-- | authfile.c | 51 | ||||
-rw-r--r-- | channels.c | 7 | ||||
-rw-r--r-- | clientloop.c | 20 | ||||
-rw-r--r-- | configure.in | 5 | ||||
-rw-r--r-- | helper.c | 64 | ||||
-rw-r--r-- | pty.c | 20 | ||||
-rw-r--r-- | pty.h | 4 | ||||
-rw-r--r-- | rc4.c | 109 | ||||
-rw-r--r-- | rc4.h | 115 | ||||
-rw-r--r-- | scp.c | 28 | ||||
-rw-r--r-- | serverloop.c | 6 | ||||
-rw-r--r-- | ssh.h | 9 | ||||
-rw-r--r-- | sshconnect.c | 19 | ||||
-rw-r--r-- | sshd.c | 19 | ||||
-rw-r--r-- | tildexpand.c | 10 |
21 files changed, 263 insertions, 361 deletions
@@ -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 diff --git a/Makefile.in b/Makefile.in index c2c3261b..80b0a6d4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 @@ -64,6 +64,12 @@ #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 index 00000000..03d635cb --- /dev/null +++ b/atomicio.c @@ -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: atomicio.c,v 1.1 1999/12/07 04:38:31 damien Exp $"); + +#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); +} diff --git a/auth-skey.c b/auth-skey.c index cc5f4510..88291599 100644 --- a/auth-skey.c +++ b/auth-skey.c @@ -1,7 +1,7 @@ #include "includes.h" #ifdef SKEY -RCSID("$Id: auth-skey.c,v 1.4 1999/12/01 16:54:35 markus Exp $"); +RCSID("$Id: auth-skey.c,v 1.5 1999/12/06 19:04:57 deraadt Exp $"); #include "ssh.h" #include "packet.h" @@ -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 */ @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$Id: authfd.c,v 1.8 1999/11/25 00:54:57 damien Exp $"); +RCSID("$Id: authfd.c,v 1.9 1999/12/07 04:38:32 damien Exp $"); #include "ssh.h" #include "rsa.h" @@ -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; } @@ -15,7 +15,7 @@ */ #include "includes.h" -RCSID("$Id: authfile.c,v 1.5 1999/11/25 00:54:58 damien Exp $"); +RCSID("$Id: authfile.c,v 1.6 1999/12/07 04:38:32 damien Exp $"); #ifdef HAVE_OPENSSL #include <openssl/bn.h> @@ -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) { @@ -16,7 +16,7 @@ */ #include "includes.h" -RCSID("$Id: channels.c,v 1.9 1999/12/06 00:47:29 damien Exp $"); +RCSID("$Id: channels.c,v 1.10 1999/12/07 04:38:32 damien Exp $"); #include "ssh.h" #include "packet.h" @@ -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. */ diff --git a/clientloop.c b/clientloop.c index 679180f5..bfa3019b 100644 --- a/clientloop.c +++ b/clientloop.c @@ -15,7 +15,7 @@ */ #include "includes.h" -RCSID("$Id: clientloop.c,v 1.6 1999/11/25 00:54:58 damien Exp $"); +RCSID("$Id: clientloop.c,v 1.7 1999/12/07 04:38:32 damien Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -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; diff --git a/configure.in b/configure.in index 86f2dde7..62e68317 100644 --- a/configure.in +++ b/configure.in @@ -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);], @@ -45,7 +45,6 @@ #include <sys/un.h> #include <fcntl.h> -#include "rc4.h" #include "xmalloc.h" #include "ssh.h" #include "config.h" @@ -57,10 +56,58 @@ #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); } @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$Id: pty.c,v 1.5 1999/11/25 00:54:59 damien Exp $"); +RCSID("$Id: pty.c,v 1.6 1999/12/07 04:38:32 damien Exp $"); #include "pty.h" #include "ssh.h" @@ -40,17 +40,19 @@ RCSID("$Id: pty.c,v 1.5 1999/11/25 00:54:59 damien Exp $"); */ 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); @@ -13,7 +13,7 @@ * tty. */ -/* RCSID("$Id: pty.h,v 1.3 1999/11/25 00:54:59 damien Exp $"); */ +/* RCSID("$Id: pty.h,v 1.4 1999/12/07 04:38:32 damien Exp $"); */ #ifndef PTY_H #define 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 @@ -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: rc4.c,v 1.1.1.1 1999/10/26 05:48:13 damien Exp $ */ - -#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 */ @@ -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, s |