- OpenBSD CVS Changes
    - [channels.c]
      make this compile, bad markus
    - [log.c readconf.c servconf.c ssh.h]
      bugfix: loglevels are per host in clientconfig,
      factor out common log-level parsing code.
    - [servconf.c]
      remove unused index (-Wall)
    - [ssh-agent.c]
      only one 'extern char *__progname'
    - [sshd.8]
      document SIGHUP, -Q to synopsis
    - [sshconnect.c serverloop.c sshd.c packet.c packet.h]
      [channels.c clientloop.c]
      SSH_CMSG_MAX_PACKET_SIZE, some clients use this, some need this, niels@
      [hope this time my ISP stays alive during commit]
diff --git a/ChangeLog b/ChangeLog
index 69a477e..3a7b120 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+19991121
+  - OpenBSD CVS Changes
+    - [channels.c]
+      make this compile, bad markus
+    - [log.c readconf.c servconf.c ssh.h]
+      bugfix: loglevels are per host in clientconfig,
+      factor out common log-level parsing code.
+    - [servconf.c]
+      remove unused index (-Wall)
+    - [ssh-agent.c]
+      only one 'extern char *__progname'
+    - [sshd.8]
+      document SIGHUP, -Q to synopsis
+    - [sshconnect.c serverloop.c sshd.c packet.c packet.h]
+      [channels.c clientloop.c]
+      SSH_CMSG_MAX_PACKET_SIZE, some clients use this, some need this, niels@
+      [hope this time my ISP stays alive during commit]
+
 19991120
  - Merged more Solaris support from Marc G. Fournier 
    <marc.fournier@acadiau.ca>
diff --git a/channels.c b/channels.c
index c5ec1fc..3e3b5f3 100644
--- a/channels.c
+++ b/channels.c
@@ -16,7 +16,7 @@
 */
 
 #include "includes.h"
-RCSID("$Id: channels.c,v 1.5 1999/11/12 04:19:27 damien Exp $");
+RCSID("$Id: channels.c,v 1.6 1999/11/21 02:23:53 damien Exp $");
 
 #include "ssh.h"
 #include "packet.h"
@@ -208,7 +208,7 @@
 
 	case SSH_CHANNEL_OPEN:
 	  if(compat13){
-	    if (buffer_len(&ch->input) < 32768)
+	    if (buffer_len(&ch->input) < packet_get_maxsize())
 	      FD_SET(ch->sock, readset);
 	    if (buffer_len(&ch->output) > 0)
 	      FD_SET(ch->sock, writeset);
@@ -216,7 +216,7 @@
 	  }
 	  /* test whether sockets are 'alive' for read/write */
           if (ch->istate == CHAN_INPUT_OPEN)
-            if (buffer_len(&ch->input) < 32768)
+            if (buffer_len(&ch->input) < packet_get_maxsize())
               FD_SET(ch->sock, readset);
           if (ch->ostate == CHAN_OUTPUT_OPEN || ch->ostate == CHAN_OUTPUT_WAIT_DRAIN){
             if (buffer_len(&ch->output) > 0){
@@ -611,9 +611,9 @@
 	case SSH_CHANNEL_AUTH_SOCKET:
 	  continue;
 	case SSH_CHANNEL_OPEN:
-	  if (buffer_len(&ch->input) > 32768)
+	  if (buffer_len(&ch->input) > packet_get_maxsize())
 	    return 0;
-	  if (buffer_len(&ch->output) > 32768)
+	  if (buffer_len(&ch->output) > packet_get_maxsize())
 	    return 0;
 	  continue;
 	case SSH_CHANNEL_INPUT_DRAINING:
diff --git a/clientloop.c b/clientloop.c
index 410dc54..8e8d762 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -15,7 +15,7 @@
 */
 
 #include "includes.h"
-RCSID("$Id: clientloop.c,v 1.3 1999/11/12 04:19:27 damien Exp $");
+RCSID("$Id: clientloop.c,v 1.4 1999/11/21 02:23:53 damien Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -322,8 +322,8 @@
 	 packet_not_very_much_data_to_write())
     {
       len = buffer_len(&stdin_buffer);
-      if (len > 32768)
-	len = 32768;  /* Keep the packets at reasonable size. */
+      if (len > packet_get_maxsize())
+	len = packet_get_maxsize();  /* Keep the packets at reasonable size. */
       packet_start(SSH_CMSG_STDIN_DATA);
       packet_put_string(buffer_ptr(&stdin_buffer), len);
       packet_send();
diff --git a/log.c b/log.c
index 3e840ec..1ce534e 100644
--- a/log.c
+++ b/log.c
@@ -5,7 +5,7 @@
 */
 
 #include "includes.h"
-RCSID("$OpenBSD: log.c,v 1.1 1999/11/10 23:36:44 markus Exp $");
+RCSID("$OpenBSD: log.c,v 1.2 1999/11/19 16:04:17 markus Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -133,3 +133,63 @@
 
   exit(255);
 }
+
+/* textual representation of log-facilities/levels */
+
+
+static struct 
+{
+  const char *name;
+  SyslogFacility val;
+} log_facilities[] =
+{
+  { "DAEMON", SYSLOG_FACILITY_DAEMON },
+  { "USER", SYSLOG_FACILITY_USER },
+  { "AUTH", SYSLOG_FACILITY_AUTH },
+  { "LOCAL0", SYSLOG_FACILITY_LOCAL0 },
+  { "LOCAL1", SYSLOG_FACILITY_LOCAL1 },
+  { "LOCAL2", SYSLOG_FACILITY_LOCAL2 },
+  { "LOCAL3", SYSLOG_FACILITY_LOCAL3 },
+  { "LOCAL4", SYSLOG_FACILITY_LOCAL4 },
+  { "LOCAL5", SYSLOG_FACILITY_LOCAL5 },
+  { "LOCAL6", SYSLOG_FACILITY_LOCAL6 },
+  { "LOCAL7", SYSLOG_FACILITY_LOCAL7 },
+  { NULL, 0 }
+};
+
+static struct 
+{
+  const char *name;
+  LogLevel val;
+} log_levels[] =
+{
+  { "QUIET",   SYSLOG_LEVEL_QUIET },
+  { "FATAL",   SYSLOG_LEVEL_FATAL },
+  { "ERROR",   SYSLOG_LEVEL_ERROR },
+  { "INFO",    SYSLOG_LEVEL_INFO },
+  { "CHAT",	SYSLOG_LEVEL_CHAT },
+  { "DEBUG",   SYSLOG_LEVEL_DEBUG },
+  { NULL, 0 }
+};
+
+SyslogFacility
+log_facility_number(char *name)
+{
+  int i;
+  if (name != NULL)
+    for (i = 0; log_facilities[i].name; i++)
+      if (strcasecmp(log_facilities[i].name, name) == 0)
+        return log_facilities[i].val;
+  return (SyslogFacility)-1;
+}
+
+LogLevel
+log_level_number(char *name)
+{
+  int i;
+  if (name != NULL)
+    for (i = 0; log_levels[i].name; i++)
+      if (strcasecmp(log_levels[i].name, name) == 0)
+        return log_levels[i].val;
+  return (LogLevel)-1;
+}
diff --git a/packet.c b/packet.c
index 9c2a4f8..74bb382 100644
--- a/packet.c
+++ b/packet.c
@@ -15,7 +15,7 @@
 */
 
 #include "includes.h"
-RCSID("$Id: packet.c,v 1.3 1999/11/16 02:37:16 damien Exp $");
+RCSID("$Id: packet.c,v 1.4 1999/11/21 02:23:53 damien Exp $");
 
 #include "xmalloc.h"
 #include "buffer.h"
@@ -66,6 +66,9 @@
 /* Flag indicating whether packet compression/decompression is enabled. */
 static int packet_compression = 0;
 
+/* default maximum packet size */
+int max_packet_size = 32768;
+
 /* Flag indicating whether this module has been initialized. */
 static int initialized = 0;
 
@@ -745,3 +748,20 @@
 {
   return interactive_mode;
 }
+
+int
+packet_set_maxsize(int s)
+{
+  static int called = 0;
+  if (called) {
+    log("packet_set_maxsize: called twice: old %d new %d", max_packet_size, s);
+    return -1;
+  }
+  if (s < 4*1024 || s > 1024*1024) {
+    log("packet_set_maxsize: bad size %d", s);
+    return -1;
+  }
+  log("packet_set_maxsize: setting to %d", s);
+  max_packet_size = s;
+  return s;
+}
diff --git a/packet.h b/packet.h
index 5aa4fd9..250a6b3 100644
--- a/packet.h
+++ b/packet.h
@@ -13,7 +13,7 @@
 
 */
 
-/* RCSID("$Id: packet.h,v 1.4 1999/11/16 02:37:16 damien Exp $"); */
+/* RCSID("$Id: packet.h,v 1.5 1999/11/21 02:23:53 damien Exp $"); */
 
 #ifndef PACKET_H
 #define PACKET_H
@@ -154,6 +154,11 @@
 /* Returns true if there is not too much data to write to the connection. */
 int packet_not_very_much_data_to_write(void);
 
+/* maximum packet size, requested by client with SSH_CMSG_MAX_PACKET_SIZE */
+extern int max_packet_size;
+int packet_set_maxsize(int s);
+#define packet_get_maxsize() max_packet_size
+
 /* Stores tty modes from the fd into current packet. */
 void tty_make_modes(int fd);
 
diff --git a/readconf.c b/readconf.c
index b341322..d8694b8 100644
--- a/readconf.c
+++ b/readconf.c
@@ -14,7 +14,7 @@
 */
 
 #include "includes.h"
-RCSID("$Id: readconf.c,v 1.3 1999/11/15 04:25:10 damien Exp $");
+RCSID("$Id: readconf.c,v 1.4 1999/11/21 02:23:53 damien Exp $");
 
 #include "ssh.h"
 #include "cipher.h"
@@ -155,23 +155,6 @@
   { NULL, 0 }
 };
 
-/* textual representation of log-levels */
-
-static struct 
-{
-  const char *name;
-  LogLevel level;
-} log_levels[] =
-{
-  { "QUIET", SYSLOG_LEVEL_QUIET },
-  { "FATAL", SYSLOG_LEVEL_FATAL },
-  { "ERROR", SYSLOG_LEVEL_ERROR },
-  { "INFO",  SYSLOG_LEVEL_INFO },
-  { "CHAT",  SYSLOG_LEVEL_CHAT },
-  { "DEBUG", SYSLOG_LEVEL_DEBUG },
-  { NULL, 0 }
-};
-
 /* Characters considered whitespace in strtok calls. */
 #define WHITESPACE " \t\r\n"
 
@@ -237,7 +220,7 @@
 			 int *activep)
 {
   char buf[256], *cp, *string, **charptr;
-  int opcode, *intptr, value, fwd_port, fwd_host_port, i;
+  int opcode, *intptr, value, fwd_port, fwd_host_port;
 
   /* Skip leading whitespace. */
   cp = line + strspn(line, WHITESPACE);
@@ -462,30 +445,21 @@
       cp = strtok(NULL, WHITESPACE);
       value = cipher_number(cp);
       if (value == -1)
-	fatal("%.200s line %d: Bad cipher.", filename, linenum);
+	fatal("%.200s line %d: Bad cipher '%s'.",
+	      filename, linenum, cp ? cp : "<NONE>");
       if (*activep && *intptr == -1)
 	*intptr = value;
       break;
 
     case oLogLevel:
+      intptr = (int *)&options->log_level;
       cp = strtok(NULL, WHITESPACE);
-      if (!cp)
-        {
-          fprintf(stderr, "%s line %d: missing level name.\n",
-	          filename, linenum);
-          exit(1);
-        }
-      for (i = 0; log_levels[i].name; i++)
-        if (strcasecmp(log_levels[i].name, cp) == 0)
-          break;
-      if (!log_levels[i].name)
-        {
-          fprintf(stderr, "%s line %d: unsupported log level %s\n",
-	          filename, linenum, cp);
-          exit(1);
-        }
-      if (options->log_level == (LogLevel)(-1))
-        options->log_level = log_levels[i].level;
+      value = log_level_number(cp);
+      if (value == (LogLevel)-1)
+        fatal("%.200s line %d: unsupported log level '%s'\n",
+	      filename, linenum, cp ? cp : "<NONE>");
+      if (*activep && (LogLevel)*intptr == -1)
+	*intptr = (LogLevel)value;
       break;
       
     case oRemoteForward:
diff --git a/servconf.c b/servconf.c
index f6d0639..086bc03 100644
--- a/servconf.c
+++ b/servconf.c
@@ -12,7 +12,7 @@
 */
 
 #include "includes.h"
-RCSID("$Id: servconf.c,v 1.4 1999/11/12 04:19:27 damien Exp $");
+RCSID("$Id: servconf.c,v 1.5 1999/11/21 02:23:53 damien Exp $");
 
 #include "ssh.h"
 #include "servconf.h"
@@ -214,41 +214,6 @@
   { NULL, 0 }
 };
 
-static struct 
-{
-  const char *name;
-  SyslogFacility facility;
-} log_facilities[] =
-{
-  { "DAEMON", SYSLOG_FACILITY_DAEMON },
-  { "USER", SYSLOG_FACILITY_USER },
-  { "AUTH", SYSLOG_FACILITY_AUTH },
-  { "LOCAL0", SYSLOG_FACILITY_LOCAL0 },
-  { "LOCAL1", SYSLOG_FACILITY_LOCAL1 },
-  { "LOCAL2", SYSLOG_FACILITY_LOCAL2 },
-  { "LOCAL3", SYSLOG_FACILITY_LOCAL3 },
-  { "LOCAL4", SYSLOG_FACILITY_LOCAL4 },
-  { "LOCAL5", SYSLOG_FACILITY_LOCAL5 },
-  { "LOCAL6", SYSLOG_FACILITY_LOCAL6 },
-  { "LOCAL7", SYSLOG_FACILITY_LOCAL7 },
-  { NULL, 0 }
-};
-
-static struct 
-{
-  const char *name;
-  LogLevel level;
-} log_levels[] =
-{
-  { "QUIET", SYSLOG_LEVEL_QUIET },
-  { "FATAL", SYSLOG_LEVEL_FATAL },
-  { "ERROR", SYSLOG_LEVEL_ERROR },
-  { "INFO",  SYSLOG_LEVEL_INFO },
-  { "CHAT",  SYSLOG_LEVEL_CHAT },
-  { "DEBUG", SYSLOG_LEVEL_DEBUG },
-  { NULL, 0 }
-};
-
 /* Returns the number of the token pointed to by cp of length len.
    Never returns if the token is not known. */
 
@@ -273,7 +238,7 @@
   FILE *f;
   char line[1024];
   char *cp, **charptr;
-  int linenum, *intptr, i, value;
+  int linenum, *intptr, value;
   int bad_options = 0;
   ServerOpCodes opcode;
 
@@ -495,45 +460,25 @@
           goto parse_flag;
 
 	case sLogFacility:
+	  intptr = (int *)&options->log_facility;
 	  cp = strtok(NULL, WHITESPACE);
-	  if (!cp)
-	    {
-	      fprintf(stderr, "%s line %d: missing facility name.\n",
-		      filename, linenum);
-	      exit(1);
-	    }
-	  for (i = 0; log_facilities[i].name; i++)
-	    if (strcasecmp(log_facilities[i].name, cp) == 0)
-	      break;
-	  if (!log_facilities[i].name)
-	    {
-	      fprintf(stderr, "%s line %d: unsupported log facility %s\n",
-		      filename, linenum, cp);
-	      exit(1);
-	    }
-	  if (options->log_facility == (SyslogFacility)(-1))
-	    options->log_facility = log_facilities[i].facility;
+	  value = log_facility_number(cp);
+	  if (value == (SyslogFacility)-1)
+	    fatal("%.200s line %d: unsupported log facility '%s'\n",
+      	      filename, linenum, cp ? cp : "<NONE>");
+	  if (*intptr == -1)
+	    *intptr = (SyslogFacility)value;
 	  break;
 
 	case sLogLevel:
+	  intptr = (int *)&options->log_level;
 	  cp = strtok(NULL, WHITESPACE);
-	  if (!cp)
-	    {
-	      fprintf(stderr, "%s line %d: missing level name.\n",
-		      filename, linenum);
-	      exit(1);
-	    }
-	  for (i = 0; log_levels[i].name; i++)
-	    if (strcasecmp(log_levels[i].name, cp) == 0)
-	      break;
-	  if (!log_levels[i].name)
-	    {
-	      fprintf(stderr, "%s line %d: unsupported log level %s\n",
-		      filename, linenum, cp);
-	      exit(1);
-	    }
-	  if (options->log_level == (LogLevel)(-1))
-	    options->log_level = log_levels[i].level;
+	  value = log_level_number(cp);
+	  if (value == (LogLevel)-1)
+	    fatal("%.200s line %d: unsupported log level '%s'\n",
+      	      filename, linenum, cp ? cp : "<NONE>");
+	  if (*intptr == -1)
+	    *intptr = (LogLevel)value;
 	  break;
 	  
 	case sAllowUsers:
diff --git a/serverloop.c b/serverloop.c
index 2aec2cf..9961170 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -176,8 +176,8 @@
 	}
       else
 	{
-	  if (len > 32768)
-	    len = 32768;  /* Keep the packets at reasonable size. */
+	  if (len > packet_get_maxsize())
+	    len = packet_get_maxsize();  /* Keep the packets at reasonable size. */
 	}
       packet_start(SSH_SMSG_STDERR_DATA);
       packet_put_string(buffer_ptr(&stderr_buffer), len);
@@ -206,8 +206,8 @@
 	}
       else
 	{
-	  if (len > 32768)
-	    len = 32768;  /* Keep the packets at reasonable size. */
+	  if (len > packet_get_maxsize())
+	    len = packet_get_maxsize();  /* Keep the packets at reasonable size. */
 	}
       packet_start(SSH_SMSG_STDOUT_DATA);
       packet_put_string(buffer_ptr(&stdout_buffer), len);
diff --git a/ssh-agent.c b/ssh-agent.c
index 296bb4c..f1ceb56 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ssh-agent.c,v 1.19 1999/11/18 14:00:49 markus Exp $	*/
+/*	$OpenBSD: ssh-agent.c,v 1.20 1999/11/19 10:20:51 markus Exp $	*/
 
 /*
 
@@ -16,7 +16,7 @@
 */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.19 1999/11/18 14:00:49 markus Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.20 1999/11/19 10:20:51 markus Exp $");
 
 #include "ssh.h"
 #include "rsa.h"
diff --git a/ssh.h b/ssh.h
index 72685e6..9066828 100644
--- a/ssh.h
+++ b/ssh.h
@@ -13,7 +13,7 @@
 
 */
 
-/* RCSID("$Id: ssh.h,v 1.13 1999/11/16 02:37:17 damien Exp $"); */
+/* RCSID("$Id: ssh.h,v 1.14 1999/11/21 02:23:53 damien Exp $"); */
 
 #ifndef SSH_H
 #define SSH_H
@@ -392,6 +392,10 @@
 /* Logging implementation, depending on server or client */
 void do_log(LogLevel level, const char *fmt, va_list args);
 
+/* name to facility/level */
+SyslogFacility log_facility_number(char *name);
+LogLevel log_level_number(char *name);
+
 /* Output a message to syslog or stderr */
 void fatal(const char *fmt, ...);
 void error(const char *fmt, ...);
diff --git a/sshconnect.c b/sshconnect.c
index 8b77374..fba389d 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -15,7 +15,7 @@
 */
 
 #include "includes.h"
-RCSID("$Id: sshconnect.c,v 1.12 1999/11/18 21:25:48 damien Exp $");
+RCSID("$Id: sshconnect.c,v 1.13 1999/11/21 02:23:53 damien Exp $");
 
 #ifdef HAVE_OPENSSL
 #include <openssl/bn.h>
@@ -906,7 +906,7 @@
   for (i = 0; i < sizeof(buf) - 1; i++)
     {
       if (read(connection_in, &buf[i], 1) != 1)
-	fatal("read: %.100s", strerror(errno));
+	fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
       if (buf[i] == '\r')
 	{
 	  buf[i] = '\n';
diff --git a/sshd.8 b/sshd.8
index e9a09f4..ac728f8 100644
--- a/sshd.8
+++ b/sshd.8
@@ -9,7 +9,7 @@
 .\"
 .\" Created: Sat Apr 22 21:55:14 1995 ylo
 .\"
-.\" $Id: sshd.8,v 1.7 1999/11/12 00:33:04 damien Exp $
+.\" $Id: sshd.8,v 1.8 1999/11/21 02:23:53 damien Exp $
 .\"
 .Dd September 25, 1999
 .Dt SSHD 8
@@ -19,7 +19,7 @@
 .Nd secure shell daemon
 .Sh SYNOPSIS
 .Nm sshd
-.Op Fl diq
+.Op Fl diqQ
 .Op Fl b Ar bits
 .Op Fl f Ar config_file
 .Op Fl g Ar login_grace_time
@@ -106,6 +106,10 @@
 file.  Command-line options override values specified in the
 configuration file.
 .Pp
+.Nm
+rereads its configuration file when it receives a hangup signal,
+.Dv SIGHUP .
+.Pp
 The options are as follows:
 .Bl -tag -width Ds
 .It Fl b Ar bits
diff --git a/sshd.c b/sshd.c
index 1953807..ad51dac 100644
--- a/sshd.c
+++ b/sshd.c
@@ -18,7 +18,7 @@
 */
 
 #include "includes.h"
-RCSID("$Id: sshd.c,v 1.25 1999/11/18 21:25:48 damien Exp $");
+RCSID("$Id: sshd.c,v 1.26 1999/11/21 02:23:53 damien Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -1753,6 +1753,11 @@
 	  channel_input_port_forward_request(pw->pw_uid == 0);
 	  break;
 
+	case SSH_CMSG_MAX_PACKET_SIZE:
+          if (packet_set_maxsize(packet_get_int()) < 0)
+	    goto fail;
+	  break;
+
 	case SSH_CMSG_EXEC_SHELL:
 	  /* Set interactive/non-interactive mode. */
 	  packet_set_interactive(have_pty || display != NULL, 
@@ -1791,10 +1796,6 @@
 	  xfree(command);
 	  return;
 
-	case SSH_CMSG_MAX_PACKET_SIZE:
-      	  debug("The server does not support limiting packet size.");
-	  goto fail;
-
 	default:
 	  /* Any unknown messages in this phase are ignored, and a failure
 	     message is returned. */