]> andersk Git - openssh.git/commitdiff
- Remove references to SSLeay.
authordamien <damien>
Sun, 7 May 2000 02:03:14 +0000 (02:03 +0000)
committerdamien <damien>
Sun, 7 May 2000 02:03:14 +0000 (02:03 +0000)
 - Big OpenBSD CVS update
  - markus@cvs.openbsd.org
    [clientloop.c]
    - typo
    [session.c]
    - update proctitle on pty alloc/dealloc, e.g. w/ windows client
    [session.c]
    - update proctitle for proto 1, too
    [channels.h nchan.c serverloop.c session.c sshd.c]
    - use c-style comments
  - deraadt@cvs.openbsd.org
    [scp.c]
    - more atomicio
  - markus@cvs.openbsd.org
    [channels.c]
    - set O_NONBLOCK
    [ssh.1]
    - update AUTHOR
    [readconf.c ssh-keygen.c ssh.h]
    - default DSA key file ~/.ssh/id_dsa
    [clientloop.c]
    - typo, rm verbose debug
  - deraadt@cvs.openbsd.org
    [ssh-keygen.1]
    - document DSA use of ssh-keygen
    [sshd.8]
    - a start at describing what i understand of the DSA side
    [ssh-keygen.1]
    - document -X and -x
    [ssh-keygen.c]
    - simplify usage
  - markus@cvs.openbsd.org
    [sshd.8]
    - there is no rhosts_dsa
    [ssh-keygen.1]
    - document -y, update -X,-x
    [nchan.c]
    - fix close for non-open ssh1 channels
    [servconf.c servconf.h ssh.h sshd.8 sshd.c ]
    - s/DsaKey/HostDSAKey/, document option
    [sshconnect2.c]
    - respect number_of_password_prompts
    [channels.c channels.h servconf.c servconf.h session.c sshd.8]
    - GatewayPorts for sshd, ok deraadt@
    [ssh-add.1 ssh-agent.1 ssh.1]
    - more doc on: DSA, id_dsa, known_hosts2, authorized_keys2
    [ssh.1]
    - more info on proto 2
    [sshd.8]
    - sync AUTHOR w/ ssh.1
    [key.c key.h sshconnect.c]
    - print key type when talking about host keys
    [packet.c]
    - clear padding in ssh2
    [dsa.c key.c radix.c ssh.h sshconnect1.c uuencode.c uuencode.h]
    - replace broken uuencode w/ libc b64_ntop
    [auth2.c]
    - log failure before sending the reply
    [key.c radix.c uuencode.c]
    - remote trailing comments before calling __b64_pton
    [auth2.c readconf.c readconf.h servconf.c servconf.h ssh.1]
    [sshconnect2.c sshd.8]
    - add DSAAuthetication option to ssh/sshd, document SSH2 in sshd.8
 - Bring in b64_ntop and b64_pton from OpenBSD libc (bsd-base64.[ch])

36 files changed:
ChangeLog
Makefile.in
auth2.c
bsd-base64.c [new file with mode: 0644]
bsd-base64.h [new file with mode: 0644]
channels.c
channels.h
clientloop.c
configure.in
dsa.c
includes.h
key.c
key.h
nchan.c
packet.c
radix.c
readconf.c
readconf.h
scp.c
servconf.c
servconf.h
serverloop.c
session.c
ssh-add.1
ssh-agent.1
ssh-keygen.1
ssh-keygen.c
ssh.1
ssh.h
sshconnect.c
sshconnect1.c
sshconnect2.c
sshd.8
sshd.c
uuencode.c
uuencode.h

index d7143d5d4bf772ac05c28828957491e4e03b5a0f..c6e3548a8c285c24137cbda33e0edab0570146d8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,70 @@
+20000507
+ - Remove references to SSLeay.
+ - Big OpenBSD CVS update
+  - markus@cvs.openbsd.org
+    [clientloop.c]
+    - typo
+    [session.c]
+    - update proctitle on pty alloc/dealloc, e.g. w/ windows client
+    [session.c]
+    - update proctitle for proto 1, too
+    [channels.h nchan.c serverloop.c session.c sshd.c]
+    - use c-style comments
+  - deraadt@cvs.openbsd.org
+    [scp.c]
+    - more atomicio
+  - markus@cvs.openbsd.org 
+    [channels.c]
+    - set O_NONBLOCK
+    [ssh.1]
+    - update AUTHOR
+    [readconf.c ssh-keygen.c ssh.h]
+    - default DSA key file ~/.ssh/id_dsa
+    [clientloop.c]
+    - typo, rm verbose debug
+  - deraadt@cvs.openbsd.org
+    [ssh-keygen.1]
+    - document DSA use of ssh-keygen
+    [sshd.8]
+    - a start at describing what i understand of the DSA side
+    [ssh-keygen.1]
+    - document -X and -x
+    [ssh-keygen.c]
+    - simplify usage
+  - markus@cvs.openbsd.org 
+    [sshd.8]
+    - there is no rhosts_dsa
+    [ssh-keygen.1]
+    - document -y, update -X,-x
+    [nchan.c]
+    - fix close for non-open ssh1 channels
+    [servconf.c servconf.h ssh.h sshd.8 sshd.c ]
+    - s/DsaKey/HostDSAKey/, document option
+    [sshconnect2.c]
+    - respect number_of_password_prompts
+    [channels.c channels.h servconf.c servconf.h session.c sshd.8]
+    - GatewayPorts for sshd, ok deraadt@
+    [ssh-add.1 ssh-agent.1 ssh.1]
+    - more doc on: DSA, id_dsa, known_hosts2, authorized_keys2
+    [ssh.1]
+    - more info on proto 2
+    [sshd.8]
+    - sync AUTHOR w/ ssh.1
+    [key.c key.h sshconnect.c]
+    - print key type when talking about host keys
+    [packet.c]
+    - clear padding in ssh2
+    [dsa.c key.c radix.c ssh.h sshconnect1.c uuencode.c uuencode.h]
+    - replace broken uuencode w/ libc b64_ntop
+    [auth2.c]
+    - log failure before sending the reply
+    [key.c radix.c uuencode.c]
+    - remote trailing comments before calling __b64_pton
+    [auth2.c readconf.c readconf.h servconf.c servconf.h ssh.1]
+    [sshconnect2.c sshd.8]
+    - add DSAAuthetication option to ssh/sshd, document SSH2 in sshd.8
+ - Bring in b64_ntop and b64_pton from OpenBSD libc (bsd-base64.[ch])
+
 20000502
  - OpenBSD CVS update
    [channels.c]
index 646201c0484399aa409668d55067a91b7e61b22b..de2fbd269c652e152b6e57ae5c834b0d449d686f 100644 (file)
@@ -33,7 +33,7 @@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
 
 TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS)
 
-LIBOBJS= atomicio.o authfd.o authfile.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.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 dispatch.o dsa.o fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o 
+LIBOBJS= atomicio.o authfd.o authfile.o bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.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 dispatch.o dsa.o fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o 
 
 SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o
 
diff --git a/auth2.c b/auth2.c
index e77358a3b3efad831a4584f080fb75d0a45bf698..3d997f45b35f469c22dbff784fd9139d8edf3d22 100644 (file)
--- a/auth2.c
+++ b/auth2.c
@@ -27,7 +27,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.5 2000/05/01 23:13:39 djm Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.7 2000/05/06 17:45:36 markus Exp $");
 
 #include <openssl/dsa.h>
 #include <openssl/rsa.h>
@@ -188,9 +188,29 @@ input_userauth_request(int type, int plen)
                        authenticated = 0;
 #endif /* USE_PAM */
 
-       /* XXX todo: check if multiple auth methods are needed */
+       /* Raise logging level */
+       if (authenticated == 1 ||
+           attempt == AUTH_FAIL_LOG ||
+           strcmp(method, "password") == 0)
+               authlog = log;
+
+       /* Log before sending the reply */
        if (authenticated == 1) {
                authmsg = "Accepted";
+       } else if (authenticated == 0) {
+               authmsg = "Failed";
+       } else {
+               authmsg = "Postponed";
+       }
+       authlog("%s %s for %.200s from %.200s port %d ssh2",
+               authmsg,
+               method,
+               pw && pw->pw_uid == 0 ? "ROOT" : user,
+               get_remote_ipaddr(),
+               get_remote_port());
+
+       /* XXX todo: check if multiple auth methods are needed */
+       if (authenticated == 1) {
                /* turn off userauth */
                dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
                packet_start(SSH2_MSG_USERAUTH_SUCCESS);
@@ -199,27 +219,12 @@ input_userauth_request(int type, int plen)
                /* now we can break out */
                userauth_success = 1;
        } else if (authenticated == 0) {
-               authmsg = "Failed";
                packet_start(SSH2_MSG_USERAUTH_FAILURE);
                packet_put_cstring("publickey,password");       /* XXX dynamic */
                packet_put_char(0);                             /* XXX partial success, unused */
                packet_send();
                packet_write_wait();
-       } else {
-               authmsg = "Postponed";
        }
-       /* Raise logging level */
-       if (authenticated == 1||
-           attempt == AUTH_FAIL_LOG ||
-           strcmp(method, "password") == 0)
-               authlog = log;
-
-       authlog("%s %s for %.200s from %.200s port %d ssh2",
-               authmsg,
-               method,
-               pw && pw->pw_uid == 0 ? "ROOT" : user,
-               get_remote_ipaddr(),
-               get_remote_port());
 
        xfree(service);
        xfree(user);
@@ -269,7 +274,7 @@ ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
        int have_sig;
        int authenticated = 0;
 
-       if (options.rsa_authentication == 0) {
+       if (options.dsa_authentication == 0) {
                debug("pubkey auth disabled");
                return 0;
        }
@@ -306,6 +311,13 @@ ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
                        debug("test key...");
                        /* test whether pkalg/pkblob are acceptable */
                        /* XXX fake reply and always send PK_OK ? */
+                       /*
+                        * XXX this allows testing whether a user is allowed
+                        * to login: if you happen to have a valid pubkey this
+                        * message is sent. the message is NEVER sent at all
+                        * if a user is not allowed to login. is this an
+                        * issue? -markus
+                        */
                        if (user_dsa_key_allowed(pw, key)) {
                                packet_start(SSH2_MSG_USERAUTH_PK_OK);
                                packet_put_string(pkalg, alen);
diff --git a/bsd-base64.c b/bsd-base64.c
new file mode 100644 (file)
index 0000000..57a9573
--- /dev/null
@@ -0,0 +1,315 @@
+/*     $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt Exp $      */
+
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "config.h"
+
+#ifndef HAVE_B64_NTOP
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#define Assert(Cond) if (!(Cond)) abort()
+
+static const char Base64[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+   The following encoding technique is taken from RFC 1521 by Borenstein
+   and Freed.  It is reproduced here in a slightly edited form for
+   convenience.
+
+   A 65-character subset of US-ASCII is used, enabling 6 bits to be
+   represented per printable character. (The extra 65th character, "=",
+   is used to signify a special processing function.)
+
+   The encoding process represents 24-bit groups of input bits as output
+   strings of 4 encoded characters. Proceeding from left to right, a
+   24-bit input group is formed by concatenating 3 8-bit input groups.
+   These 24 bits are then treated as 4 concatenated 6-bit groups, each
+   of which is translated into a single digit in the base64 alphabet.
+
+   Each 6-bit group is used as an index into an array of 64 printable
+   characters. The character referenced by the index is placed in the
+   output string.
+
+                         Table 1: The Base64 Alphabet
+
+      Value Encoding  Value Encoding  Value Encoding  Value Encoding
+          0 A            17 R            34 i            51 z
+          1 B            18 S            35 j            52 0
+          2 C            19 T            36 k            53 1
+          3 D            20 U            37 l            54 2
+          4 E            21 V            38 m            55 3
+          5 F            22 W            39 n            56 4
+          6 G            23 X            40 o            57 5
+          7 H            24 Y            41 p            58 6
+          8 I            25 Z            42 q            59 7
+          9 J            26 a            43 r            60 8
+         10 K            27 b            44 s            61 9
+         11 L            28 c            45 t            62 +
+         12 M            29 d            46 u            63 /
+         13 N            30 e            47 v
+         14 O            31 f            48 w         (pad) =
+         15 P            32 g            49 x
+         16 Q            33 h            50 y
+
+   Special processing is performed if fewer than 24 bits are available
+   at the end of the data being encoded.  A full encoding quantum is
+   always completed at the end of a quantity.  When fewer than 24 input
+   bits are available in an input group, zero bits are added (on the
+   right) to form an integral number of 6-bit groups.  Padding at the
+   end of the data is performed using the '=' character.
+
+   Since all base64 input is an integral number of octets, only the
+         -------------------------------------------------                       
+   following cases can arise:
+   
+       (1) the final quantum of encoding input is an integral
+           multiple of 24 bits; here, the final unit of encoded
+          output will be an integral multiple of 4 characters
+          with no "=" padding,
+       (2) the final quantum of encoding input is exactly 8 bits;
+           here, the final unit of encoded output will be two
+          characters followed by two "=" padding characters, or
+       (3) the final quantum of encoding input is exactly 16 bits;
+           here, the final unit of encoded output will be three
+          characters followed by one "=" padding character.
+   */
+
+int
+b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize)
+{
+       size_t datalength = 0;
+       u_char input[3];
+       u_char output[4];
+       int i;
+
+       while (2 < srclength) {
+               input[0] = *src++;
+               input[1] = *src++;
+               input[2] = *src++;
+               srclength -= 3;
+
+               output[0] = input[0] >> 2;
+               output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+               output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+               output[3] = input[2] & 0x3f;
+               Assert(output[0] < 64);
+               Assert(output[1] < 64);
+               Assert(output[2] < 64);
+               Assert(output[3] < 64);
+
+               if (datalength + 4 > targsize)
+                       return (-1);
+               target[datalength++] = Base64[output[0]];
+               target[datalength++] = Base64[output[1]];
+               target[datalength++] = Base64[output[2]];
+               target[datalength++] = Base64[output[3]];
+       }
+    
+       /* Now we worry about padding. */
+       if (0 != srclength) {
+               /* Get what's left. */
+               input[0] = input[1] = input[2] = '\0';
+               for (i = 0; i < srclength; i++)
+                       input[i] = *src++;
+       
+               output[0] = input[0] >> 2;
+               output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+               output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+               Assert(output[0] < 64);
+               Assert(output[1] < 64);
+               Assert(output[2] < 64);
+
+               if (datalength + 4 > targsize)
+                       return (-1);
+               target[datalength++] = Base64[output[0]];
+               target[datalength++] = Base64[output[1]];
+               if (srclength == 1)
+                       target[datalength++] = Pad64;
+               else
+                       target[datalength++] = Base64[output[2]];
+               target[datalength++] = Pad64;
+       }
+       if (datalength >= targsize)
+               return (-1);
+       target[datalength] = '\0';      /* Returned value doesn't count \0. */
+       return (datalength);
+}
+
+/* skips all whitespace anywhere.
+   converts characters, four at a time, starting at (or after)
+   src from base - 64 numbers into three 8 bit bytes in the target area.
+   it returns the number of data bytes stored at the target, or -1 on error.
+ */
+
+int
+b64_pton(char const *src, u_char *target, size_t targsize)
+{
+       int tarindex, state, ch;
+       char *pos;
+
+       state = 0;
+       tarindex = 0;
+
+       while ((ch = *src++) != '\0') {
+               if (isspace(ch))        /* Skip whitespace anywhere. */
+                       continue;
+
+               if (ch == Pad64)
+                       break;
+
+               pos = strchr(Base64, ch);
+               if (pos == 0)           /* A non-base64 character. */
+                       return (-1);
+
+               switch (state) {
+               case 0:
+                       if (target) {
+                               if (tarindex >= targsize)
+                                       return (-1);
+                               target[tarindex] = (pos - Base64) << 2;
+                       }
+                       state = 1;
+                       break;
+               case 1:
+                       if (target) {
+                               if (tarindex + 1 >= targsize)
+                                       return (-1);
+                               target[tarindex]   |=  (pos - Base64) >> 4;
+                               target[tarindex+1]  = ((pos - Base64) & 0x0f)
+                                                       << 4 ;
+                       }
+                       tarindex++;
+                       state = 2;
+                       break;
+               case 2:
+                       if (target) {
+                               if (tarindex + 1 >= targsize)
+                                       return (-1);
+                               target[tarindex]   |=  (pos - Base64) >> 2;
+                               target[tarindex+1]  = ((pos - Base64) & 0x03)
+                                                       << 6;
+                       }
+                       tarindex++;
+                       state = 3;
+                       break;
+               case 3:
+                       if (target) {
+                               if (tarindex >= targsize)
+                                       return (-1);
+                               target[tarindex] |= (pos - Base64);
+                       }
+                       tarindex++;
+                       state = 0;
+                       break;
+               }
+       }
+
+       /*
+        * We are done decoding Base-64 chars.  Let's see if we ended
+        * on a byte boundary, and/or with erroneous trailing characters.
+        */
+
+       if (ch == Pad64) {              /* We got a pad char. */
+               ch = *src++;            /* Skip it, get next. */
+               switch (state) {
+               case 0:         /* Invalid = in first position */
+               case 1:         /* Invalid = in second position */
+                       return (-1);
+
+               case 2:         /* Valid, means one byte of info */
+                       /* Skip any number of spaces. */
+                       for (; ch != '\0'; ch = *src++)
+                               if (!isspace(ch))
+                                       break;
+                       /* Make sure there is another trailing = sign. */
+                       if (ch != Pad64)
+                               return (-1);
+                       ch = *src++;            /* Skip the = */
+                       /* Fall through to "single trailing =" case. */
+                       /* FALLTHROUGH */
+
+               case 3:         /* Valid, means two bytes of info */
+                       /*
+                        * We know this char is an =.  Is there anything but
+                        * whitespace after it?
+                        */
+                       for (; ch != '\0'; ch = *src++)
+                               if (!isspace(ch))
+                                       return (-1);
+
+                       /*
+                        * Now make sure for cases 2 and 3 that the "extra"
+                        * bits that slopped past the last full byte were
+                        * zeros.  If we don't check them, they become a
+                        * subliminal channel.
+                        */
+                       if (target && target[tarindex] != 0)
+                               return (-1);
+               }
+       } else {
+               /*
+                * We ended by seeing the end of the string.  Make sure we
+                * have no partial bytes lying around.
+                */
+               if (state != 0)
+                       return (-1);
+       }
+
+       return (tarindex);
+}
+
+#endif /* HAVE_B64_NTOP */
diff --git a/bsd-base64.h b/bsd-base64.h
new file mode 100644 (file)
index 0000000..c5dace7
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _BSD_BASE64_H
+#define _BSD_BASE64_H
+
+#include "config.h"
+
+#ifndef HAVE___B64_NTOP
+# ifdef HAVE_B64_NTOP
+#  define __b64_ntop b64_ntop
+#  define __b64_pton b64_pton
+# else /* !HAVE_B64_NTOP */
+
+int b64_ntop(u_char const *src, size_t srclength, char *target, 
+    size_t targsize);
+int b64_pton(char const *src, u_char *target, size_t targsize);
+
+# endif /* HAVE_B64_NTOP */
+#endif /* HAVE___B64_NTOP */
+
+#endif /* _BSD_BINRESVPORT_H */
index abeb4955a76d791907d15efac582a6c17a6bb54c..7cd36adf3a0f689b92432d6b6a7827853456f37f 100644 (file)
@@ -147,8 +147,25 @@ channel_lookup(int id)
        return c;
 }
 
+void
+set_nonblock(int fd)
+{
+       int val;
+       val = fcntl(fd, F_GETFL, 0);
+       if (val < 0) {
+               error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
+               return;
+       }
+       if (val & O_NONBLOCK)
+               return;
+       debug("fd %d setting O_NONBLOCK", fd);
+       val |= O_NONBLOCK;
+       if (fcntl(fd, F_SETFL, val) == -1)
+               error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, strerror(errno));
+}
+
 /*
- * register filedescriptors for a channel, used when allocating a channel or
+ * Register filedescriptors for a channel, used when allocating a channel or
  * when the channel consumer/producer is ready, e.g. shell exec'd
  */
 
@@ -163,11 +180,18 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage)
        if (efd > channel_max_fd_value)
                channel_max_fd_value = efd;
        /* XXX set close-on-exec -markus */
+
        c->rfd = rfd;
        c->wfd = wfd;
        c->sock = (rfd == wfd) ? rfd : -1;
        c->efd = efd;
        c->extended_usage = extusage;
+       if (rfd != -1)
+               set_nonblock(rfd);
+       if (wfd != -1)
+               set_nonblock(wfd);
+       if (efd != -1)
+               set_nonblock(efd);
 }
 
 /*
@@ -1532,7 +1556,7 @@ channel_request_remote_forwarding(u_short listen_port, const char *host_to_conne
  */
 
 void
-channel_input_port_forward_request(int is_root)
+channel_input_port_forward_request(int is_root, int gateway_ports)
 {
        u_short port, host_port;
        char *hostname;
@@ -1551,9 +1575,8 @@ channel_input_port_forward_request(int is_root)
                                  port);
        /*
         * Initiate forwarding,
-        * bind port to localhost only (gateway ports == 0).
         */
-       channel_request_local_forwarding(port, hostname, host_port, 0);
+       channel_request_local_forwarding(port, hostname, host_port, gateway_ports);
 
        /* Free the argument string. */
        xfree(hostname);
index 24fedb3224501601415aedef7271281870e5a0a3..613c010721d1c01e81490f90beb6ff0763aec0bc 100644 (file)
@@ -56,7 +56,7 @@ typedef struct Channel {
 
        char   *ctype;          /* type */
 
-       // callback
+       /* callback */
        channel_callback_fn     *cb_fn;
        void    *cb_arg;
        int     cb_event;
@@ -175,7 +175,7 @@ void    channel_permit_all_opens(void);
  * listening for the port, and sends back a success reply (or disconnect
  * message if there was an error).  This never returns if there was an error.
  */
-void    channel_input_port_forward_request(int is_root);
+void    channel_input_port_forward_request(int is_root, int gateway_ports);
 
 /*
  * Creates a port for X11 connections, and starts listening for it. Returns
index ab6713787af57529442fe48accc87e170a3175fd..86972f67583f13013fe49c594dd3549ed77b3451 100644 (file)
@@ -971,7 +971,7 @@ client_input_channel_open(int type, int plen)
        rwindow = packet_get_int();
        rmaxpack = packet_get_int();
 
-       log("server_input_open: ctype %s rchan %d win %d max %d",
+       debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
            ctype, rchan, rwindow, rmaxpack);
 
        if (strcmp(ctype, "x11") == 0) {
@@ -1077,7 +1077,7 @@ client_input_channel_req(int id, void *arg)
        rtype = packet_get_string(&len);
        reply = packet_get_char();
 
-       debug("session_input_channel_req: rtype %s reply %d", rtype, reply);
+       debug("client_input_channel_req: rtype %s reply %d", rtype, reply);
 
        c = channel_lookup(id);
        if (c == NULL)
index be2a63df1c7d7a45e30b31b497ec38a908f547e5..1b099c6b8a73ad6403aec856b256d0582e195336 100644 (file)
@@ -132,7 +132,7 @@ fi
 AC_CHECK_HEADERS(bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h util.h utmp.h utmpx.h)
 
 # Checks for library functions.
-AC_CHECK_FUNCS(arc4random bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage innetgr md5_crypt mkdtemp openpty rresvport_af setenv seteuid setlogin setproctitle setreuid snprintf strlcat strlcpy updwtmpx vsnprintf vhangup _getpty)
+AC_CHECK_FUNCS(arc4random b64_ntop bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage innetgr md5_crypt mkdtemp openpty rresvport_af setenv seteuid setlogin setproctitle setreuid snprintf strlcat strlcpy updwtmpx vsnprintf vhangup _getpty __b64_ntop)
 
 AC_CHECK_FUNC(login, 
        [AC_DEFINE(HAVE_LOGIN)],
@@ -196,7 +196,7 @@ saved_CFLAGS="$CFLAGS"
 if test "x$prefix" != "xNONE" ; then
        tryssldir="$tryssldir $prefix"
 fi
-AC_MSG_CHECKING([for OpenSSL/SSLeay directory])
+AC_MSG_CHECKING([for OpenSSL directory])
 for ssldir in "" $tryssldir /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do
        if test ! -z "$ssldir" ; then
                LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir"
diff --git a/dsa.c b/dsa.c
index e1f23ec3f14c1b54ff0d319494d639322979a6bc..1b0251e5de919879e26526001d07bcb2b3f84187 100644 (file)
--- a/dsa.c
+++ b/dsa.c
@@ -63,7 +63,7 @@ dsa_key_from_blob(
        Key *key;
 
 #ifdef DEBUG_DSS
-       dump_base64(blob, blen);
+       dump_base64(stderr, blob, blen);
 #endif
        /* fetch & parse DSA/DSS pubkey */
        key = key_new(KEY_DSA);
index a83e03167b3930e452219792de7e6789e303fce1..56878a040e1cf69b32c09af7645fde8c77dc6d29 100644 (file)
@@ -99,6 +99,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 #include "bsd-snprintf.h"
 #include "bsd-daemon.h"
 #include "bsd-login.h"
+#include "bsd-base64.h"
 
 /* rfc2553 socket API replacements */
 #include "fake-getaddrinfo.h"
diff --git a/key.c b/key.c
index 583c529010ddae08e223d2a8c4418ee2c449d7f9..ae355a3fcdc6532019f24f6a21a671d657537f82 100644 (file)
--- a/key.c
+++ b/key.c
@@ -255,6 +255,10 @@ key_read(Key *ret, char **cpp)
                len = 2*strlen(cp);
                blob = xmalloc(len);
                n = uudecode(cp, blob, len);
+               if (n < 0) {
+                       error("uudecode %s failed", cp);
+                       return 0;
+               }
                k = dsa_key_from_blob(blob, n);
                if (k == NULL)
                         return 0;
@@ -297,11 +301,26 @@ key_write(Key *key, FILE *f)
                unsigned char *blob, *uu;
                dsa_make_key_blob(key, &blob, &len);
                uu = xmalloc(2*len);
-               n = uuencode(blob, len, uu);
-               fprintf(f, "%s %s", SSH_DSS, uu);
+               n = uuencode(blob, len, uu, 2*len);
+               if (n > 0) {
+                       fprintf(f, "%s %s", SSH_DSS, uu);
+                       success = 1;
+               }
                xfree(blob);
                xfree(uu);
-               success = 1;
        }
        return success;
 }
+char *
+key_type(Key *k)
+{
+       switch (k->type) {
+       case KEY_RSA:
+               return "RSA";
+               break;
+       case KEY_DSA:
+               return "DSA";
+               break;
+       }
+       return "unknown";
+}
diff --git a/key.h b/key.h
index d1bcf3b1bed7e3df49c2d29c15b6a2ae54138dfa..ed3f770b8be91205c55a7761ef4ff06014f0537b 100644 (file)
--- a/key.h
+++ b/key.h
@@ -17,6 +17,7 @@ Key   *key_new(int type);
 void   key_free(Key *k);
 int    key_equal(Key *a, Key *b);
 char   *key_fingerprint(Key *k);
+char   *key_type(Key *k);
 int    key_write(Key *key, FILE *f);
 unsigned int
 key_read(Key *key, char **cpp);
diff --git a/nchan.c b/nchan.c
index cef94323908a4629a79d63454f13cb5b82e3d0d1..51e5ba3c21112cc3a2863cb4a0bbd58f4b4640a6 100644 (file)
--- a/nchan.c
+++ b/nchan.c
@@ -139,6 +139,25 @@ static void
 chan_rcvd_ieof1(Channel *c)
 {
        debug("channel %d: rcvd ieof", c->self);
+       if (c->type != SSH_CHANNEL_OPEN) {
+               debug("channel %d: non-open", c->self);
+               if (c->istate == CHAN_INPUT_OPEN) {
+                       debug("channel %d: non-open: input open -> wait_oclose", c->self);
+                       chan_shutdown_read(c);
+                       chan_send_ieof1(c);
+                       c->istate = CHAN_INPUT_WAIT_OCLOSE;
+               } else {
+                       error("channel %d: istate %d != open", c->self, c->istate);
+               }
+               if (c->ostate == CHAN_OUTPUT_OPEN) {
+                       debug("channel %d: non-open: output open -> closed", c->self);
+                       chan_send_oclose1(c);
+                       c->ostate = CHAN_OUTPUT_CLOSED;
+               } else {
+                       error("channel %d: ostate %d != open", c->self, c->ostate);
+               }
+               return;
+       }
        switch (c->ostate) {
        case CHAN_OUTPUT_OPEN:
                debug("channel %d: output open -> drain", c->self);
@@ -314,7 +333,7 @@ chan_write_failed2(Channel *c)
        switch (c->ostate) {
        case CHAN_OUTPUT_OPEN:
                debug("channel %d: output open -> closed", c->self);
-               chan_shutdown_write(c); // ??
+               chan_shutdown_write(c); /* ?? */
                c->ostate = CHAN_OUTPUT_CLOSED;
                break;
        case CHAN_OUTPUT_WAIT_DRAIN:
index 0b5850a2d6c1bd236452a78925a3a356357a83e8..7bc6cada429e37b216747472066808bf4ef8699d 100644 (file)
--- a/packet.c
+++ b/packet.c
@@ -465,7 +465,7 @@ packet_send1()
        /* Compute packet length without padding (add checksum, remove padding). */
        len = buffer_len(&outgoing_packet) + 4 - 8;
 
-       /* Insert padding. */
+       /* Insert padding. Initialized to zero in packet_start1() */
        padding = 8 - len % 8;
        if (cipher_type != SSH_CIPHER_NONE) {
                cp = buffer_ptr(&outgoing_packet);
@@ -569,12 +569,16 @@ packet_send2()
                padlen += block_size;
        buffer_append_space(&outgoing_packet, &cp, padlen);
        if (enc && enc->type != SSH_CIPHER_NONE) {
+               /* random padding */
                for (i = 0; i < padlen; i++) {
                        if (i % 4 == 0)
                                rand = arc4random();
                        cp[i] = rand & 0xff;
                        rand <<= 8;
                }
+       } else {
+               /* clear padding */
+               memset(cp, 0, padlen);
        }
        /* packet_length includes payload, padding and padding length field */
        packet_length = buffer_len(&outgoing_packet) - 4;
@@ -657,10 +661,11 @@ packet_read(int *payload_len_ptr)
        for (;;) {
                /* Try to read a packet from the buffer. */
                type = packet_read_poll(payload_len_ptr);
-               if (type == SSH_SMSG_SUCCESS
+               if (!use_ssh2_packet_format && (
+                   type == SSH_SMSG_SUCCESS
                    || type == SSH_SMSG_FAILURE
                    || type == SSH_CMSG_EOF
-                   || type == SSH_CMSG_EXIT_CONFIRMATION)
+                   || type == SSH_CMSG_EXIT_CONFIRMATION))
                        packet_integrity_check(*payload_len_ptr, 0, type);
                /* If we got a packet, return it. */
                if (type != SSH_MSG_NONE)
diff --git a/radix.c b/radix.c
index 9d1c999a12becd13ebc4ac5fa5ec62183d23f559..033773344152c22aecfab56fb62bbd2b428021c0 100644 (file)
--- a/radix.c
+++ b/radix.c
@@ -69,7 +69,7 @@ typedef unsigned short my_u_short;
 
 
 int
-creds_to_radix(CREDENTIALS *creds, unsigned char *buf)
+creds_to_radix(CREDENTIALS *creds, unsigned char *buf, size_t buflen)
 {
        char *p, *s;
        int len;
@@ -119,7 +119,7 @@ creds_to_radix(CREDENTIALS *creds, unsigned char *buf)
        p += creds->ticket_st.length;
        len = p - temp;
 
-       return (uuencode((unsigned char *)temp, len, (char *)buf));
+       return (uuencode((unsigned char *)temp, len, (char *)buf, buflen));
 }
 
 int
@@ -131,7 +131,8 @@ radix_to_creds(const char *buf, CREDENTIALS *creds)
        char version;
        char temp[2048];
 
-       if (!(len = uudecode(buf, (unsigned char *)temp, sizeof(temp))))
+       len = uudecode(buf, (unsigned char *)temp, sizeof(temp));
+       if (len < 0)
                return 0;
 
        p = temp;
index 6c00cd6617f2ccf25374b6c2f749474cc66f4767..fdbd1e7d91db0129b75f21ec70c22441a89eb327 100644 (file)
@@ -105,7 +105,7 @@ typedef enum {
        oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
        oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
        oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2,
-       oGlobalKnownHostsFile2, oUserKnownHostsFile2
+       oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -121,6 +121,7 @@ static struct {
        { "rhostsauthentication", oRhostsAuthentication },
        { "passwordauthentication", oPasswordAuthentication },
        { "rsaauthentication", oRSAAuthentication },
+       { "dsaauthentication", oDSAAuthentication },
        { "skeyauthentication", oSkeyAuthentication },
 #ifdef KRB4
        { "kerberosauthentication", oKerberosAuthentication },
@@ -290,6 +291,10 @@ parse_flag:
                intptr = &options->password_authentication;
                goto parse_flag;
 
+       case oDSAAuthentication:
+               intptr = &options->dsa_authentication;
+               goto parse_flag;
+
        case oRSAAuthentication:
                intptr = &options->rsa_authentication;
                goto parse_flag;
@@ -637,6 +642,7 @@ initialize_options(Options * options)
        options->use_privileged_port = -1;
        options->rhosts_authentication = -1;
        options->rsa_authentication = -1;
+       options->dsa_authentication = -1;
        options->skey_authentication = -1;
 #ifdef KRB4
        options->kerberos_authentication = -1;
@@ -696,6 +702,8 @@ fill_default_options(Options * options)
                options->rhosts_authentication = 1;
        if (options->rsa_authentication == -1)
                options->rsa_authentication = 1;
+       if (options->dsa_authentication == -1)
+               options->dsa_authentication = 1;
        if (options->skey_authentication == -1)
                options->skey_authentication = 0;
 #ifdef KRB4
@@ -745,14 +753,12 @@ fill_default_options(Options * options)
                sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
                options->num_identity_files = 1;
        }
-#if 0
        if (options->num_identity_files2 == 0) {
                options->identity_files2[0] =
-                       xmalloc(2 + strlen(SSH2_CLIENT_IDENTITY) + 1);
-               sprintf(options->identity_files2[0], "~/%.100s", SSH2_CLIENT_IDENTITY);
+                       xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1);
+               sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA);
                options->num_identity_files2 = 1;
        }
-#endif
        if (options->escape_char == -1)
                options->escape_char = '~';
        if (options->system_hostfile == NULL)
index 7a6dcc815ed6d632e5e80753317d8d229fdba5bd..f3ebe359ec15c69cac6308d36ebb6a7fe8937b48 100644 (file)
@@ -36,6 +36,7 @@ typedef struct {
        int     rhosts_rsa_authentication;      /* Try rhosts with RSA
                                                 * authentication. */
        int     rsa_authentication;     /* Try RSA authentication. */
+       int     dsa_authentication;     /* Try DSA authentication. */
        int     skey_authentication;    /* Try S/Key or TIS authentication. */
 #ifdef KRB4
        int     kerberos_authentication;        /* Try Kerberos
diff --git a/scp.c b/scp.c
index e6da90a33dd355e3822ae56d8008a343573a8de1..df6a691e4f2e6381393be3b1684e630ef1d8fcff 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -573,7 +573,7 @@ next:                       (void) close(fd);
                        if (i + amt > stb.st_size)
                                amt = stb.st_size - i;
                        if (!haderr) {
-                               result = read(fd, bp->buf, amt);
+                               result = atomicio(read, fd, bp->buf, amt);
                                if (result != amt)
                                        haderr = result >= 0 ? EIO : errno;
                        }
@@ -692,12 +692,12 @@ sink(argc, argv)
                targisdir = 1;
        for (first = 1;; first = 0) {
                cp = buf;
-               if (read(remin, cp, 1) <= 0)
+               if (atomicio(read, remin, cp, 1) <= 0)
                        return;
                if (*cp++ == '\n')
                        SCREWUP("unexpected <newline>");
                do {
-                       if (read(remin, &ch, sizeof(ch)) != sizeof(ch))
+                       if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch))
                                SCREWUP("lost connection");
                        *cp++ = ch;
                } while (cp < &buf[sizeof(buf) - 1] && ch != '\n');
@@ -835,7 +835,7 @@ bad:                        run_err("%s: %s", np, strerror(errno));
                                amt = size - i;
                        count += amt;
                        do {
-                               j = read(remin, cp, amt);
+                               j = atomicio(read, remin, cp, amt);
                                if (j <= 0) {
                                        run_err("%s", j ? strerror(errno) :
                                                "dropped connection");
@@ -848,7 +848,7 @@ bad:                        run_err("%s: %s", np, strerror(errno));
                        if (count == bp->cnt) {
                                /* Keep reading so we stay sync'd up. */
                                if (wrerr == NO) {
-                                       j = write(ofd, bp->buf, count);
+                                       j = atomicio(write, ofd, bp->buf, count);
                                        if (j != count) {
                                                wrerr = YES;
                                                wrerrno = j >= 0 ? EIO : errno;
@@ -861,7 +861,7 @@ bad:                        run_err("%s: %s", np, strerror(errno));
                if (showprogress)
                        progressmeter(1);
                if (count != 0 && wrerr == NO &&
-                   (j = write(ofd, bp->buf, count)) != count) {
+                   (j = atomicio(write, ofd, bp->buf, count)) != count) {
                        wrerr = YES;
                        wrerrno = j >= 0 ? EIO : errno;
                }
@@ -913,7 +913,7 @@ response()
 {
        char ch, *cp, resp, rbuf[2048];
 
-       if (read(remin, &resp, sizeof(resp)) != sizeof(resp))
+       if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp))
                lostconn(0);
 
        cp = rbuf;
@@ -926,7 +926,7 @@ response()
        case 1:         /* error, followed by error msg */
        case 2:         /* fatal error, "" */
                do {
-                       if (read(remin, &ch, sizeof(ch)) != sizeof(ch))
+                       if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch))
                                lostconn(0);
                        *cp++ = ch;
                } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n');
index 8aeed3e3b00d99b6698ad8965e905125db19780b..36a7d1a133eb7fb9b8593e87a989f8e882c357ae 100644 (file)
@@ -32,7 +32,7 @@ initialize_server_options(ServerOptions *options)
        options->ports_from_cmdline = 0;
        options->listen_addrs = NULL;
        options->host_key_file = NULL;
-       options->dsa_key_file = NULL;
+       options->host_dsa_key_file = NULL;
        options->pid_file = NULL;
        options->server_key_bits = -1;
        options->login_grace_time = -1;
@@ -51,6 +51,7 @@ initialize_server_options(ServerOptions *options)
        options->rhosts_authentication = -1;
        options->rhosts_rsa_authentication = -1;
        options->rsa_authentication = -1;
+       options->dsa_authentication = -1;
 #ifdef KRB4
        options->kerberos_authentication = -1;
        options->kerberos_or_local_passwd = -1;
@@ -72,6 +73,7 @@ initialize_server_options(ServerOptions *options)
        options->num_deny_groups = 0;
        options->ciphers = NULL;
        options->protocol = SSH_PROTO_UNKNOWN;
+       options->gateway_ports = -1;
 }
 
 void
@@ -83,8 +85,8 @@ fill_default_server_options(ServerOptions *options)
                add_listen_addr(options, NULL);
        if (options->host_key_file == NULL)
                options->host_key_file = HOST_KEY_FILE;
-       if (options->dsa_key_file == NULL)
-               options->dsa_key_file = DSA_KEY_FILE;
+       if (options->host_dsa_key_file == NULL)
+               options->host_dsa_key_file = HOST_DSA_KEY_FILE;
        if (options->pid_file == NULL)
                options->pid_file = SSH_DAEMON_PID_FILE;
        if (options->server_key_bits == -1)
@@ -121,6 +123,8 @@ fill_default_server_options(ServerOptions *options)
                options->rhosts_rsa_authentication = 0;
        if (options->rsa_authentication == -1)
                options->rsa_authentication = 1;
+       if (options->dsa_authentication == -1)
+               options->dsa_authentication = 1;
 #ifdef KRB4
        if (options->kerberos_authentication == -1)
                options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
@@ -147,6 +151,8 @@ fill_default_server_options(ServerOptions *options)
                options->use_login = 0;
        if (options->protocol == SSH_PROTO_UNKNOWN)
                options->protocol = SSH_PROTO_1|SSH_PROTO_2;
+       if (options->gateway_ports == -1)
+               options->gateway_ports = 0;
 }
 
 #define WHITESPACE " \t\r\n"
@@ -170,7 +176,8 @@ typedef enum {
        sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
        sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
        sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
-       sIgnoreUserKnownHosts, sDSAKeyFile, sCiphers, sProtocol, sPidFile
+       sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
+       sGatewayPorts, sDSAAuthentication
 } ServerOpCodes;
 
 /* Textual representation of the tokens. */
@@ -180,7 +187,7 @@ static struct {
 } keywords[] = {
        { "port", sPort },
        { "hostkey", sHostKeyFile },
-       { "dsakey", sDSAKeyFile },
+       { "hostdsakey", sHostDSAKeyFile },
        { "pidfile", sPidFile },
        { "serverkeybits", sServerKeyBits },
        { "logingracetime", sLoginGraceTime },
@@ -191,6 +198,7 @@ static struct {
        { "rhostsauthentication", sRhostsAuthentication },
        { "rhostsrsaauthentication", sRhostsRSAAuthentication },
        { "rsaauthentication", sRSAAuthentication },
+       { "dsaauthentication", sDSAAuthentication },
 #ifdef KRB4
        { "kerberosauthentication", sKerberosAuthentication },
        { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
@@ -222,6 +230,7 @@ static struct {
        { "denygroups", sDenyGroups },
        { "ciphers", sCiphers },
        { "protocol", sProtocol },
+       { "gatewayports", sGatewayPorts },
        { NULL, 0 }
 };
 
@@ -353,9 +362,9 @@ parse_int:
                        break;
 
                case sHostKeyFile:
-               case sDSAKeyFile:
+               case sHostDSAKeyFile:
                        charptr = (opcode == sHostKeyFile ) ?
-                           &options->host_key_file : &options->dsa_key_file;
+                           &options->host_key_file : &options->host_dsa_key_file;
                        cp = strtok(NULL, WHITESPACE);
                        if (!cp) {
                                fprintf(stderr, "%s line %d: missing file name.\n",
@@ -445,6 +454,10 @@ parse_flag:
                        intptr = &options->rsa_authentication;
                        goto parse_flag;
 
+               case sDSAAuthentication:
+                       intptr = &options->dsa_authentication;
+                       goto parse_flag;
+
 #ifdef KRB4
                case sKerberosAuthentication:
                        intptr = &options->kerberos_authentication;
@@ -511,6 +524,10 @@ parse_flag:
                        intptr = &options->use_login;
                        goto parse_flag;
 
+               case sGatewayPorts:
+                       intptr = &options->gateway_ports;
+                       goto parse_flag;
+
                case sLogFacility:
                        intptr = (int *) &options->log_facility;
                        cp = strtok(NULL, WHITESPACE);
index f2b1779264db1217f13538b9f569a719528004cd..40ef05fbd4b7b2e952efb3ce938acb45f6cd6953 100644 (file)
@@ -32,7 +32,7 @@ typedef struct {
        char   *listen_addr;            /* Address on which the server listens. */
        struct addrinfo *listen_addrs;  /* Addresses on which the server listens. */
        char   *host_key_file;  /* File containing host key. */
-       char   *dsa_key_file;   /* File containing dsa host key. */
+       char   *host_dsa_key_file;      /* File containing dsa host key. */
        char   *pid_file;       /* Where to put our pid */
        int     server_key_bits;/* Size of the server key. */
        int     login_grace_time;       /* Disconnect if no auth in this time
@@ -51,6 +51,7 @@ typedef struct {
        int     keepalives;     /* If true, set SO_KEEPALIVE. */
        char   *ciphers;        /* Ciphers in order of preference. */
        int     protocol;       /* Protocol in order of preference. */
+       int     gateway_ports;  /* If true, allow remote connects to forwarded ports. */
        SyslogFacility log_facility;    /* Facility for system logging. */
        LogLevel log_level;     /* Level for system logging. */
        int     rhosts_authentication;  /* If true, permit rhosts
@@ -58,6 +59,7 @@ typedef struct {
        int     rhosts_rsa_authentication;      /* If true, permit rhosts RSA
                                                 * authentication. */
        int     rsa_authentication;     /* If true, permit RSA authentication. */
+       int     dsa_authentication;     /* If true, permit DSA authentication. */
 #ifdef KRB4
        int     kerberos_authentication;        /* If true, permit Kerberos
                                                 * authentication. */
index 1e031873c9dee1b740ac34a3b82adaec9969b805..1bc5d8b751455adbb76a0fb77ebb3a39c427ac48 100644 (file)
@@ -171,7 +171,7 @@ retry_select:
         * stdin or channel data.
         */
        if (compat20) {
-               // wrong: bad conditionXXX
+               /* wrong: bad condition XXX */
                if (channel_not_very_much_buffered_data())
                        FD_SET(connection_in, readset);
        } else {
index 0679d837cfd576a90277642b5723b69ebf18676f..c490f087ee92df341d62f95056a9e17f26220df7 100644 (file)
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.8 2000/04/29 16:06:08 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.12 2000/05/03 18:03:07 markus Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -57,6 +57,7 @@ struct Session {
 Session *session_new(void);
 void   session_set_fds(Session *s, int fdin, int fdout, int fderr);
 void   session_pty_cleanup(Session *s);
+void   session_proctitle(Session *s);
 void   do_exec_pty(Session *s, const char *command, struct passwd * pw);
 void   do_exec_no_pty(Session *s, const char *command, struct passwd * pw);
 
@@ -240,6 +241,8 @@ do_authenticated(struct passwd * pw)
                        tty_parse_modes(s->ttyfd, &n_bytes);
                        packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type);
 
+                       session_proctitle(s);
+
                        /* Indicate that we now have a pty. */
                        success = 1;
                        have_pty = 1;
@@ -312,7 +315,7 @@ do_authenticated(struct passwd * pw)
                                break;
                        }
                        debug("Received TCP/IP port forwarding request.");
-                       channel_input_port_forward_request(pw->pw_uid == 0);
+                       channel_input_port_forward_request(pw->pw_uid == 0, options.gateway_ports);
                        success = 1;
                        break;
 
@@ -397,7 +400,7 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw)
        if (s == NULL)
                fatal("do_exec_no_pty: no session");
 
-       setproctitle("%s@notty", pw->pw_name);
+       session_proctitle(s);
 
 #ifdef USE_PAM
                        do_pam_setcred();
@@ -527,7 +530,6 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
                last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
                                                      buf, sizeof(buf));
        }
-       setproctitle("%s@%s", pw->pw_name, strrchr(s->tty, '/') + 1);
 
 #ifdef USE_PAM
                        do_pam_session(pw->pw_name, s->tty);
@@ -563,7 +565,7 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
                /* Close the extra descriptor for the pseudo tty. */
                close(ttyfd);
 
-///XXXX ? move to do_child() ??
+/* XXXX ? move to do_child() ??*/
                /*
                 * Get IP address of client.  This is needed because we want
                 * to record where the user logged in from.  If the
@@ -1257,6 +1259,8 @@ session_pty_req(Session *s)
        /* Get window size from the packet. */
        pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
 
+       session_proctitle(s);
+
        /* XXX parse and set terminal modes */
        xfree(term_modes);
        return 1;
@@ -1499,6 +1503,7 @@ session_close(Session *s)
 {
        session_pty_cleanup(s);
        session_free(s);
+       session_proctitle(s);
 }
 
 void
@@ -1542,6 +1547,34 @@ session_close_by_channel(int id, void *arg)
        }
 }
 
+char *
+session_tty_list(void)
+{
+       static char buf[1024];
+       int i;
+       buf[0] = '\0';
+       for(i = 0; i < MAX_SESSIONS; i++) {
+               Session *s = &sessions[i];
+               if (s->used && s->ttyfd != -1) {
+                       if (buf[0] != '\0')
+                               strlcat(buf, ",", sizeof buf);
+                       strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf);
+               }
+       }
+       if (buf[0] == '\0')
+               strlcpy(buf, "notty", sizeof buf);
+       return buf;
+}
+
+void
+session_proctitle(Session *s)
+{
+       if (s->pw == NULL)
+               error("no user for session %d", s->self);
+       else
+               setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
+}
+
 void
 do_authenticated2(void)
 {
index eadf4fa0b267906052a1b0c3f86f9f87907bd088..5fe73a9c994465da4a81d13e83b35415feb58ce7 100644 (file)
--- a/ssh-add.1
+++ b/ssh-add.1
 .Os
 .Sh NAME
 .Nm ssh-add
-.Nd adds identities for the authentication agent
+.Nd adds RSA identities for the authentication agent
 .Sh SYNOPSIS
 .Nm ssh-add
 .Op Fl lLdD
 .Op Ar
 .Sh DESCRIPTION
 .Nm
-adds identities to the authentication agent,
+adds RSA identities to the authentication agent,
 .Xr ssh-agent 1 .
 When run without arguments, it adds the file
 .Pa $HOME/.ssh/identity .
index 68e6b84e12ade7bc18934f4f038287288ad47c39..66a47569248d7ec7ed2acb4cf260a8ddef33a76a 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-agent.1,v 1.11 2000/04/12 21:47:50 aaron Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.12 2000/05/03 18:04:39 markus Exp $
 .\"
 .\"  -*- nroff -*-
 .\"
@@ -27,7 +27,7 @@
 .Oc
 .Sh DESCRIPTION
 .Nm
-is a program to hold authentication private keys.
+is a program to hold private keys used for RSA authentication.
 The idea is that
 .Nm
 is started in the beginning of an X-session or a login session, and
index dfc404089a00bbf0fca9710fb571471bc9b7ed1c..200761f1e6c071037b6d3444103a0f7f81480bbe 100644 (file)
@@ -19,7 +19,7 @@
 .Nd authentication key generation
 .Sh SYNOPSIS
 .Nm ssh-keygen
-.Op Fl q
+.Op Fl dq
 .Op Fl b Ar bits
 .Op Fl N Ar new_passphrase
 .Op Fl C Ar comment
 .Op Fl N Ar new_passphrase
 .Op Fl f Ar keyfile
 .Nm ssh-keygen
+.Fl x
+.Op Fl f Ar keyfile
+.Nm ssh-keygen
+.Fl X
+.Op Fl f Ar keyfile
+.Nm ssh-keygen
+.Fl y
+.Op Fl f Ar keyfile
+.Nm ssh-keygen
 .Fl c
 .Op Fl P Ar passphrase
 .Op Fl C Ar comment
 .Nm
 generates and manages authentication keys for
 .Xr ssh 1 .
+.Nm
+defaults to generating an RSA key for use by protocols 1.3 and 1.5;
+specifying the
+.Fl d
+flag will create a DSA key instead for use by protocol 2.0.
+.Pp
 Normally each user wishing to use SSH
-with RSA authentication runs this once to create the authentication
+with RSA or DSA authentication runs this once to create the authentication
 key in
-.Pa $HOME/.ssh/identity .
-Additionally, the system administrator may use this to generate host keys.
+.Pa $HOME/.ssh/identity
+or
+.Pa $HOME/.ssh/id_dsa .
+Additionally, the system administrator may use this to generate host keys,
+as seen in
+.Pa /etc/rc .
 .Pp
 Normally this program generates the key and asks for a file in which
 to store the private key.
@@ -71,7 +90,7 @@ If the passphrase is
 lost or forgotten, you will have to generate a new key and copy the
 corresponding public key to other machines.
 .Pp
-There is also a comment field in the key file that is only for
+For RSA, there is also a comment field in the key file that is only for
 convenience to the user to help identify the key.
 The comment can tell what the key is for, or whatever is useful.
 The comment is initialized to
@@ -80,6 +99,9 @@ when the key is created, but can be changed using the
 .Fl c
 option.
 .Pp
+After a key is generated, instructions below detail where the keys
+should be placed to be activated.
+.Pp
 The options are as follows:
 .Bl -tag -width Ds
 .It Fl b Ar bits
@@ -118,6 +140,15 @@ Provides the (old) passphrase.
 If RSA support is functional, immediately exits with code 0.  If RSA
 support is not functional, exits with code 1.  This flag will be
 removed once the RSA patent expires.
+.It Fl x
+This option will read a private
+OpenSSH DSA format file and prints to stdout a SSH2-compatible public key.
+.It Fl X
+This option will read a
+SSH2-compatible public key file and print to stdout an OpenSSH DSA compatible public key.
+.It Fl y
+This option will read a private
+OpenSSH DSA format file and prints to stdout an OpenSSH DSA public key.
 .El
 .Sh FILES
 .Bl -tag -width Ds
@@ -130,6 +161,8 @@ used to encrypt the private part of this file using 3DES.
 This file is not automatically accessed by
 .Nm
 but it is offered as the default file for the private key.
+.Xr sshd 8
+will read this file when a login attempt is made.
 .It Pa $HOME/.ssh/identity.pub
 Contains the public key for authentication.
 The contents of this file should be added to
@@ -137,6 +170,24 @@ The contents of this file should be added to
 on all machines
 where you wish to log in using RSA authentication.
 There is no need to keep the contents of this file secret.
+.It Pa $HOME/.ssh/id_dsa
+Contains the DSA authentication identity of the user.
+This file should not be readable by anyone but the user.
+It is possible to
+specify a passphrase when generating the key; that passphrase will be
+used to encrypt the private part of this file using 3DES.
+This file is not automatically accessed by
+.Nm
+but it is offered as the default file for the private key.
+.Xr sshd 8
+will read this file when a login attempt is made.
+.It Pa $HOME/.ssh/id_dsa.pub
+Contains the public key for authentication.
+The contents of this file should be added to
+.Pa $HOME/.ssh/authorized_keys2
+on all machines
+where you wish to log in using DSA authentication.
+There is no need to keep the contents of this file secret.
 .Sh AUTHOR
 Tatu Ylonen <ylo@cs.hut.fi>
 .Pp
index e3337dd6405a88e1c3a44d604ccae6fb66cd790d..9beb653d45aab7f66283cc527172779e6a62c3bf 100644 (file)
@@ -76,7 +76,8 @@ ask_filename(struct passwd *pw, const char *prompt)
 {
        char buf[1024];
        snprintf(identity_file, sizeof(identity_file), "%s/%s",
-                pw->pw_dir, SSH_CLIENT_IDENTITY);
+           pw->pw_dir,
+           dsa_mode ? SSH_CLIENT_ID_DSA: SSH_CLIENT_IDENTITY);
        printf("%s (%s): ", prompt, identity_file);
        fflush(stdout);
        if (fgets(buf, sizeof(buf), stdin) == NULL)
@@ -491,8 +492,7 @@ do_change_comment(struct passwd *pw)
 void
 usage(void)
 {
-       printf("ssh-keygen version %s\n", SSH_VERSION);
-       printf("Usage: %s [-b bits] [-c] [-d] [-f file] [-l] [-p] [-q] [-x] [-y] [-C comment] [-N new-pass] [-P pass] [-X]\n", __progname);
+       printf("Usage: %s [-lpqxXydc] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname);
        exit(1);
 }
 
diff --git a/ssh.1 b/ssh.1
index b7be8dae615cc0b2df0d5e0f915dce4fb7f20945..662e4082ed76d740a7f6d104928a4b12d066a7aa 100644 (file)
--- a/ssh.1
+++ b/ssh.1
@@ -63,7 +63,10 @@ arbitrary TCP/IP ports can also be forwarded over the secure channel.
 connects and logs into the specified
 .Ar hostname .
 The user must prove
-his/her identity to the remote machine using one of several methods.
+his/her identity to the remote machine using one of several methods
+depending on the protocol version used:
+.Pp
+.Ss SSH protocol version 1
 .Pp
 First, if the machine the user logs in from is listed in
 .Pa /etc/hosts.equiv
@@ -88,8 +91,8 @@ or
 .Pa hosts.equiv
 method combined with RSA-based host authentication.
 It means that if the login would be permitted by
-.Pa \&.rhosts ,
-.Pa \&.shosts ,
+.Pa $HOME/.rhosts ,
+.Pa $HOME/.shosts ,
 .Pa /etc/hosts.equiv ,
 or
 .Pa /etc/shosts.equiv ,
@@ -105,7 +108,7 @@ This authentication method closes security holes due to IP
 spoofing, DNS spoofing and routing spoofing.
 [Note to the administrator:
 .Pa /etc/hosts.equiv ,
-.Pa \&.rhosts ,
+.Pa $HOME/.rhosts ,
 and the rlogin/rsh protocol in general, are inherently insecure and should be
 disabled if security is desired.]
 .Pp
@@ -143,18 +146,18 @@ implements the RSA authentication protocol automatically.
 The user creates his/her RSA key pair by running
 .Xr ssh-keygen 1 .
 This stores the private key in
-.Pa \&.ssh/identity
+.Pa $HOME/.ssh/identity
 and the public key in
-.Pa \&.ssh/identity.pub
+.Pa $HOME/.ssh/identity.pub
 in the user's home directory.
 The user should then copy the
 .Pa identity.pub
 to
-.Pa \&.ssh/authorized_keys
+.Pa $HOME/.ssh/authorized_keys
 in his/her home directory on the remote machine (the
 .Pa authorized_keys
 file corresponds to the conventional
-.Pa \&.rhosts
+.Pa $HOME/.rhosts
 file, and has one key
 per line, though the lines can be very long).
 After this, the user can log in without giving the password.
@@ -174,6 +177,38 @@ The password is sent to the remote
 host for checking; however, since all communications are encrypted,
 the password cannot be seen by someone listening on the network.
 .Pp
+.Ss SSH protocol version 2
+.Pp
+When a user connects using the protocol version 2
+different authentication methods are available:
+At first, the client attempts to authenticate using the public key method.
+If this method fails password authentication is tried.
+.Pp
+The public key method is similar to RSA authentication described
+in the previous section except that the DSA algorithm is used
+instead of the patented RSA algorithm.
+The client uses his private DSA key
+.Pa $HOME/.ssh/id_dsa
+to sign the session identifier and sends the result to the server.
+The server checks whether the matching public key is listed in
+.Pa $HOME/.ssh/authorized_keys2
+and grants access if both the key is found and the signature is correct.
+The session identifier is derived from a shared Diffie-Hellman value
+and is only known to the client and the server.
+.Pp
+If public key authentication fails or is not available a password
+can be sent encrypted to the remote host for proving the user's identity.
+This protocol 2 implementation does not yet support Kerberos or
+S/Key authentication.
+.Pp
+Protocol 2 provides additional mechanisms for confidentiality
+(the traffic is encrypted using 3DES, blowfish, cast128 or arcfour)
+and integrity (hmac-sha1, hmac-md5).
+Note that protocol 1 lacks a strong mechanism for ensuring the
+integrity of the connection.
+.Pp
+.Ss Login session and remote execution
+.Pp
 When the user's identity has been accepted by the server, the server
 either executes the given command, or logs into the machine and gives
 the user a normal shell on the remote machine.
@@ -219,6 +254,8 @@ The exit status of the remote program is returned as the exit status
 of
 .Nm ssh .
 .Pp
+.Ss X11 and TCP forwarding
+.Pp
 If the user is using X11 (the
 .Ev DISPLAY
 environment variable is set), the connection to the X11 display is
@@ -262,15 +299,22 @@ be specified either on command line or in a configuration file.
 One possible application of TCP/IP forwarding is a secure connection to an
 electronic purse; another is going trough firewalls.
 .Pp
+.Ss Server authentication
+.Pp
 .Nm
-automatically maintains and checks a database containing RSA-based
+automatically maintains and checks a database containing
 identifications for all hosts it has ever been used with.
-The database is stored in
-.Pa \&.ssh/known_hosts
+RSA host keys are stored in
+.Pa $HOME/.ssh/known_hosts
+and
+DSA host keys are stored in
+.Pa $HOME/.ssh/known_hosts2
 in the user's home directory.
-Additionally, the file
+Additionally, the files
 .Pa /etc/ssh_known_hosts
-is automatically checked for known hosts.
+and
+.Pa /etc/ssh_known_hosts2
+are automatically checked for known hosts.
 Any new hosts are automatically added to the user's file.
 If a host's identification
 ever changes,
@@ -333,7 +377,7 @@ Allows remote hosts to connect to local forwarded ports.
 Selects the file from which the identity (private key) for
 RSA authentication is read.
 Default is
-.Pa \&.ssh/identity
+.Pa $HOME/.ssh/identity
 in the user's home directory.
 Identity files may also be specified on
 a per-host basis in the configuration file.
@@ -458,7 +502,7 @@ logging in as root on the remote machine.
 .It Fl 2
 Forces
 .Nm
-to use protocol version 2 only.
+to try protocol version 2 only.
 .It Fl 4
 Forces
 .Nm
@@ -575,6 +619,15 @@ Specifies the number of tries (one per second) to make before falling
 back to rsh or exiting.
 The argument must be an integer.
 This may be useful in scripts if the connection sometimes fails.
+.It Cm DSAAuthentication
+Specifies whether to try DSA authentication.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+DSA authentication will only be
+attempted if a DSA identity file exists.
+Note that this option applies to protocol version 2 only.
 .It Cm EscapeChar
 Sets the escape character (default:
 .Ql ~ ) .
@@ -640,7 +693,7 @@ specifications).
 .It Cm IdentityFile
 Specifies the file from which the user's RSA authentication identity
 is read (default
-.Pa .ssh/identity
+.Pa $HOME/.ssh/identity
 in the user's home directory).
 Additionally, any identities represented by the authentication agent
 will be used for authentication.
@@ -649,6 +702,16 @@ syntax to refer to a user's home directory.
 It is possible to have
 multiple identity files specified in configuration files; all these
 identities will be tried in sequence.
+.It Cm IdentityFile2
+Specifies the file from which the user's DSA authentication identity
+is read (default
+.Pa $HOME/.ssh/id_dsa
+in the user's home directory).
+The file name may use the tilde
+syntax to refer to a user's home directory.
+It is possible to have
+multiple identity files specified in configuration files; all these
+identities will be tried in sequence.
 .It Cm KeepAlive
 Specifies whether the system should send keepalive messages to the
 other side.
@@ -704,6 +767,7 @@ The argument to this keyword must be
 .Dq yes
 or
 .Dq no .
+Note that this option applies to both protocol version 1 and 2.
 .It Cm Port
 Specifies the port number to connect on the remote host.
 Default is 22.
@@ -717,7 +781,11 @@ and
 .Dq 2 .
 Multiple versions must be comma-separated.
 The default is
-.Dq 1 .
+.Dq 1,2 .
+This means that
+.Nm
+tries version 1 and falls back to version 2
+if version 1 is no available.
 .It Cm ProxyCommand
 Specifies the command to use to connect to the server.
 The command
@@ -782,6 +850,7 @@ or
 RSA authentication will only be
 attempted if the identity file exists, or an authentication agent is
 running.
+Note that this option applies to protocol version 1 only.
 .It Cm SkeyAuthentication
 Specifies whether to use
 .Xr skey 1
@@ -798,10 +867,14 @@ If this flag is set to
 .Nm
 ssh will never automatically add host keys to the
 .Pa $HOME/.ssh/known_hosts
-file, and refuses to connect hosts whose host key has changed.
+and
+.Pa $HOME/.ssh/known_hosts2
+files, and refuses to connect hosts whose host key has changed.
 This provides maximum protection against trojan horse attacks.
 However, it can be somewhat annoying if you don't have good
 .Pa /etc/ssh_known_hosts
+and
+.Pa /etc/ssh_known_hosts2
 files installed and frequently
 connect new hosts.
 Basically this option forces the user to manually
@@ -921,28 +994,36 @@ in
 .Pa /etc/ssh_known_hosts ) .
 See
 .Xr sshd 8 .
-.It Pa $HOME/.ssh/identity
-Contains the RSA authentication identity of the user.
-This file
-contains sensitive data and should be readable by the user but not
+.It Pa $HOME/.ssh/identity, $HOME/.ssh/id_dsa
+Contains the RSA and the DSA authentication identity of the user.
+These files
+contain sensitive data and should be readable by the user but not
 accessible by others (read/write/execute).
 Note that
 .Nm
-ignores this file if it is accessible by others.
+ignores a private key file if it is accessible by others.
 It is possible to specify a passphrase when
 generating the key; the passphrase will be used to encrypt the
 sensitive part of this file using 3DES.
-.It Pa $HOME/.ssh/identity.pub
+.It Pa $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub
 Contains the public key for authentication (public part of the
 identity file in human-readable form).
-The contents of this file should be added to
+The contents of the
+.Pa $HOME/.ssh/identity.pub
+file should be added to
 .Pa $HOME/.ssh/authorized_keys
 on all machines
 where you wish to log in using RSA authentication.
-This file is not
+The contents of the
+.Pa $HOME/.ssh/id_dsa.pub
+file should be added to
+.Pa $HOME/.ssh/authorized_keys2
+on all machines
+where you wish to log in using DSA authentication.
+These files are not
 sensitive and can (but need not) be readable by anyone.
-This file is
-never used automatically and is not necessary; it is only provided for
+These files are
+never used automatically and are not necessary; they is only provided for
 the convenience of the user.
 .It Pa $HOME/.ssh/config
 This is the per-user configuration file.
@@ -964,9 +1045,17 @@ modulus, public exponent, modulus, and comment fields, separated by
 spaces).
 This file is not highly sensitive, but the recommended
 permissions are read/write for the user, and not accessible by others.
-.It Pa /etc/ssh_known_hosts
+.It Pa $HOME/.ssh/authorized_keys2
+Lists the DSA keys that can be used for logging in as this user.
+This file is not highly sensitive, but the recommended
+permissions are read/write for the user, and not accessible by others.
+.It Pa /etc/ssh_known_hosts, /etc/ssh_known_hosts2
 Systemwide list of known host keys.
-This file should be prepared by the
+.Pa /etc/ssh_known_hosts
+contains RSA and
+.Pa /etc/ssh_known_hosts2
+contains DSA keys.
+These files should be prepared by the
 system administrator to contain the public host keys of all machines in the
 organization.
 This file should be world-readable.
@@ -1025,7 +1114,7 @@ you can store it in
 .Pa $HOME/.ssh/known_hosts .
 The easiest way to do this is to
 connect back to the client from the server machine using ssh; this
-will automatically add the host key inxi
+will automatically add the host key to
 .Pa $HOME/.ssh/known_hosts .
 .It Pa $HOME/.shosts
 This file is used exactly the same way as
@@ -1086,6 +1175,7 @@ but with bugs removed and newer features re-added.
 Rapidly after the
 1.2.12 release, newer versions of the original ssh bore successively
 more restrictive licenses, and thus demand for a free version was born.
+.Pp
 This version of OpenSSH
 .Bl -bullet
 .It
@@ -1094,8 +1184,8 @@ directly removed from the source code; any licensed or patented components
 are chosen from
 external libraries.
 .It
-has been updated to support ssh protocol 1.5, making it compatible with
-all other ssh protocol 1 clients and servers.
+has been updated to support SSH protocol 1.5 and 2, making it compatible with
+all other SSH clients and servers.
 .It
 contains added support for
 .Xr kerberos 8
@@ -1107,6 +1197,8 @@ supports one-time password authentication with
 .Pp
 OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl,
 Niels Provos, Theo de Raadt, and Dug Song.
+.Pp
+The support for SSH protocol 2 was written by Markus Friedl.
 .Sh SEE ALSO
 .Xr rlogin 1 ,
 .Xr rsh 1 ,
diff --git a/ssh.h b/ssh.h
index a5c229d7156133354ee953b0df0ad60f35715c85..afc652726278403682a158658affd272195ee35e 100644 (file)
--- a/ssh.h
+++ b/ssh.h
@@ -97,7 +97,7 @@
 #define HOST_KEY_FILE          ETCDIR "/ssh_host_key"
 #define SERVER_CONFIG_FILE     ETCDIR "/sshd_config"
 #define HOST_CONFIG_FILE       ETCDIR "/ssh_config"
-#define DSA_KEY_FILE           ETCDIR "/ssh_host_dsa_key"
+#define HOST_DSA_KEY_FILE      ETCDIR "/ssh_host_dsa_key"
 
 #ifndef SSH_PROGRAM
 #define SSH_PROGRAM                    "/usr/bin/ssh"
  * file should only be readable by the user him/herself.
  */
 #define SSH_CLIENT_IDENTITY    ".ssh/identity"
+#define SSH_CLIENT_ID_DSA      ".ssh/id_dsa"
 
 /*
  * Configuration file in user\'s home directory.  This file need not be
@@ -527,7 +528,7 @@ int auth_krb4_password(struct passwd * pw, const char *password);
 int     auth_kerberos_tgt(struct passwd * pw, const char *string);
 int     auth_afs_token(struct passwd * pw, const char *token_string);
 
-int     creds_to_radix(CREDENTIALS * creds, unsigned char *buf);
+int     creds_to_radix(CREDENTIALS * creds, unsigned char *buf, size_t buflen);
 int     radix_to_creds(const char *buf, CREDENTIALS * creds);
 #endif                         /* AFS */
 
index 859450d36c49d14f87c638e48db043d7cc7ebbec..9b25d7c2084b70edc97342b03ad7ee4c55d84007 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.71 2000/04/26 21:28:33 markus Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.72 2000/05/04 09:50:22 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/dsa.h>
@@ -465,6 +465,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
        const char *user_hostfile, const char *system_hostfile)
 {
        Key *file_key;
+       char *type = key_type(host_key);
        char *ip = NULL;
        char hostline[1000], *hostp;
        HostStatus host_status;
@@ -551,18 +552,19 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
        switch (host_status) {
        case HOST_OK:
                /* The host is known and the key matches. */
-               debug("Host '%.200s' is known and matches the host key.", host);
+               debug("Host '%.200s' is known and matches the %s host key.",
+                   host, type);
                if (options.check_host_ip) {
                        if (ip_status == HOST_NEW) {
                                if (!add_host_to_hostfile(user_hostfile, ip, host_key))
-                                       log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).",
-                                           ip, user_hostfile);
+                                       log("Failed to add the %s host key for IP address '%.30s' to the list of known hosts (%.30s).",
+                                           type, ip, user_hostfile);
                                else
-                                       log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.",
-                                           ip);
+                                       log("Warning: Permanently added the %s host key for IP address '%.30s' to the list of known hosts.",
+                                           type, ip);
                        } else if (ip_status != HOST_OK)
-                               log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'",
-                                   host, ip);
+                               log("Warning: the %s host key for '%.200s' differs from the key for the IP address '%.30s'",
+                                   type, host, ip);
                }
                break;
        case HOST_NEW:
@@ -570,16 +572,16 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                if (options.strict_host_key_checking == 1) {
                        /* User has requested strict host key checking.  We will not add the host key
                           automatically.  The only alternative left is to abort. */
-                       fatal("No host key is known for %.200s and you have requested strict checking.", host);
+                       fatal("No %s host key is known for %.200s and you have requested strict checking.", type, host);
                } else if (options.strict_host_key_checking == 2) {
                        /* The default */
                        char prompt[1024];
                        char *fp = key_fingerprint(host_key);
                        snprintf(prompt, sizeof(prompt),
                            "The authenticity of host '%.200s' can't be established.\n"
-                           "Key fingerprint is %s.\n"
+                           "%s key fingerprint is %s.\n"
                            "Are you sure you want to continue connecting (yes/no)? ",
-                           host, fp);
+                           host, type, fp);
                        if (!read_yes_or_no(prompt, -1))
                                fatal("Aborted by user!\n");
                }
@@ -594,8 +596,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                        log("Failed to add the host to the list of known hosts (%.500s).",
                            user_hostfile);
                else
-                       log("Warning: Permanently added '%.200s' to the list of known hosts.",
-                           hostp);
+                       log("Warning: Permanently added '%.200s' (%s) to the list of known hosts.",
+                           hostp, type);
                break;
        case HOST_CHANGED:
                if (options.check_host_ip && host_ip_differ) {
@@ -609,7 +611,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                        error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                        error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
                        error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
-                       error("The host key for %s has changed,", host);
+                       error("The %s host key for %s has changed,", type, host);
                        error("and the key for the according IP address %s", ip);
                        error("%s. This could either mean that", msg);
                        error("DNS SPOOFING is happening or the IP address for the host");
@@ -621,7 +623,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
                error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
-               error("It is also possible that the host key has just been changed.");
+               error("It is also possible that the %s host key has just been changed.", type);
                error("Please contact your system administrator.");
                error("Add correct host key in %.100s to get rid of this message.",
                      user_hostfile);
@@ -631,7 +633,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                 * to edit the key manually and we can only abort.
                 */
                if (options.strict_host_key_checking)
-                       fatal("Host key for %.200s has changed and you have requested strict checking.", host);
+                       fatal("%s host key for %.200s has changed and you have requested strict checking.", type, host);
 
                /*
                 * If strict host key checking has not been requested, allow
index c5a76654bc6123d5063e8c19a5cb28efb49ebeee..31ee9843cdecce7a6747d44fb105fa2317817554 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect1.c,v 1.1 2000/04/26 21:28:33 markus Exp $");
+RCSID("$OpenBSD: sshconnect1.c,v 1.2 2000/05/04 22:38:00 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/dsa.h>
@@ -505,7 +505,7 @@ send_kerberos_tgt()
                debug("Kerberos V4 ticket expired: %s", TKT_FILE);
                return 0;
        }
-       creds_to_radix(creds, (unsigned char *)buffer);
+       creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer);
        xfree(creds);
 
        packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
@@ -573,7 +573,7 @@ send_afs_tokens(void)
                creds.pinst[0] = '\0';
 
                /* Encode token, ship it off. */
-               if (!creds_to_radix(&creds, (unsigned char*) buffer))
+               if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0)
                        break;
                packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
                packet_put_string(buffer, strlen(buffer));
index a4342e2df08727d31e7ef59bb01745e1f18effd3..17325b097ff5d5b1638ec0f1ec0581f0d16e2cab 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.5 2000/05/01 18:41:06 markus Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.7 2000/05/06 17:45:37 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
@@ -283,9 +283,13 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 int
 ssh2_try_passwd(const char *server_user, const char *host, const char *service)
 {
+       static int attempt = 0;
        char prompt[80];
        char *password;
 
+       if (attempt++ > options.number_of_password_prompts)
+               return 0;
+
        snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
            server_user, host);
        password = read_passphrase(prompt, 0);
@@ -428,7 +432,7 @@ ssh_userauth2(const char *server_user, char *host)
                packet_done();
                if (partial)
                        debug("partial success");
-               if (options.rsa_authentication &&
+               if (options.dsa_authentication &&
                    strstr(auths, "publickey") != NULL) {
                        while (i < options.num_identity_files2) {
                                sent = ssh2_try_pubkey(
diff --git a/sshd.8 b/sshd.8
index 5043403bdb3ab0b009e6e802ca5dd2846287e142..b526827c54ed6fa26fe0e26b73d28927862c8990 100644 (file)
--- a/sshd.8
+++ b/sshd.8
@@ -46,9 +46,14 @@ daemon for each incoming connection.
 The forked daemons handle
 key exchange, encryption, authentication, command execution,
 and data exchange.
-.Pp
+This implementation of
+.Nm
+supports both SSH protocol version 1 and 2 simultaneously.
 .Nm
 works as follows.
+.Pp
+.Ss SSH protocol version 1
+.Pp
 Each host has a host-specific RSA key
 (normally 1024 bits) used to identify the host.
 Additionally, when
@@ -59,7 +64,7 @@ is never stored on disk.
 Whenever a client connects the daemon responds with its public
 host and server keys.
 The client compares the
-host key against its own database to verify that it has not changed.
+RSA host key against its own database to verify that it has not changed.
 The client then generates a 256 bit random number.
 It encrypts this
 random number using both the host key and the server key, and sends
@@ -97,6 +102,28 @@ and
 .Xr rsh 1
 into the machine).
 .Pp
+.Ss SSH protocol version 2
+.Pp
+Version 2 works similar:
+Each host has a host-specific DSA key used to identify the host.
+However, when the daemon starts, it does not generate a server key.
+Forward security is provided through a Diffie-Hellman key agreement.
+This key agreement results in a shared session key.
+The rest of the session is encrypted
+using a symmetric cipher, currently
+Blowfish, 3DES or CAST128 in CBC mode or Arcfour.
+The client selects the encryption algorithm
+to use from those offered by the server.
+Additionally, session integrity is provided
+through a crytographic message authentication code
+(hmac-sha1 or hmac-md5).
+.Pp
+Protocol version 2 provides a public key based
+user authentication method (DSAAuthentication)
+and conventional password authentication.
+.Pp
+.Ss Command execution and data forwarding
+.Pp
 If the client successfully authenticates itself, a dialog for
 preparing the session is entered.
 At this time the client may request
@@ -148,7 +175,7 @@ If the client fails to authenticate the user within
 this many seconds, the server disconnects and exits.
 A value of zero indicates no limit.
 .It Fl h Ar host_key_file
-Specifies the file from which the host key is read (default
+Specifies the file from which the RSA host key is read (default
 .Pa /etc/ssh_host_key ) .
 This option must be given if
 .Nm
@@ -280,12 +307,34 @@ and
 can be used as wildcards in the patterns.
 Only user names are valid, a numerical user ID isn't recognized.
 By default login is allowed regardless of the user name.
+.It Cm DSAAuthentication
+Specifies whether DSA authentication is allowed.
+The default is
+.Dq yes .
+Note that this option applies to protocol version 2 only.
+.It Cm GatewayPorts
+Specifies whether remote hosts are allowed to connect to ports
+forwarded for the client.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+.It Cm HostDsaKey
+Specifies the file containing the private DSA host key (default
+.Pa /etc/ssh_host_dsa_key )
+used by SSH protocol 2.0.
+Note that
+.Nm
+disables protcol 2.0 if this file is group/world-accessible.
 .It Cm HostKey
-Specifies the file containing the private host key (default
-.Pa /etc/ssh_host_key ) .
+Specifies the file containing the private RSA host key (default
+.Pa /etc/ssh_host_key )
+used by SSH protocols 1.3 and 1.5.
 Note that
 .Nm
-does not start if this file is group/world-accessible.
+disables protcols 1.3 and 1.5 if this file is group/world-accessible.
 .It Cm IgnoreRhosts
 Specifies that
 .Pa .rhosts
@@ -390,6 +439,7 @@ and is not recommended.
 Specifies whether password authentication is allowed.
 The default is
 .Dq yes .
+Note that this option applies to both protocol version 1 and 2.
 .It Cm PermitEmptyPasswords
 When password authentication is allowed, it specifies whether the
 server allows login to accounts with empty password strings.
@@ -471,6 +521,7 @@ The default is
 Specifies whether pure RSA authentication is allowed.
 The default is
 .Dq yes .
+Note that this option applies to protocol version 1 only.
 .It Cm ServerKeyBits
 Defines the number of bits in the server key.
 The minimum value is 512, and the default is 768.
@@ -568,7 +619,11 @@ Runs user's shell or command.
 The
 .Pa $HOME/.ssh/authorized_keys
 file lists the RSA keys that are
-permitted for RSA authentication.
+permitted for RSA authentication in SSH protocols 1.3 and 1.5
+Similarily, the
+.Pa $HOME/.ssh/authorized_keys2
+file lists the DSA keys that are
+permitted for DSA authentication in SSH protocol 2.0.
 Each line of the file contains one
 key (empty lines and lines starting with a
 .Ql #
@@ -655,9 +710,11 @@ from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23.\|.\|.\|2334 ylo@niksula
 command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hut.fi
 .Sh SSH_KNOWN_HOSTS FILE FORMAT
 The
-.Pa /etc/ssh_known_hosts
+.Pa /etc/ssh_known_hosts ,
+.Pa /etc/ssh_known_hosts2 ,
+.Pa $HOME/.ssh/known_hosts ,
 and
-.Pa $HOME/.ssh/known_hosts
+.Pa $HOME/.ssh/known_hosts2
 files contain host public keys for all known hosts.
 The global file should
 be prepared by the administrator (optional), and the per-user file is
@@ -678,7 +735,7 @@ to indicate negation: if the host name matches a negated
 pattern, it is not accepted (by that line) even if it matched another
 pattern on the line.
 .Pp
-Bits, exponent, and modulus are taken directly from the host key; they
+Bits, exponent, and modulus are taken directly from the RSA host key; they
 can be obtained, e.g., from
 .Pa /etc/ssh_host_key.pub .
 The optional comment field continues to the end of the line, and is not used.
@@ -744,6 +801,21 @@ it being world-readable if the user's home directory resides on an NFS
 volume).
 It is recommended that it not be accessible by others.
 The format of this file is described above.
+Users will place the contents of their
+.Pa identity.pub
+files into this file, as described in
+.Xr ssh-keygen 1 .
+.It Pa $HOME/.ssh/authorized_keys2
+Lists the DSA keys that can be used to log into the user's account.
+This file must be readable by root (which may on some machines imply
+it being world-readable if the user's home directory resides on an NFS
+volume).
+It is recommended that it not be accessible by others.
+The format of this file is described above.
+Users will place the contents of their
+.Pa id_dsa.pub
+files into this file, as described in
+.Xr ssh-keygen 1 .
 .It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts"
 These files are consulted when using rhosts with RSA host
 authentication to check the public key of the host.
@@ -875,6 +947,7 @@ but with bugs removed and newer features re-added.
 Rapidly after the
 1.2.12 release, newer versions of the original ssh bore successively
 more restrictive licenses, and thus demand for a free version was born.
+.Pp
 This version of OpenSSH
 .Bl -bullet
 .It
@@ -883,8 +956,8 @@ directly removed from the source code; any licensed or patented components
 are chosen from
 external libraries.
 .It
-has been updated to support ssh protocol 1.5, making it compatible with
-all other ssh protocol 1 clients and servers.
+has been updated to support SSH protocol 1.5 and 2, making it compatible with
+all other SSH clients and servers.
 .It
 contains added support for
 .Xr kerberos 8
@@ -893,6 +966,11 @@ authentication and ticket passing.
 supports one-time password authentication with
 .Xr skey 1 .
 .El
+.Pp
+OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl,
+Niels Provos, Theo de Raadt, and Dug Song.
+.Pp
+The support for SSH protocol 2 was written by Markus Friedl.
 .Sh SEE ALSO
 .Xr scp 1 ,
 .Xr ssh 1 ,
diff --git a/sshd.c b/sshd.c
index 70f292cc71944ffd6482673422cbfdb16bbcdc75..d1ed1506e41113e318d516a66ab7c97ab888b089 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -14,7 +14,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.113 2000/05/01 20:34:51 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.115 2000/05/03 10:21:49 markus Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -562,8 +562,9 @@ main(int ac, char **av)
        }
        if (options.protocol & SSH_PROTO_2) {
                sensitive_data.dsa_host_key = key_new(KEY_DSA);
-               if (!load_private_key(options.dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) {
-                       error("Could not load DSA host key: %.200s", options.dsa_key_file);
+               if (!load_private_key(options.host_dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) {
+
+                       error("Could not load DSA host key: %.200s", options.host_dsa_key_file);
                        log("Disabling protocol version 2");
                        options.protocol &= ~SSH_PROTO_2;
                }
@@ -1320,7 +1321,7 @@ do_ssh2_kex()
        /* send server hostkey, DH pubkey 'f' and singed H */
        packet_start(SSH2_MSG_KEXDH_REPLY);
        packet_put_string((char *)server_host_key_blob, sbloblen);
-       packet_put_bignum2(dh->pub_key);        // f
+       packet_put_bignum2(dh->pub_key);        /* f */
        packet_put_string((char *)signature, slen);
        packet_send();
        xfree(signature);
index 62689005090a997ea74a6a5a26cd8783c75e644d..fc84d5a5830b591b5ea192542eb341fedfe1eb00 100644 (file)
 /*
- *   base-64 encoding pinched from lynx2-7-2, who pinched it from rpem.
- *   Originally written by Mark Riordan 12 August 1990 and 17 Feb 1991
- *   and placed in the public domain.
- *
- *   Dug Song <dugsong@UMICH.EDU>
+ * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  */
-
 #include "includes.h"
 #include "xmalloc.h"
 
-char six2pr[64] = {
-       'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
-       'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
-       'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
-       'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-       '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
-};
-
-unsigned char pr2six[256];
+#include <resolv.h>
 
 int
-uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded)
+uuencode(unsigned char *src, unsigned int srclength,
+    char *target, size_t targsize)
 {
-       /* ENC is the basic 1 character encoding function to make a char printing */
-#define ENC(c) six2pr[c]
-
-       register char *outptr = bufcoded;
-       unsigned int i;
-
-       for (i = 0; i < nbytes; i += 3) {
-               *(outptr++) = ENC(*bufin >> 2);                                         /* c1 */
-               *(outptr++) = ENC(((*bufin << 4) & 060)   | ((bufin[1] >> 4) & 017));   /* c2 */
-               *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03));    /* c3 */
-               *(outptr++) = ENC(bufin[2] & 077);                                      /* c4 */
-               bufin += 3;
-       }
-       if (i == nbytes + 1) {
-               outptr[-1] = '=';
-       } else if (i == nbytes + 2) {
-               outptr[-1] = '=';
-               outptr[-2] = '=';
-       } else if (i == nbytes) {
-               *(outptr++) = '=';
-       }
-       *outptr = '\0';
-       return (outptr - bufcoded);
+       return __b64_ntop(src, srclength, target, targsize);
 }
 
 int
-uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize)
+uudecode(const char *src, unsigned char *target, size_t targsize)
 {
-       /* single character decode */
-#define DEC(c) pr2six[(unsigned char)c]
-#define MAXVAL 63
-
-       static int first = 1;
-       int nbytesdecoded, j;
-       const char *bufin = bufcoded;
-       register unsigned char *bufout = bufplain;
-       register int nprbytes;
+       int len;
+       char *encoded, *p;
 
-       /* If this is the first call, initialize the mapping table. */
-       if (first) {
-               first = 0;
-               for (j = 0; j < 256; j++)
-                       pr2six[j] = MAXVAL + 1;
-               for (j = 0; j < 64; j++)
-                       pr2six[(unsigned char) six2pr[j]] = (unsigned char) j;
-       }
-       /* Strip leading whitespace. */
-       while (*bufcoded == ' ' || *bufcoded == '\t')
-               bufcoded++;
-
-       /*
-        * Figure out how many characters are in the input buffer. If this
-        * would decode into more bytes than would fit into the output
-        * buffer, adjust the number of input bytes downwards.
-        */
-       bufin = bufcoded;
-       while (DEC(*(bufin++)) <= MAXVAL)
+       /* copy the 'readonly' source */
+       encoded = xstrdup(src);
+       /* skip whitespace and data */
+       for (p = encoded; *p == ' ' || *p == '\t'; p++)
                ;
-       nprbytes = bufin - bufcoded - 1;
-       nbytesdecoded = ((nprbytes + 3) / 4) * 3;
-       if (nbytesdecoded > outbufsize)
-               nprbytes = (outbufsize * 4) / 3;
-
-       bufin = bufcoded;
-
-       while (nprbytes > 0) {
-               *(bufout++) = (unsigned char) (DEC(*bufin)   << 2 | DEC(bufin[1]) >> 4);
-               *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
-               *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
-               bufin += 4;
-               nprbytes -= 4;
-       }
-       if (nprbytes & 03) {
-               if (DEC(bufin[-2]) > MAXVAL)
-                       nbytesdecoded -= 2;
-               else
-                       nbytesdecoded -= 1;
-       }
-       return (nbytesdecoded);
+       for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
+               ;
+       /* and remote trailing whitespace because __b64_pton needs this */
+       *p = '\0';
+       len = __b64_pton(encoded, target, targsize);
+       xfree(encoded);
+       return len;
 }
 
 void
@@ -108,7 +38,7 @@ dump_base64(FILE *fp, unsigned char *data, int len)
 {
        unsigned char *buf = xmalloc(2*len);
        int i, n;
-       n = uuencode(data, len, buf);
+       n = uuencode(data, len, buf, 2*len);
        for (i = 0; i < n; i++) {
                fprintf(fp, "%c", buf[i]);
                if (i % 70 == 69)
index d3f4462845bfef01ab3e40bc0845fac1d72bd3d7..c92c62744cc2afaf5222b81539826ff6df28dcb7 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef UUENCODE_H
 #define UUENCODE_H
-int    uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded);
-int    uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize);
+int    uuencode(unsigned char *src, unsigned int srclength, char *target, size_t targsize);
+int    uudecode(const char *src, unsigned char *target, size_t targsize);
 void   dump_base64(FILE *fp, unsigned char *data, int len);
 #endif
This page took 0.53124 seconds and 5 git commands to generate.