Index: b/sshd.c =================================================================== --- b.orig/sshd.c +++ b/sshd.c @@ -1420,6 +1420,8 @@ server_accept_loop(struct ssh *ssh, int options.log_level, options.log_facility, log_stderr); + + set_log_session_id(); // Set log session ID for this session if (rexec_flag) close(config_s[0]); else { Index: b/auth-pam.c =================================================================== --- b.orig/auth-pam.c +++ b/auth-pam.c @@ -766,7 +766,20 @@ sshpam_init(struct ssh *ssh, Authctxt *a return (-1); } #endif - return (0); + debug("PAM: setting PAM LOG_SESSION_ID to \"%s\"", get_log_session_id()); + { + char log_session_id_env[HOST_NAME_MAX + 50]; + snprintf(log_session_id_env, sizeof(log_session_id_env), + "LOG_SESSION_ID=%s", get_log_session_id()); + sshpam_err = pam_putenv(sshpam_handle, log_session_id_env); + if (sshpam_err != PAM_SUCCESS) { + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + return (-1); + } + } + + return (0); } static void Index: b/log.c =================================================================== --- b.orig/log.c +++ b/log.c @@ -410,17 +410,17 @@ do_log(LogLevel level, int force, const tmp_handler(level, force, fmtbuf, log_handler_ctx); log_handler = tmp_handler; } else if (log_on_stderr) { - snprintf(msgbuf, sizeof msgbuf, "%.*s\r\n", - (int)sizeof msgbuf - 3, fmtbuf); + snprintf(msgbuf, sizeof msgbuf, "%.*s session=%s\r\n", + (int)sizeof msgbuf - 3, fmtbuf, get_log_session_id()); (void)write(log_stderr_fd, msgbuf, strlen(msgbuf)); } else { #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata); - syslog_r(pri, &sdata, "%.500s", fmtbuf); + syslog_r(pri, &sdata, "%.500s session=%s", fmtbuf, get_log_session_id()); closelog_r(&sdata); #else openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility); - syslog(pri, "%.500s", fmtbuf); + syslog(pri, "%.500s session=%s", fmtbuf, get_log_session_id()); closelog(); #endif } @@ -452,6 +452,33 @@ sshlogdie(const char *file, const char * } void +set_log_session_id() +{ + struct timeval tv; + char hostname[HOST_NAME_MAX + 1]; + char session_id[HOST_NAME_MAX + 20]; + char *s; + if (gethostname(hostname, sizeof(hostname)) != 0) { + *hostname = '\0'; + } + gettimeofday(&tv, NULL); + snprintf(session_id, sizeof(session_id), "%s:%x.%x", + hostname, tv.tv_sec, tv.tv_usec); + setenv("LOG_SESSION_ID", session_id, 1); +} + +const char * +get_log_session_id() +{ + const char *id = getenv("LOG_SESSION_ID"); + if (!id) { + set_log_session_id(); + id = getenv("LOG_SESSION_ID"); + } + return id; +} + +void sshsigdie(const char *file, const char *func, int line, int showfunc, LogLevel level, const char *suffix, const char *fmt, ...) { Index: b/regress/session-id.sh =================================================================== --- /dev/null +++ b/regress/session-id.sh @@ -0,0 +1,23 @@ +tid="session id" + +start_sshd + +${SSH} -F $OBJ/ssh_config somehost true +if [ $? -ne 0 ]; then + fail "ssh connect with failed" +fi + +expected="session=$(hostname)" + +# grab the first session ID which will be stable across session +sessionid=$(grep -m1 $expected $TEST_SSHD_LOGFILE | sed -E 's/.*(session=.*)/\1/') + +line_count=$(grep -c $expected $TEST_SSHD_LOGFILE) +if [ $line_count == "0" ]; then + fail "No session ID lines found" +fi + +stable_id_count=$(grep -c $sessionid $TEST_SSHD_LOGFILE) +if [ $line_count != $stable_id_count ]; then + fail 'Mismatching session ids found' +fi Index: b/log.h =================================================================== --- b.orig/log.h +++ b/log.h @@ -68,6 +68,9 @@ const char * log_level_name(LogLevel); void set_log_handler(log_handler_fn *, void *); void cleanup_exit(int) __attribute__((noreturn)); +void set_log_session_id(); +const char * get_log_session_id(); + void sshlog(const char *, const char *, int, int, LogLevel, const char *, const char *, ...) __attribute__((format(printf, 7, 8)));