--- /dev/null
+diff -ur openssh-3.4p1-owl-hide-unknown/auth-pam.c openssh-3.4p1/auth-pam.c
+--- openssh-3.4p1-owl-hide-unknown/auth-pam.c Wed May 8 06:27:56 2002
++++ openssh-3.4p1/auth-pam.c Sat Jun 29 21:13:08 2002
+@@ -204,15 +204,20 @@
+ {
+ extern ServerOptions options;
+ int pam_retval;
++ int fail;
+ struct passwd *pw = authctxt->pw;
+
+ do_pam_set_conv(&conv);
+
+ /* deny if no user. */
+- if (pw == NULL)
+- return 0;
+- if (pw->pw_uid == 0 && options.permit_root_login == PERMIT_NO_PASSWD)
+- return 0;
++ fail = 0;
++ if (pw == NULL ||
++ (pw->pw_uid == 0 && options.permit_root_login == PERMIT_NO_PASSWD)) {
++ /* Attempt to reduce information leaks via timings. */
++ fail = 1;
++ if (*password) password = "INCORRECT";
++ }
++
+ if (*password == '\0' && options.permit_empty_passwd == 0)
+ return 0;
+
+@@ -221,14 +226,14 @@
+ pamstate = INITIAL_LOGIN;
+ pam_retval = do_pam_authenticate(
+ options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0);
+- if (pam_retval == PAM_SUCCESS) {
+- debug("PAM Password authentication accepted for "
+- "user \"%.100s\"", pw->pw_name);
++ if (!fail && pam_retval == PAM_SUCCESS) {
++ debug("PAM password authentication accepted for "
++ "%.100s", pw->pw_name);
+ return 1;
+ } else {
+- debug("PAM Password authentication for \"%.100s\" "
+- "failed[%d]: %s", pw->pw_name, pam_retval,
+- PAM_STRERROR(__pamh, pam_retval));
++ debug("PAM password authentication failed for "
++ "%.100s: %s", pw ? pw->pw_name : "an illegal user",
++ fail ? "Forced" : PAM_STRERROR(__pamh, pam_retval));
+ return 0;
+ }
+ }
+diff -ur openssh-3.4p1-owl-hide-unknown/auth1.c openssh-3.4p1/auth1.c
+--- openssh-3.4p1-owl-hide-unknown/auth1.c Sat Jun 29 21:02:35 2002
++++ openssh-3.4p1/auth1.c Sat Jun 29 21:13:08 2002
+@@ -383,7 +383,7 @@
+ use_privsep ? " [net]" : "");
+
+ #ifdef USE_PAM
+- PRIVSEP(start_pam(authctxt->pw == NULL ? "NOUSER" : user));
++ PRIVSEP(start_pam(authctxt->pw ? user : "ILLEGAL USER"));
+ #endif
+
+ /*
+diff -ur openssh-3.4p1-owl-hide-unknown/auth2.c openssh-3.4p1/auth2.c
+--- openssh-3.4p1-owl-hide-unknown/auth2.c Sat Jun 29 21:03:37 2002
++++ openssh-3.4p1/auth2.c Sat Jun 29 21:13:08 2002
+@@ -164,7 +164,7 @@
+ authctxt->pw = NULL;
+ authctxt->valid = 0;
+ #ifdef USE_PAM
+- PRIVSEP(start_pam("NOUSER"));
++ PRIVSEP(start_pam("ILLEGAL USER"));
+ #endif
+ }
+ setproctitle("%s%s", authctxt->pw ? user : "UNKNOWN USER",
--- /dev/null
+diff -ur openssh-3.4p1.orig/auth-pam.c openssh-3.4p1/auth-pam.c
+--- openssh-3.4p1.orig/auth-pam.c Wed May 8 06:27:56 2002
++++ openssh-3.4p1/auth-pam.c Sat Jul 6 02:42:50 2002
+@@ -177,7 +177,7 @@
+ {
+ int pam_retval = PAM_SUCCESS;
+
+- if (__pamh && session_opened) {
++ if (__pamh && getpid() == session_opened) {
+ pam_retval = pam_close_session(__pamh, 0);
+ if (pam_retval != PAM_SUCCESS)
+ log("Cannot close PAM session[%d]: %.200s",
+@@ -291,7 +291,7 @@
+ fatal("PAM session setup failed[%d]: %.200s",
+ pam_retval, PAM_STRERROR(__pamh, pam_retval));
+
+- session_opened = 1;
++ session_opened = getpid();
+ }
+
+ /* Set PAM credentials */
+diff -ur openssh-3.4p1.orig/packet.c openssh-3.4p1/packet.c
+--- openssh-3.4p1.orig/packet.c Mon Jun 24 01:49:25 2002
++++ openssh-3.4p1/packet.c Sat Jul 6 02:39:59 2002
+@@ -148,8 +148,6 @@
+ buffer_init(&outgoing_packet);
+ buffer_init(&incoming_packet);
+ }
+- /* Kludge: arrange the close function to be called from fatal(). */
+- fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
+ }
+
+ /* Returns 1 if remote host is connected via socket, 0 if not. */
+diff -ur openssh-3.4p1.orig/session.c openssh-3.4p1/session.c
+--- openssh-3.4p1.orig/session.c Wed Jun 26 17:51:06 2002
++++ openssh-3.4p1/session.c Sat Jul 6 05:24:37 2002
+@@ -470,6 +470,8 @@
+
+ /* Fork the child. */
+ if ((pid = fork()) == 0) {
++ fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
++
+ /* Child. Reinitialize the log since the pid has changed. */
+ log_init(__progname, options.log_level, options.log_facility, log_stderr);
+
+@@ -585,6 +587,8 @@
+
+ /* Fork the child. */
+ if ((pid = fork()) == 0) {
++ fatal_remove_cleanup(session_pty_cleanup, (void *)s);
++ fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
+
+ /* Child. Reinitialize the log because the pid has changed. */
+ log_init(__progname, options.log_level, options.log_facility, log_stderr);
+@@ -1593,7 +1597,9 @@
+ * Add a cleanup function to clear the utmp entry and record logout
+ * time in case we call fatal() (e.g., the connection gets closed).
+ */
++ fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
+ fatal_add_cleanup(session_pty_cleanup, (void *)s);
++ fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
+ if (!use_privsep)
+ pty_setowner(s->pw, s->tty);
+
+diff -ur openssh-3.4p1.orig/ssh-keyscan.c openssh-3.4p1/ssh-keyscan.c
+--- openssh-3.4p1.orig/ssh-keyscan.c Fri Jun 21 04:09:54 2002
++++ openssh-3.4p1/ssh-keyscan.c Sun Jul 28 03:20:35 2002
+@@ -344,6 +344,7 @@
+ int j;
+
+ packet_set_connection(c->c_fd, c->c_fd);
++ fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
+ enable_compat20();
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA?
+ "ssh-dss": "ssh-rsa";
+diff -ur openssh-3.4p1.orig/sshconnect.c openssh-3.4p1/sshconnect.c
+--- openssh-3.4p1.orig/sshconnect.c Mon Jun 24 01:23:20 2002
++++ openssh-3.4p1/sshconnect.c Sun Jul 28 03:20:07 2002
+@@ -153,6 +153,7 @@
+
+ /* Set the connection file descriptors. */
+ packet_set_connection(pout[0], pin[1]);
++ fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
+
+ /* Indicate OK return */
+ return 0;
+@@ -354,6 +355,7 @@
+
+ /* Set the connection. */
+ packet_set_connection(sock, sock);
++ fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
+
+ return 0;
+ }
+diff -ur openssh-3.4p1.orig/sshd.c openssh-3.4p1/sshd.c
+--- openssh-3.4p1.orig/sshd.c Wed Jun 26 03:24:19 2002
++++ openssh-3.4p1/sshd.c Sun Jul 7 07:04:55 2002
+@@ -303,9 +303,6 @@
+ {
+ /* XXX no idea how fix this signal handler */
+
+- /* Close the connection. */
+- packet_close();
+-
+ /* Log error and exit. */
+ fatal("Timeout before authentication for %s.", get_remote_ipaddr());
+ }
+@@ -612,6 +609,8 @@
+ if (getuid() == 0 || geteuid() == 0)
+ privsep_preauth_child();
+ setproctitle("%s", "[net]");
++
++ fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
+ }
+ return (NULL);
+ }
+@@ -630,6 +629,7 @@
+ if (authctxt->pw->pw_uid == 0 || options.use_login) {
+ #endif
+ /* File descriptor passing is broken or root login */
++ fatal_add_cleanup((void (*) (void *))packet_close, NULL);
+ monitor_apply_keystate(pmonitor);
+ use_privsep = 0;
+ return;
+@@ -665,6 +665,8 @@
+ /* Drop privileges */
+ do_setusercontext(authctxt->pw);
+
++ fatal_add_cleanup((void (*) (void *))packet_close, NULL);
++
+ /* It is safe now to apply the key state */
+ monitor_apply_keystate(pmonitor);
+ }
+@@ -1483,9 +1485,11 @@
+
+ packet_set_nonblocking();
+
+- if (use_privsep)
++ if (use_privsep) {
+ if ((authctxt = privsep_preauth()) != NULL)
+ goto authenticated;
++ } else
++ fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
+
+ /* perform the key exchange */
+ /* authenticate user and start session */
--- /dev/null
+diff -ur openssh-3.4p1.orig/auth.c openssh-3.4p1/auth.c
+--- openssh-3.4p1.orig/auth.c Wed May 22 09:06:28 2002
++++ openssh-3.4p1/auth.c Sat Jun 29 21:02:35 2002
+@@ -251,8 +251,9 @@
+ authlog("%s %s for %s%.100s from %.200s port %d%s",
+ authmsg,
+ method,
+- authctxt->valid ? "" : "illegal user ",
+- authctxt->user,
++ !authctxt->valid ? "UNKNOWN USER" :
++ (authctxt->pw->pw_uid == 0 ? "ROOT USER " : ""),
++ authctxt->valid ? authctxt->user : "",
+ get_remote_ipaddr(),
+ get_remote_port(),
+ info);
+diff -ur openssh-3.4p1.orig/auth1.c openssh-3.4p1/auth1.c
+--- openssh-3.4p1.orig/auth1.c Fri Jun 21 10:21:11 2002
++++ openssh-3.4p1/auth1.c Sat Jun 29 21:02:35 2002
+@@ -379,7 +379,7 @@
+ else
+ debug("do_authentication: illegal user %s", user);
+
+- setproctitle("%s%s", authctxt->pw ? user : "unknown",
++ setproctitle("%s%s", authctxt->pw ? user : "UNKNOWN USER",
+ use_privsep ? " [net]" : "");
+
+ #ifdef USE_PAM
+diff -ur openssh-3.4p1.orig/auth2.c openssh-3.4p1/auth2.c
+--- openssh-3.4p1.orig/auth2.c Fri Jun 21 10:21:11 2002
++++ openssh-3.4p1/auth2.c Sat Jun 29 21:03:37 2002
+@@ -160,12 +160,14 @@
+ PRIVSEP(start_pam(authctxt->pw->pw_name));
+ #endif
+ } else {
+- log("input_userauth_request: illegal user %s", user);
++ debug2("input_userauth_request: illegal user %s", user);
++ authctxt->pw = NULL;
++ authctxt->valid = 0;
+ #ifdef USE_PAM
+ PRIVSEP(start_pam("NOUSER"));
+ #endif
+ }
+- setproctitle("%s%s", authctxt->pw ? user : "unknown",
++ setproctitle("%s%s", authctxt->pw ? user : "UNKNOWN USER",
+ use_privsep ? " [net]" : "");
+ authctxt->user = xstrdup(user);
+ authctxt->service = xstrdup(service);
--- /dev/null
+diff -ur openssh-3.4p1.orig/auth-pam.c openssh-3.4p1/auth-pam.c
+--- openssh-3.4p1.orig/auth-pam.c Wed May 8 06:27:56 2002
++++ openssh-3.4p1/auth-pam.c Sat Jul 6 22:27:59 2002
+@@ -75,6 +75,7 @@
+ int do_pam_authenticate(int flags)
+ {
+ int retval = pam_authenticate(__pamh, flags);
++ log_reinit();
+ was_authenticated = (retval == PAM_SUCCESS);
+ return retval;
+ }
+@@ -179,6 +180,7 @@
+
+ if (__pamh && session_opened) {
+ pam_retval = pam_close_session(__pamh, 0);
++ log_reinit();
+ if (pam_retval != PAM_SUCCESS)
+ log("Cannot close PAM session[%d]: %.200s",
+ pam_retval, PAM_STRERROR(__pamh, pam_retval));
+@@ -186,6 +188,7 @@
+
+ if (__pamh && creds_set) {
+ pam_retval = pam_setcred(__pamh, PAM_DELETE_CRED);
++ log_reinit();
+ if (pam_retval != PAM_SUCCESS)
+ debug("Cannot delete credentials[%d]: %.200s",
+ pam_retval, PAM_STRERROR(__pamh, pam_retval));
+@@ -249,6 +252,7 @@
+ }
+
+ pam_retval = pam_acct_mgmt(__pamh, 0);
++ log_reinit();
+ debug2("pam_acct_mgmt() = %d", pam_retval);
+ switch (pam_retval) {
+ case PAM_SUCCESS:
+@@ -287,6 +291,7 @@
+ }
+
+ pam_retval = pam_open_session(__pamh, 0);
++ log_reinit();
+ if (pam_retval != PAM_SUCCESS)
+ fatal("PAM session setup failed[%d]: %.200s",
+ pam_retval, PAM_STRERROR(__pamh, pam_retval));
+@@ -307,6 +312,7 @@
+ debug("PAM establishing creds");
+ pam_retval = pam_setcred(__pamh,
+ init ? PAM_ESTABLISH_CRED : PAM_REINITIALIZE_CRED);
++ log_reinit();
+ if (pam_retval != PAM_SUCCESS) {
+ if (was_authenticated)
+ fatal("PAM setcred failed[%d]: %.200s",
+@@ -339,6 +345,7 @@
+ if (password_change_required) {
+ pamstate = OTHER;
+ pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
++ log_reinit();
+ if (pam_retval != PAM_SUCCESS)
+ fatal("PAM pam_chauthtok failed[%d]: %.200s",
+ pam_retval, PAM_STRERROR(__pamh, pam_retval));
+diff -ur openssh-3.4p1.orig/entropy.c openssh-3.4p1/entropy.c
+--- openssh-3.4p1.orig/entropy.c Sun Jun 9 23:41:48 2002
++++ openssh-3.4p1/entropy.c Sat Jun 29 20:36:17 2002
+@@ -93,7 +93,8 @@
+ original_uid, strerror(errno));
+ _exit(1);
+ }
+-
++
++ log_done();
+ execl(SSH_RAND_HELPER, "ssh-rand-helper", NULL);
+ fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n",
+ SSH_RAND_HELPER, strerror(errno));
+diff -ur openssh-3.4p1.orig/log.c openssh-3.4p1/log.c
+--- openssh-3.4p1.orig/log.c Tue Feb 26 20:52:15 2002
++++ openssh-3.4p1/log.c Sat Jun 29 20:34:00 2002
+@@ -241,6 +241,15 @@
+ */
+
+ void
++log_reinit(void)
++{
++ if (log_on_stderr)
++ return;
++
++ openlog(argv0 ? argv0 : __progname, LOG_PID|LOG_NDELAY, log_facility);
++}
++
++void
+ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
+ {
+ argv0 = av0;
+@@ -311,6 +320,15 @@
+ (int) facility);
+ exit(1);
+ }
++
++ tzset();
++ log_reinit();
++}
++
++void
++log_done(void)
++{
++ closelog();
+ }
+
+ #define MSGBUFSIZ 1024
+@@ -369,8 +387,6 @@
+ if (log_on_stderr) {
+ fprintf(stderr, "%s\r\n", msgbuf);
+ } else {
+- openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
+ syslog(pri, "%.500s", msgbuf);
+- closelog();
+ }
+ }
+diff -ur openssh-3.4p1.orig/log.h openssh-3.4p1/log.h
+--- openssh-3.4p1.orig/log.h Thu Jun 6 23:51:06 2002
++++ openssh-3.4p1/log.h Sat Jun 29 20:35:24 2002
+@@ -49,6 +49,8 @@
+ } LogLevel;
+
+ void log_init(char *, LogLevel, SyslogFacility, int);
++void log_done(void);
++void log_reinit(void);
+
+ SyslogFacility log_facility_number(char *);
+ LogLevel log_level_number(char *);
+diff -ur openssh-3.4p1.orig/monitor.c openssh-3.4p1/monitor.c
+--- openssh-3.4p1.orig/monitor.c Wed Jun 26 17:27:11 2002
++++ openssh-3.4p1/monitor.c Sat Jun 29 21:01:38 2002
+@@ -279,8 +279,6 @@
+ }
+
+ if (ent->flags & MON_AUTHDECIDE) {
+- auth_log(authctxt, authenticated, auth_method,
+- compat20 ? " ssh2" : "");
+ if (!authenticated)
+ authctxt->failures++;
+ }
+diff -ur openssh-3.4p1.orig/readpass.c openssh-3.4p1/readpass.c
+--- openssh-3.4p1.orig/readpass.c Wed Mar 27 20:28:47 2002
++++ openssh-3.4p1/readpass.c Sat Jun 29 20:37:06 2002
+@@ -58,7 +58,9 @@
+ close(p[0]);
+ if (dup2(p[1], STDOUT_FILENO) < 0)
+ fatal("ssh_askpass: dup2: %s", strerror(errno));
++ log_done();
+ execlp(askpass, askpass, msg, (char *) 0);
++ log_reinit();
+ fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
+ }
+ close(p[1]);
+diff -ur openssh-3.4p1.orig/scp.c openssh-3.4p1/scp.c
+--- openssh-3.4p1.orig/scp.c Fri Jun 21 04:41:52 2002
++++ openssh-3.4p1/scp.c Sat Jun 29 20:38:16 2002
+@@ -174,6 +174,7 @@
+ addargs(&args, "%s", host);
+ addargs(&args, "%s", cmd);
+
++ log_done();
+ execvp(ssh_program, args.list);
+ perror(ssh_program);
+ exit(1);
+diff -ur openssh-3.4p1.orig/session.c openssh-3.4p1/session.c
+--- openssh-3.4p1.orig/session.c Wed Jun 26 17:51:06 2002
++++ openssh-3.4p1/session.c Sat Jul 6 22:21:36 2002
+@@ -471,7 +471,7 @@
+ /* Fork the child. */
+ if ((pid = fork()) == 0) {
+ /* Child. Reinitialize the log since the pid has changed. */
+- log_init(__progname, options.log_level, options.log_facility, log_stderr);
++ log_reinit();
+
+ /*
+ * Create a new session and process group since the 4.4BSD
+@@ -587,7 +587,7 @@
+ if ((pid = fork()) == 0) {
+
+ /* Child. Reinitialize the log because the pid has changed. */
+- log_init(__progname, options.log_level, options.log_facility, log_stderr);
++ log_reinit();
+ /* Close the master side of the pseudo tty. */
+ close(ptyfd);
+
+@@ -1225,6 +1225,7 @@
+ {
+ /* Launch login(1). */
+
++ log_done();
+ execl(LOGIN_PROGRAM, "login", "-h", hostname,
+ #ifdef xxxLOGIN_NEEDS_TERM
+ (s->term ? s->term : "unknown"),
+@@ -1391,6 +1392,8 @@
+ exit(1);
+ }
+
++ log_done();
++
+ /* Execute the shell. */
+ argv[0] = argv0;
+ argv[1] = NULL;
+@@ -1400,6 +1403,9 @@
+ perror(shell);
+ exit(1);
+ }
++
++ log_done();
++
+ /*
+ * Execute the command using the user's shell. This uses the -c
+ * option to execute the command.
+diff -ur openssh-3.4p1.orig/sftp-int.c openssh-3.4p1/sftp-int.c
+--- openssh-3.4p1.orig/sftp-int.c Mon Jun 24 01:27:19 2002
++++ openssh-3.4p1/sftp-int.c Sat Jun 29 20:44:53 2002
+@@ -167,9 +167,11 @@
+ /* XXX: child has pipe fds to ssh subproc open - issue? */
+ if (args) {
+ debug3("Executing %s -c \"%s\"", shell, args);
++ log_done();
+ execl(shell, shell, "-c", args, (char *)NULL);
+ } else {
+ debug3("Executing %s", shell);
++ log_done();
+ execl(shell, shell, (char *)NULL);
+ }
+ fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell,
+diff -ur openssh-3.4p1.orig/sftp.c openssh-3.4p1/sftp.c
+--- openssh-3.4p1.orig/sftp.c Mon Jun 24 01:27:19 2002
++++ openssh-3.4p1/sftp.c Sat Jun 29 20:44:26 2002
+@@ -84,6 +84,7 @@
+ close(*out);
+ close(c_in);
+ close(c_out);
++ log_done();
+ execv(path, args);
+ fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
+ exit(1);
+diff -ur openssh-3.4p1.orig/ssh-agent.c openssh-3.4p1/ssh-agent.c
+--- openssh-3.4p1.orig/ssh-agent.c Wed Jun 26 03:19:13 2002
++++ openssh-3.4p1/ssh-agent.c Sat Jun 29 20:45:37 2002
+@@ -1091,6 +1091,7 @@
+ perror("setenv");
+ exit(1);
+ }
++ log_done();
+ execvp(av[0], av);
+ perror(av[0]);
+ exit(1);
+diff -ur openssh-3.4p1.orig/ssh-rand-helper.c openssh-3.4p1/ssh-rand-helper.c
+--- openssh-3.4p1.orig/ssh-rand-helper.c Sun Jun 9 23:41:49 2002
++++ openssh-3.4p1/ssh-rand-helper.c Sat Jun 29 20:48:36 2002
+@@ -313,7 +313,9 @@
+ close(p[1]);
+ close(devnull);
+
++ log_done();
+ execv(src->path, (char**)(src->args));
++ log_reinit();
+
+ debug("(child) Couldn't exec '%s': %s",
+ src->cmdstring, strerror(errno));
+diff -ur openssh-3.4p1.orig/sshconnect.c openssh-3.4p1/sshconnect.c
+--- openssh-3.4p1.orig/sshconnect.c Mon Jun 24 01:23:20 2002
++++ openssh-3.4p1/sshconnect.c Sat Jun 29 20:47:40 2002
+@@ -127,6 +127,8 @@
+ /* Cannot be 1 because pin allocated two descriptors. */
+ close(pout[1]);
+
++ log_done();
++
+ /* Stderr is left as it is so that error messages get
+ printed on the user's terminal. */
+ argv[0] = _PATH_BSHELL;
+diff -ur openssh-3.4p1.orig/sshconnect2.c openssh-3.4p1/sshconnect2.c
+--- openssh-3.4p1.orig/sshconnect2.c Mon Jun 24 01:23:21 2002
++++ openssh-3.4p1/sshconnect2.c Sat Jun 29 20:46:29 2002
+@@ -937,7 +937,9 @@
+ fatal("ssh_keysign: dup2: %s", strerror(errno));
+ close(from[1]);
+ close(to[0]);
++ log_done();
+ execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);
++ log_reinit();
+ fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,
+ strerror(errno));
+ }
+diff -ur openssh-3.4p1.orig/sshd.c openssh-3.4p1/sshd.c
+--- openssh-3.4p1.orig/sshd.c Wed Jun 26 03:24:19 2002
++++ openssh-3.4p1/sshd.c Sat Jul 6 22:21:36 2002
+@@ -261,7 +261,9 @@
+ log("Received SIGHUP; restarting.");
+ close_listen_socks();
+ close_startup_pipes();
++ log_done();
+ execv(saved_argv[0], saved_argv);
++ log_reinit();
+ log("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
+ strerror(errno));
+ exit(1);
+@@ -1081,7 +1083,7 @@
+ #endif /* TIOCNOTTY */
+ }
+ /* Reinitialize the log (because of the fork above). */
+- log_init(__progname, options.log_level, options.log_facility, log_stderr);
++ log_reinit();
+
+ /* Initialize the random number generator. */
+ arc4random_stir();
+@@ -1335,7 +1337,7 @@
+ close_listen_socks();
+ sock_in = newsock;
+ sock_out = newsock;
+- log_init(__progname, options.log_level, options.log_facility, log_stderr);
++ log_reinit();
+ break;
+ }
+ }
--- /dev/null
+diff -urN openssh-3.4p1-owl-always-auth/Makefile.in openssh-3.4p1/Makefile.in
+--- openssh-3.4p1-owl-always-auth/Makefile.in Wed Jun 26 03:45:42 2002
++++ openssh-3.4p1/Makefile.in Mon Jul 1 23:11:30 2002
+@@ -64,7 +64,7 @@
+
+ SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o
+
+-SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth2-hostbased.o auth2-kbdint.o auth2-none.o auth2-passwd.o auth2-pubkey.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-krb5.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o monitor_mm.o monitor.o
++SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth2-hostbased.o auth2-kbdint.o auth2-none.o auth2-passwd.o auth2-pubkey.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-krb5.o auth-pam.o appl_userpass.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o monitor_mm.o monitor.o
+
+ MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
+ MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
+diff -urN openssh-3.4p1-owl-always-auth/_pam_userpass.h openssh-3.4p1/_pam_userpass.h
+--- openssh-3.4p1-owl-always-auth/_pam_userpass.h Thu Jan 1 03:00:00 1970
++++ openssh-3.4p1/_pam_userpass.h Mon Jul 1 23:11:30 2002
+@@ -0,0 +1,12 @@
++#ifndef __PAM_USERPASS_H
++#define __PAM_USERPASS_H
++
++#define USERPASS_AGENT_ID "userpass"
++#define USERPASS_AGENT_ID_LENGTH 8
++
++#define USERPASS_USER_MASK 0x03
++#define USERPASS_USER_REQUIRED 1
++#define USERPASS_USER_KNOWN 2
++#define USERPASS_USER_FIXED 3
++
++#endif
+diff -urN openssh-3.4p1-owl-always-auth/appl_userpass.c openssh-3.4p1/appl_userpass.c
+--- openssh-3.4p1-owl-always-auth/appl_userpass.c Thu Jan 1 03:00:00 1970
++++ openssh-3.4p1/appl_userpass.c Mon Jul 1 23:11:30 2002
+@@ -0,0 +1,59 @@
++#include <string.h>
++#include <stdlib.h>
++
++#include <security/pam_appl.h>
++#include <security/pam_client.h>
++
++#ifndef PAM_BP_RCONTROL
++/* Linux-PAM prior to 0.74 */
++#define PAM_BP_RCONTROL PAM_BP_CONTROL
++#define PAM_BP_WDATA PAM_BP_DATA
++#define PAM_BP_RDATA PAM_BP_DATA
++#endif
++
++#include "_pam_userpass.h"
++#include "pam_userpass.h"
++
++int pam_userpass_conv(int num_msg, const struct pam_message **msg,
++ struct pam_response **resp, void *appdata_ptr)
++{
++ pam_userpass_t *userpass = (pam_userpass_t *)appdata_ptr;
++ pamc_bp_t prompt;
++ const char *input;
++ char *output;
++ char flags;
++
++ if (num_msg != 1 || msg[0]->msg_style != PAM_BINARY_PROMPT)
++ return PAM_CONV_ERR;
++
++ prompt = (pamc_bp_t)msg[0]->msg;
++ input = PAM_BP_RDATA(prompt);
++
++ if (PAM_BP_RCONTROL(prompt) != PAM_BPC_SELECT ||
++ strncmp(input, USERPASS_AGENT_ID "/", USERPASS_AGENT_ID_LENGTH + 1))
++ return PAM_CONV_ERR;
++
++ flags = input[USERPASS_AGENT_ID_LENGTH + 1];
++ input += USERPASS_AGENT_ID_LENGTH + 1 + 1;
++
++ if ((flags & USERPASS_USER_MASK) == USERPASS_USER_FIXED &&
++ strcmp(input, userpass->user))
++ return PAM_CONV_AGAIN;
++
++ if (!(*resp = malloc(sizeof(struct pam_response))))
++ return PAM_CONV_ERR;
++
++ prompt = NULL;
++ PAM_BP_RENEW(&prompt, PAM_BPC_DONE,
++ strlen(userpass->user) + 1 + strlen(userpass->pass));
++ output = PAM_BP_WDATA(prompt);
++
++ strcpy(output, userpass->user);
++ output += strlen(output) + 1;
++ memcpy(output, userpass->pass, strlen(userpass->pass));
++
++ (*resp)[0].resp_retcode = 0;
++ (*resp)[0].resp = (char *)prompt;
++
++ return PAM_SUCCESS;
++}
+diff -urN openssh-3.4p1-owl-always-auth/auth-pam.c openssh-3.4p1/auth-pam.c
+--- openssh-3.4p1-owl-always-auth/auth-pam.c Mon Jul 1 23:09:55 2002
++++ openssh-3.4p1/auth-pam.c Mon Jul 1 23:38:11 2002
+@@ -34,6 +34,9 @@
+ #include "canohost.h"
+ #include "readpass.h"
+
++#include <security/pam_misc.h>
++#include "pam_userpass.h"
++
+ extern char *__progname;
+
+ RCSID("$Id$");
+@@ -45,13 +48,13 @@
+ struct pam_response **resp, void *appdata_ptr);
+
+ /* module-local variables */
++static pam_userpass_t userpass;
+ static struct pam_conv conv = {
+ do_pam_conversation,
+- NULL
++ &userpass
+ };
+ static char *__pam_msg = NULL;
+ static pam_handle_t *__pamh = NULL;
+-static const char *__pampasswd = NULL;
+
+ /* states for do_pam_conversation() */
+ enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
+@@ -83,18 +86,45 @@
+ * PAM conversation function.
+ * There are two states this can run in.
+ *
+- * INITIAL_LOGIN mode simply feeds the password from the client into
+- * PAM in response to PAM_PROMPT_ECHO_OFF, and collects output
+- * messages with into __pam_msg. This is used during initial
+- * authentication to bypass the normal PAM password prompt.
++ * INITIAL_LOGIN mode simply feeds the username and the password from
++ * the client into PAM via Linux-PAM binary prompts and queues any text
++ * messages for printing later.
+ *
+- * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase()
+- * and outputs messages to stderr. This mode is used if pam_chauthtok()
+- * is called to update expired passwords.
++ * OTHER mode is a regular PAM conversation. This mode is used if
++ * pam_chauthtok() is called to update expired passwords.
+ */
+ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
+ struct pam_response **resp, void *appdata_ptr)
+ {
++ if (pamstate == INITIAL_LOGIN) {
++ int i, status;
++
++ status = pam_userpass_conv(num_msg, msg, resp, appdata_ptr);
++ if (status != PAM_CONV_ERR)
++ return status;
++
++ if (!(*resp = malloc(num_msg * sizeof(struct pam_response))))
++ return PAM_CONV_ERR;
++ for (i = 0; i < num_msg; i++) {
++ switch (msg[i]->msg_style) {
++ case PAM_ERROR_MSG:
++ case PAM_TEXT_INFO:
++ message_cat(&__pam_msg, msg[i]->msg);
++ (*resp)[i].resp_retcode = PAM_SUCCESS;
++ (*resp)[i].resp = NULL;
++ continue;
++ default:
++ free(*resp);
++ *resp = NULL;
++ return PAM_CONV_ERR;
++ }
++ }
++ return PAM_SUCCESS;
++ }
++
++ return misc_conv(num_msg, msg, resp, appdata_ptr);
++
++#if 0
+ struct pam_response *reply;
+ int count;
+ char buf[1024];
+@@ -170,6 +200,7 @@
+ *resp = reply;
+
+ return PAM_SUCCESS;
++#endif
+ }
+
+ /* Called at exit to cleanly shutdown PAM */
+@@ -221,7 +252,8 @@
+ if (*password == '\0' && options.permit_empty_passwd == 0)
+ return 0;
+
+- __pampasswd = password;
++ userpass.user = pw ? pw->pw_name : "ILLEGAL USER";
++ userpass.pass = password;
+
+ pamstate = INITIAL_LOGIN;
+ pam_retval = do_pam_authenticate(
+diff -urN openssh-3.4p1-owl-always-auth/pam_userpass.h openssh-3.4p1/pam_userpass.h
+--- openssh-3.4p1-owl-always-auth/pam_userpass.h Thu Jan 1 03:00:00 1970
++++ openssh-3.4p1/pam_userpass.h Mon Jul 1 23:11:30 2002
+@@ -0,0 +1,14 @@
++#ifndef _PAM_USERPASS_H
++#define _PAM_USERPASS_H
++
++#include <security/pam_appl.h>
++
++typedef struct {
++ const char *user;
++ const char *pass;
++} pam_userpass_t;
++
++extern int pam_userpass_conv(int num_msg, const struct pam_message **msg,
++ struct pam_response **resp, void *appdata_ptr);
++
++#endif
--- /dev/null
+diff -ur openssh-3.4p1.orig/auth-pam.c openssh-3.4p1/auth-pam.c
+--- openssh-3.4p1.orig/auth-pam.c Wed May 8 06:27:56 2002
++++ openssh-3.4p1/auth-pam.c Fri Jul 5 23:39:24 2002
+@@ -29,6 +29,7 @@
+ #include "xmalloc.h"
+ #include "log.h"
+ #include "auth.h"
++#include "auth-options.h"
+ #include "auth-pam.h"
+ #include "servconf.h"
+ #include "canohost.h"
+@@ -36,10 +37,14 @@
+
+ extern char *__progname;
+
++extern int use_privsep;
++
+ RCSID("$Id$");
+
+ #define NEW_AUTHTOK_MSG \
+- "Warning: Your password has expired, please change it now"
++ "Warning: Your password has expired, please change it now."
++#define NEW_AUTHTOK_MSG_PRIVSEP \
++ "Your password has expired, the session cannot proceed."
+
+ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
+ struct pam_response **resp, void *appdata_ptr);
+@@ -55,7 +60,7 @@
+
+ /* states for do_pam_conversation() */
+ enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
+-/* remember whether pam_acct_mgmt() returned PAM_NEWAUTHTOK_REQD */
++/* remember whether pam_acct_mgmt() returned PAM_NEW_AUTHTOK_REQD */
+ static int password_change_required = 0;
+ /* remember whether the last pam_authenticate() succeeded or not */
+ static int was_authenticated = 0;
+@@ -254,13 +259,16 @@
+ case PAM_SUCCESS:
+ /* This is what we want */
+ break;
+-#if 0
+ case PAM_NEW_AUTHTOK_REQD:
+- message_cat(&__pam_msg, NEW_AUTHTOK_MSG);
++ message_cat(&__pam_msg, use_privsep ?
++ NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG);
+ /* flag that password change is necessary */
+ password_change_required = 1;
++ /* disallow other functionality for now */
++ no_port_forwarding_flag |= 2;
++ no_agent_forwarding_flag |= 2;
++ no_x11_forwarding_flag |= 2;
+ break;
+-#endif
+ default:
+ log("PAM rejected by account configuration[%d]: "
+ "%.200s", pam_retval, PAM_STRERROR(__pamh,
+@@ -328,7 +336,7 @@
+ * Have user change authentication token if pam_acct_mgmt() indicated
+ * it was expired. This needs to be called after an interactive
+ * session is established and the user's pty is connected to
+- * stdin/stout/stderr.
++ * stdin/stdout/stderr.
+ */
+ void do_pam_chauthtok(void)
+ {
+@@ -337,11 +345,23 @@
+ do_pam_set_conv(&conv);
+
+ if (password_change_required) {
++ if (use_privsep)
++ fatal("Password changing is currently unsupported"
++ " with privilege separation");
+ pamstate = OTHER;
+ pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+ if (pam_retval != PAM_SUCCESS)
+ fatal("PAM pam_chauthtok failed[%d]: %.200s",
+ pam_retval, PAM_STRERROR(__pamh, pam_retval));
++#if 0
++ /* XXX: This would need to be done in the parent process,
++ * but there's currently no way to pass such request. */
++ no_port_forwarding_flag &= ~2;
++ no_agent_forwarding_flag &= ~2;
++ no_x11_forwarding_flag &= ~2;
++ if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
++ channel_permit_all_opens();
++#endif
+ }
+ }
+