From 6a17f9c26618db5e9592adabbd53c0d5729c63ea Mon Sep 17 00:00:00 2001 From: damien Date: Thu, 11 Nov 1999 06:57:39 +0000 Subject: [PATCH] - Merged more OpenBSD CVS changes: - [auth-krb4.c auth-passwd.c] remove x11- and krb-cleanup from fatal() + krb-cleanup cleanup - [clientloop.c log-client.c log-server.c ] [readconf.c readconf.h servconf.c servconf.h ] [ssh.1 ssh.c ssh.h sshd.8] add LogLevel {QUIET, FATAL, ERROR, INFO, CHAT, DEBUG} to ssh/sshd, obsoletes QuietMode and FascistLogging in sshd. --- ChangeLog | 11 ++- Makefile.in | 2 +- acconfig.h | 14 ++++ auth-krb4.c | 118 +++++++++++++++++------------ auth-passwd.c | 30 +++----- clientloop.c | 5 +- log-client.c | 135 ++++++++-------------------------- log-server.c | 200 ++++++++++++++------------------------------------ log.c | 135 ++++++++++++++++++++++++++++++++++ readconf.c | 46 +++++++++++- readconf.h | 1 + servconf.c | 60 ++++++++++----- servconf.h | 3 +- ssh.1 | 6 ++ ssh.c | 14 ++-- ssh.h | 130 +++++++++++++++----------------- sshd.8 | 26 +++---- sshd.c | 64 +++++++++------- 18 files changed, 538 insertions(+), 462 deletions(-) create mode 100644 log.c diff --git a/ChangeLog b/ChangeLog index a1bfb211..4971a442 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,8 +7,15 @@ - [sshd.8] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too - Fix integer overflow which was messing up scp's progress bar for large file transfers. Fix submitted to OpenBSD developers. - - Released 1.2pre10 - + - Merged more OpenBSD CVS changes: + - [auth-krb4.c auth-passwd.c] remove x11- and krb-cleanup from fatal() + + krb-cleanup cleanup + - [clientloop.c log-client.c log-server.c ] + [readconf.c readconf.h servconf.c servconf.h ] + [ssh.1 ssh.c ssh.h sshd.8] + add LogLevel {QUIET, FATAL, ERROR, INFO, CHAT, DEBUG} to ssh/sshd, + obsoletes QuietMode and FascistLogging in sshd. + 19991110 - Merged several minor fixed: - ssh-agent commandline parsing diff --git a/Makefile.in b/Makefile.in index 0d239e88..bd7950a5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -30,7 +30,7 @@ OBJS= authfd.o authfile.o auth-passwd.o auth-rhosts.o auth-rh-rsa.o \ all: $(OBJS) $(TARGETS) -libssh.a: authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o hostfile.o match.o mpaux.o nchan.o packet.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o helper.o rc4.o mktemp.o strlcpy.o +libssh.a: authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o hostfile.o match.o mpaux.o nchan.o packet.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o helper.o rc4.o mktemp.o strlcpy.o log.o $(AR) rv $@ $^ $(RANLIB) $@ diff --git a/acconfig.h b/acconfig.h index 063b9171..56075fd9 100644 --- a/acconfig.h +++ b/acconfig.h @@ -20,3 +20,17 @@ /* Define is libutil has login() function */ #undef HAVE_LIBUTIL_LOGIN + + +/* Shouldn't need to edit below this line *************************** */ +#ifndef SHUT_RDWR +enum +{ + SHUT_RD = 0, /* No more receptions. */ +#define SHUT_RD SHUT_RD + SHUT_WR, /* No more transmissions. */ +#define SHUT_WR SHUT_WR + SHUT_RDWR /* No more receptions or transmissions. */ +#define SHUT_RDWR SHUT_RDWR +}; +#endif diff --git a/auth-krb4.c b/auth-krb4.c index 556fef16..fc26a708 100644 --- a/auth-krb4.c +++ b/auth-krb4.c @@ -15,38 +15,59 @@ #include "ssh.h" #ifdef KRB4 -int ssh_tf_init(uid_t uid) +char *ticket = NULL; + +void +krb4_cleanup_proc(void *ignore) +{ + debug("krb4_cleanup_proc called"); + + if (ticket) { + (void) dest_tkt(); + xfree(ticket); + ticket = NULL; + } +} + +int krb4_init(uid_t uid) { - extern char *ticket; + static int cleanup_registered = 0; char *tkt_root = TKT_ROOT; struct stat st; int fd; - - /* Set unique ticket string manually since we're still root. */ - ticket = xmalloc(MAXPATHLEN); + + if (!ticket) { + /* Set unique ticket string manually since we're still root. */ + ticket = xmalloc(MAXPATHLEN); #ifdef AFS - if (lstat("/ticket", &st) != -1) - tkt_root = "/ticket/"; + if (lstat("/ticket", &st) != -1) + tkt_root = "/ticket/"; #endif /* AFS */ - snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid()); - (void) krb_set_tkt_string(ticket); - - /* Make sure we own this ticket file, and we created it. */ - if (lstat(ticket, &st) == -1 && errno == ENOENT) { - /* good, no ticket file exists. create it. */ - if ((fd = open(ticket, O_RDWR|O_CREAT|O_EXCL, 0600)) != -1) { - close(fd); - return 1; - } + snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid()); + (void) krb_set_tkt_string(ticket); + } + /* Register ticket cleanup in case of fatal error. */ + if (!cleanup_registered) { + fatal_add_cleanup(krb4_cleanup_proc, NULL); + cleanup_registered = 1; + } + /* Try to create our ticket file. */ + if ((fd = mkstemp(ticket)) != -1) { + close(fd); + return 1; } - else { - /* file exists. make sure server_user owns it (e.g. just passed ticket), - and that it isn't a symlink, and that it is mode 600. */ + /* Ticket file exists - make sure user owns it (just passed ticket). */ + if (lstat(ticket, &st) != -1) { if (st.st_mode == (S_IFREG|S_IRUSR|S_IWUSR) && st.st_uid == uid) return 1; } - /* Failure. */ + /* Failure - cancel cleanup function, leaving bad ticket for inspection. */ log("WARNING: bad ticket file %s", ticket); + fatal_remove_cleanup(krb4_cleanup_proc, NULL); + cleanup_registered = 0; + xfree(ticket); + ticket = NULL; + return 0; } @@ -103,8 +124,7 @@ int auth_krb4(const char *server_user, KTEXT auth, char **client) reply.dat[0] = 0; reply.length = 0; } - else - reply.length = r; + else reply.length = r; /* Clear session key. */ memset(&adat.session, 0, sizeof(&adat.session)); @@ -121,8 +141,6 @@ int auth_krb4(const char *server_user, KTEXT auth, char **client) int auth_kerberos_tgt(struct passwd *pw, const char *string) { CREDENTIALS creds; - extern char *ticket; - int r; if (!radix_to_creds(string, &creds)) { log("Protocol error decoding Kerberos V4 tgt"); @@ -133,37 +151,39 @@ int auth_kerberos_tgt(struct passwd *pw, const char *string) strlcpy(creds.service, "krbtgt", sizeof creds.service); if (strcmp(creds.service, "krbtgt")) { - log("Kerberos V4 tgt (%s%s%s@%s) rejected for uid %d", - creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm, - pw->pw_uid); - packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for uid %d", + log("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", creds.pname, + creds.pinst[0] ? "." : "", creds.pinst, creds.realm, pw->pw_name); + packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", creds.pname, creds.pinst[0] ? "." : "", creds.pinst, - creds.realm, pw->pw_uid); + creds.realm, pw->pw_name); goto auth_kerberos_tgt_failure; } - if (!ssh_tf_init(pw->pw_uid) || - (r = in_tkt(creds.pname, creds.pinst)) || - (r = save_credentials(creds.service, creds.instance, creds.realm, - creds.session, creds.lifetime, creds.kvno, - &creds.ticket_st, creds.issue_date))) { - xfree(ticket); - ticket = NULL; + if (!krb4_init(pw->pw_uid)) + goto auth_kerberos_tgt_failure; + + if (in_tkt(creds.pname, creds.pinst) != KSUCCESS) + goto auth_kerberos_tgt_failure; + + if (save_credentials(creds.service, creds.instance, creds.realm, + creds.session, creds.lifetime, creds.kvno, + &creds.ticket_st, creds.issue_date) != KSUCCESS) { packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials"); goto auth_kerberos_tgt_failure; } /* Successful authentication, passed all checks. */ - chown(ticket, pw->pw_uid, pw->pw_gid); - packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)", - creds.service, creds.instance, creds.realm, - creds.pname, creds.pinst[0] ? "." : "", - creds.pinst, creds.realm); + chown(tkt_string(), pw->pw_uid, pw->pw_gid); + packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)", + creds.service, creds.instance, creds.realm, creds.pname, + creds.pinst[0] ? "." : "", creds.pinst, creds.realm); + memset(&creds, 0, sizeof(creds)); packet_start(SSH_SMSG_SUCCESS); packet_send(); packet_write_wait(); return 1; - -auth_kerberos_tgt_failure: + + auth_kerberos_tgt_failure: + krb4_cleanup_proc(NULL); memset(&creds, 0, sizeof(creds)); packet_start(SSH_SMSG_FAILURE); packet_send(); @@ -191,10 +211,11 @@ int auth_afs_token(struct passwd *pw, const char *token_string) uid = atoi(creds.pname + 7); if (kafs_settoken(creds.realm, uid, &creds)) { - log("AFS token (%s@%s) rejected for uid %d", creds.pname, - creds.realm, uid); - packet_send_debug("AFS token (%s@%s) rejected for uid %d", creds.pname, - creds.realm, uid); + log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm, + pw->pw_name); + packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname, + creds.realm, pw->pw_name); + memset(&creds, 0, sizeof(creds)); packet_start(SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); @@ -202,6 +223,7 @@ int auth_afs_token(struct passwd *pw, const char *token_string) } packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service, creds.realm, creds.pname, creds.realm); + memset(&creds, 0, sizeof(creds)); packet_start(SSH_SMSG_SUCCESS); packet_send(); packet_write_wait(); diff --git a/auth-passwd.c b/auth-passwd.c index 27d2818a..9e7e0069 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -22,10 +22,6 @@ RCSID("$Id$"); #include "servconf.h" #include "xmalloc.h" -#ifdef KRB4 -extern char *ticket; -#endif /* KRB4 */ - /* Tries to authenticate the user using password. Returns true if authentication succeeds. */ @@ -80,9 +76,9 @@ int auth_password(struct passwd *pw, const char *password) KTEXT_ST tkt; struct hostent *hp; unsigned long faddr; - char localhost[MAXHOSTNAMELEN]; /* local host name */ - char phost[INST_SZ]; /* host instance */ - char realm[REALM_SZ]; /* local Kerberos realm */ + char localhost[MAXHOSTNAMELEN]; + char phost[INST_SZ]; + char realm[REALM_SZ]; int r; /* Try Kerberos password authentication only for non-root @@ -90,9 +86,8 @@ int auth_password(struct passwd *pw, const char *password) if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { /* Set up our ticket file. */ - if (!ssh_tf_init(pw->pw_uid)) { - log("Couldn't initialize Kerberos ticket file for %s!", - pw->pw_name); + if (!krb4_init(pw->pw_uid)) { + log("Couldn't initialize Kerberos ticket file for %s!", pw->pw_name); goto kerberos_auth_failure; } /* Try to get TGT using our password. */ @@ -104,13 +99,12 @@ int auth_password(struct passwd *pw, const char *password) goto kerberos_auth_failure; } /* Successful authentication. */ - chown(ticket, pw->pw_uid, pw->pw_gid); - - (void) gethostname(localhost, sizeof(localhost)); - (void) strlcpy(phost, (char *)krb_get_phost(localhost), INST_SZ); + chown(tkt_string(), pw->pw_uid, pw->pw_gid); /* Now that we have a TGT, try to get a local "rcmd" ticket to ensure that we are not talking to a bogus Kerberos server. */ + (void) gethostname(localhost, sizeof(localhost)); + (void) strlcpy(phost, (char *)krb_get_phost(localhost), INST_SZ); r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); if (r == KSUCCESS) { @@ -150,10 +144,10 @@ int auth_password(struct passwd *pw, const char *password) return 1; kerberos_auth_failure: - (void) dest_tkt(); - xfree(ticket); - ticket = NULL; - if (!options.kerberos_or_local_passwd ) return 0; + krb4_cleanup_proc(NULL); + + if (!options.kerberos_or_local_passwd) + return 0; } else { /* Logging in as root or no local Kerberos realm. */ diff --git a/clientloop.c b/clientloop.c index b797f819..708566b9 100644 --- a/clientloop.c +++ b/clientloop.c @@ -22,9 +22,10 @@ RCSID("$Id$"); #include "packet.h" #include "buffer.h" #include "authfd.h" +#include "readconf.h" /* Flag indicating whether quiet mode is on. */ -extern int quiet_flag; +extern Options options; /* Flag indicating that stdin should be redirected from /dev/null. */ extern int stdin_null_flag; @@ -866,7 +867,7 @@ int client_loop(int have_pty, int escape_char_arg) /* In interactive mode (with pseudo tty) display a message indicating that the connection has been closed. */ - if (have_pty && !quiet_flag) + if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); buffer_append(&stderr_buffer, buf, strlen(buf)); diff --git a/log-client.c b/log-client.c index 1e2be077..18700cdb 100644 --- a/log-client.c +++ b/log-client.c @@ -10,6 +10,7 @@ Copyright (c) 1995 Tatu Ylonen , Espoo, Finland Created: Mon Mar 20 21:13:40 1995 ylo Client-side versions of debug(), log(), etc. These print to stderr. +This is a stripped down version of log-server.c. */ @@ -19,120 +20,44 @@ RCSID("$Id$"); #include "xmalloc.h" #include "ssh.h" -static int log_debug = 0; -static int log_quiet = 0; +static LogLevel log_level = SYSLOG_LEVEL_INFO; -void log_init(char *av0, int on_stderr, int debug, int quiet, - SyslogFacility facility) -{ - log_debug = debug; - log_quiet = quiet; -} - -void log(const char *fmt, ...) -{ - va_list args; - - if (log_quiet) - return; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\r\n"); - va_end(args); -} - -void debug(const char *fmt, ...) -{ - va_list args; - if (log_quiet || !log_debug) - return; - va_start(args, fmt); - fprintf(stderr, "debug: "); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\r\n"); - va_end(args); -} - -void error(const char *fmt, ...) -{ - va_list args; - if (log_quiet) - return; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\r\n"); - va_end(args); -} - -struct fatal_cleanup -{ - struct fatal_cleanup *next; - void (*proc)(void *); - void *context; -}; - -static struct fatal_cleanup *fatal_cleanups = NULL; - -/* Registers a cleanup function to be called by fatal() before exiting. */ - -void fatal_add_cleanup(void (*proc)(void *), void *context) -{ - struct fatal_cleanup *cu; +/* Initialize the log. + av0 program name (should be argv[0]) + level logging level + */ - cu = xmalloc(sizeof(*cu)); - cu->proc = proc; - cu->context = context; - cu->next = fatal_cleanups; - fatal_cleanups = cu; -} - -/* Removes a cleanup frunction to be called at fatal(). */ - -void fatal_remove_cleanup(void (*proc)(void *context), void *context) +void +log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2) { - struct fatal_cleanup **cup, *cu; - - for (cup = &fatal_cleanups; *cup; cup = &cu->next) + switch (level) { - cu = *cup; - if (cu->proc == proc && cu->context == context) - { - *cup = cu->next; - xfree(cu); - return; - } + case SYSLOG_LEVEL_QUIET: + case SYSLOG_LEVEL_ERROR: + case SYSLOG_LEVEL_FATAL: + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_CHAT: + case SYSLOG_LEVEL_DEBUG: + log_level = level; + break; + default: + /* unchanged */ + break; } - fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", - (unsigned long)proc, (unsigned long)context); } -/* Function to display an error message and exit. This is in this file because - this needs to restore terminal modes before exiting. See log-client.c - for other related functions. */ +#define MSGBUFSIZE 1024 -void fatal(const char *fmt, ...) +void +do_log(LogLevel level, const char *fmt, va_list args) { - va_list args; - struct fatal_cleanup *cu, *next_cu; - static int fatal_called = 0; - - if (!fatal_called) - { - fatal_called = 1; + char msgbuf[MSGBUFSIZE]; - /* Call cleanup functions. */ - for (cu = fatal_cleanups; cu; cu = next_cu) - { - next_cu = cu->next; - (*cu->proc)(cu->context); - } - } - - va_start(args, fmt); - vfprintf(stderr, fmt, args); + if (level > log_level) + return; + if (level == SYSLOG_LEVEL_DEBUG) + fprintf(stderr, "debug: "); + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + fprintf(stderr, "%s", msgbuf); fprintf(stderr, "\r\n"); - va_end(args); - exit(255); } - -/* fatal() is in ssh.c so that it can properly reset terminal modes. */ diff --git a/log-server.c b/log-server.c index b2bef645..8aa20928 100644 --- a/log-server.c +++ b/log-server.c @@ -22,22 +22,35 @@ RCSID("$Id$"); #include "xmalloc.h" #include "ssh.h" -static int log_debug = 0; -static int log_quiet = 0; +static LogLevel log_level = SYSLOG_LEVEL_INFO; static int log_on_stderr = 0; /* Initialize the log. av0 program name (should be argv[0]) on_stderr print also on stderr - debug send debugging messages to system log - quiet don\'t log anything + level logging level */ -void log_init(char *av0, int on_stderr, int debug, int quiet, - SyslogFacility facility) +void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) { int log_facility; + switch (level) + { + case SYSLOG_LEVEL_QUIET: + case SYSLOG_LEVEL_ERROR: + case SYSLOG_LEVEL_FATAL: + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_CHAT: + case SYSLOG_LEVEL_DEBUG: + log_level = level; + break; + default: + fprintf(stderr, "Unrecognized internal syslog level code %d\n", + (int)level); + exit(1); + } + switch (facility) { case SYSLOG_FACILITY_DAEMON: @@ -79,8 +92,6 @@ void log_init(char *av0, int on_stderr, int debug, int quiet, exit(1); } - log_debug = debug; - log_quiet = quiet; log_on_stderr = on_stderr; closelog(); /* Close any previous log. */ openlog(av0, LOG_PID, log_facility); @@ -88,146 +99,49 @@ void log_init(char *av0, int on_stderr, int debug, int quiet, #define MSGBUFSIZE 1024 -#define DECL_MSGBUF char msgbuf[MSGBUFSIZE] - -/* Log this message (information that usually should go to the log). */ - -void log(const char *fmt, ...) -{ - va_list args; - DECL_MSGBUF; - if (log_quiet) - return; - va_start(args, fmt); - vsnprintf(msgbuf, MSGBUFSIZE, fmt, args); - va_end(args); - if (log_on_stderr) - fprintf(stderr, "log: %s\n", msgbuf); - syslog(LOG_INFO, "log: %.500s", msgbuf); -} - -/* Debugging messages that should not be logged during normal operation. */ - -void debug(const char *fmt, ...) +void +do_log(LogLevel level, const char *fmt, va_list args) { - va_list args; - DECL_MSGBUF; - if (!log_debug || log_quiet) - return; - va_start(args, fmt); - vsnprintf(msgbuf, MSGBUFSIZE, fmt, args); - va_end(args); - if (log_on_stderr) - fprintf(stderr, "debug: %s\n", msgbuf); - syslog(LOG_DEBUG, "debug: %.500s", msgbuf); -} + char msgbuf[MSGBUFSIZE]; + char fmtbuf[MSGBUFSIZE]; + char *txt = NULL; + int pri = LOG_INFO; -/* Error messages that should be logged. */ - -void error(const char *fmt, ...) -{ - va_list args; - DECL_MSGBUF; - if (log_quiet) + if (level > log_level) return; - va_start(args, fmt); - vsnprintf(msgbuf, MSGBUFSIZE, fmt, args); - va_end(args); - if (log_on_stderr) - fprintf(stderr, "error: %s\n", msgbuf); - syslog(LOG_ERR, "error: %.500s", msgbuf); -} - -struct fatal_cleanup -{ - struct fatal_cleanup *next; - void (*proc)(void *); - void *context; -}; - -static struct fatal_cleanup *fatal_cleanups = NULL; - -/* Registers a cleanup function to be called by fatal() before exiting. */ - -void fatal_add_cleanup(void (*proc)(void *), void *context) -{ - struct fatal_cleanup *cu; - - cu = xmalloc(sizeof(*cu)); - cu->proc = proc; - cu->context = context; - cu->next = fatal_cleanups; - fatal_cleanups = cu; -} - -/* Removes a cleanup frunction to be called at fatal(). */ - -void fatal_remove_cleanup(void (*proc)(void *context), void *context) -{ - struct fatal_cleanup **cup, *cu; - - for (cup = &fatal_cleanups; *cup; cup = &cu->next) + switch (level) { - cu = *cup; - if (cu->proc == proc && cu->context == context) - { - *cup = cu->next; - xfree(cu); - return; - } + case SYSLOG_LEVEL_ERROR: + txt = "error"; + pri = LOG_ERR; + break; + case SYSLOG_LEVEL_FATAL: + txt = "fatal"; + pri = LOG_ERR; + break; + case SYSLOG_LEVEL_INFO: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_CHAT: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_DEBUG: + txt = "debug"; + pri = LOG_DEBUG; + break; + default: + txt = "internal error"; + pri = LOG_ERR; + break; } - fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", - (unsigned long)proc, (unsigned long)context); -} - -/* Fatal messages. This function never returns. */ -void fatal(const char *fmt, ...) -{ - va_list args; - struct fatal_cleanup *cu, *next_cu; - static int fatal_called = 0; -#if defined(KRB4) - extern char *ticket; -#endif /* KRB4 */ - DECL_MSGBUF; - - if (log_quiet) - exit(1); - va_start(args, fmt); - vsnprintf(msgbuf, MSGBUFSIZE, fmt, args); - va_end(args); + if (txt != NULL) { + snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt); + vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args); + }else{ + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + } if (log_on_stderr) - fprintf(stderr, "fatal: %s\n", msgbuf); - syslog(LOG_ERR, "fatal: %.500s", msgbuf); - - if (fatal_called) - exit(1); - fatal_called = 1; - - /* Call cleanup functions. */ - for (cu = fatal_cleanups; cu; cu = next_cu) - { - next_cu = cu->next; - debug("Calling cleanup 0x%lx(0x%lx)", - (unsigned long)cu->proc, (unsigned long)cu->context); - (*cu->proc)(cu->context); - } -#if defined(KRB4) - /* If you forwarded a ticket you get one shot for proper - authentication. */ - /* If tgt was passed unlink file */ - if (ticket) - { - if (strcmp(ticket,"none")) - unlink(ticket); - else - ticket = NULL; - } -#endif /* KRB4 */ - - /* If local XAUTHORITY was created, remove it. */ - if (xauthfile) unlink(xauthfile); - - exit(1); + fprintf(stderr, "%s\n", msgbuf); + syslog(pri, "%.500s", msgbuf); } diff --git a/log.c b/log.c new file mode 100644 index 00000000..3e840ecb --- /dev/null +++ b/log.c @@ -0,0 +1,135 @@ +/* + +Shared versions of debug(), log(), etc. + +*/ + +#include "includes.h" +RCSID("$OpenBSD: log.c,v 1.1 1999/11/10 23:36:44 markus Exp $"); + +#include "ssh.h" +#include "xmalloc.h" + +/* Fatal messages. This function never returns. */ + +void +fatal(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_FATAL, fmt, args); + va_end(args); + fatal_cleanup(); +} + +/* Error messages that should be logged. */ + +void +error(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_ERROR, fmt, args); + va_end(args); +} + +/* Log this message (information that usually should go to the log). */ + +void +log(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_INFO, fmt, args); + va_end(args); +} + +/* More detailed messages (information that does not need to go to the log). */ + +void +chat(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_CHAT, fmt, args); + va_end(args); +} + +/* Debugging messages that should not be logged during normal operation. */ + +void +debug(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_DEBUG, fmt, args); + va_end(args); +} + +/* Fatal cleanup */ + +struct fatal_cleanup +{ + struct fatal_cleanup *next; + void (*proc)(void *); + void *context; +}; + +static struct fatal_cleanup *fatal_cleanups = NULL; + +/* Registers a cleanup function to be called by fatal() before exiting. */ + +void +fatal_add_cleanup(void (*proc)(void *), void *context) +{ + struct fatal_cleanup *cu; + + cu = xmalloc(sizeof(*cu)); + cu->proc = proc; + cu->context = context; + cu->next = fatal_cleanups; + fatal_cleanups = cu; +} + +/* Removes a cleanup frunction to be called at fatal(). */ + +void +fatal_remove_cleanup(void (*proc)(void *context), void *context) +{ + struct fatal_cleanup **cup, *cu; + + for (cup = &fatal_cleanups; *cup; cup = &cu->next) + { + cu = *cup; + if (cu->proc == proc && cu->context == context) + { + *cup = cu->next; + xfree(cu); + return; + } + } + fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", + (unsigned long)proc, (unsigned long)context); +} + +/* Cleanup and exit */ +void +fatal_cleanup(void) +{ + struct fatal_cleanup *cu, *next_cu; + static int called = 0; + if (called) + exit(255); + called = 1; + + /* Call cleanup functions. */ + for (cu = fatal_cleanups; cu; cu = next_cu) + { + next_cu = cu->next; + debug("Calling cleanup 0x%lx(0x%lx)", + (unsigned long)cu->proc, (unsigned long)cu->context); + (*cu->proc)(cu->context); + } + + exit(255); +} diff --git a/readconf.c b/readconf.c index 50f29261..e9b251a9 100644 --- a/readconf.c +++ b/readconf.c @@ -101,7 +101,7 @@ typedef enum oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, - oUsePrivilegedPort + oUsePrivilegedPort, oLogLevel } OpCodes; /* Textual representations of the tokens. */ @@ -150,6 +150,24 @@ static struct { "keepalive", oKeepAlives }, { "numberofpasswordprompts", oNumberOfPasswordPrompts }, { "tisauthentication", oTISAuthentication }, + { "loglevel", oLogLevel }, + { 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 } }; @@ -218,7 +236,7 @@ void process_config_line(Options *options, const char *host, int *activep) { char buf[256], *cp, *string, **charptr; - int opcode, *intptr, value, fwd_port, fwd_host_port; + int opcode, *intptr, value, fwd_port, fwd_host_port, i; /* Skip leading whitespace. */ cp = line + strspn(line, WHITESPACE); @@ -445,6 +463,27 @@ void process_config_line(Options *options, const char *host, if (*activep && *intptr == -1) *intptr = value; break; + + case oLogLevel: + 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; + break; case oRemoteForward: cp = strtok(NULL, WHITESPACE); @@ -607,6 +646,7 @@ void initialize_options(Options *options) options->user_hostfile = NULL; options->num_local_forwards = 0; options->num_remote_forwards = 0; + options->log_level = (LogLevel)-1; } /* Called after processing other sources of option data, this fills those @@ -677,6 +717,8 @@ void fill_default_options(Options *options) options->system_hostfile = SSH_SYSTEM_HOSTFILE; if (options->user_hostfile == NULL) options->user_hostfile = SSH_USER_HOSTFILE; + if (options->log_level == (LogLevel)-1) + options->log_level = SYSLOG_LEVEL_INFO; /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ /* options->hostname will be set in the main program if appropriate */ diff --git a/readconf.h b/readconf.h index 25d02e65..06337752 100644 --- a/readconf.h +++ b/readconf.h @@ -54,6 +54,7 @@ typedef struct int compression; /* Compress packets in both directions. */ int compression_level; /* Compression level 1 (fast) to 9 (best). */ int keepalives; /* Set SO_KEEPALIVE. */ + LogLevel log_level; /* Level for logging. */ int port; /* Port to connect. */ int connection_attempts; /* Max attempts (seconds) before giving up */ diff --git a/servconf.c b/servconf.c index 8c95a9af..6943b2b5 100644 --- a/servconf.c +++ b/servconf.c @@ -31,8 +31,6 @@ void initialize_server_options(ServerOptions *options) options->key_regeneration_time = -1; options->permit_root_login = -1; options->ignore_rhosts = -1; - options->quiet_mode = -1; - options->fascist_logging = -1; options->print_motd = -1; options->check_mail = -1; options->x11_forwarding = -1; @@ -40,6 +38,7 @@ void initialize_server_options(ServerOptions *options) options->strict_modes = -1; options->keepalives = -1; options->log_facility = (SyslogFacility)-1; + options->log_level = (LogLevel)-1; options->rhosts_authentication = -1; options->rhosts_rsa_authentication = -1; options->rsa_authentication = -1; @@ -89,12 +88,8 @@ void fill_default_server_options(ServerOptions *options) options->permit_root_login = 1; /* yes */ if (options->ignore_rhosts == -1) options->ignore_rhosts = 0; - if (options->quiet_mode == -1) - options->quiet_mode = 0; if (options->check_mail == -1) options->check_mail = 0; - if (options->fascist_logging == -1) - options->fascist_logging = 1; if (options->print_motd == -1) options->print_motd = 1; if (options->x11_forwarding == -1) @@ -107,6 +102,8 @@ void fill_default_server_options(ServerOptions *options) options->keepalives = 1; if (options->log_facility == (SyslogFacility)(-1)) options->log_facility = SYSLOG_FACILITY_AUTH; + if (options->log_level == (LogLevel)(-1)) + options->log_level = SYSLOG_LEVEL_INFO; if (options->rhosts_authentication == -1) options->rhosts_authentication = 0; if (options->rhosts_rsa_authentication == -1) @@ -145,7 +142,7 @@ void fill_default_server_options(ServerOptions *options) typedef enum { sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, - sPermitRootLogin, sQuietMode, sFascistLogging, sLogFacility, + sPermitRootLogin, sLogFacility, sLogLevel, sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, #ifdef KRB4 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, @@ -176,9 +173,8 @@ static struct { "logingracetime", sLoginGraceTime }, { "keyregenerationinterval", sKeyRegenerationTime }, { "permitrootlogin", sPermitRootLogin }, - { "quietmode", sQuietMode }, - { "fascistlogging", sFascistLogging }, { "syslogfacility", sLogFacility }, + { "loglevel", sLogLevel }, { "rhostsauthentication", sRhostsAuthentication }, { "rhostsrsaauthentication", sRhostsRSAAuthentication }, { "rsaauthentication", sRSAAuthentication }, @@ -233,6 +229,21 @@ static struct { 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. */ @@ -392,14 +403,6 @@ void read_server_config(ServerOptions *options, const char *filename) *intptr = value; break; - case sQuietMode: - intptr = &options->quiet_mode; - goto parse_flag; - - case sFascistLogging: - intptr = &options->fascist_logging; - goto parse_flag; - case sRhostsAuthentication: intptr = &options->rhosts_authentication; goto parse_flag; @@ -487,7 +490,7 @@ void read_server_config(ServerOptions *options, const char *filename) exit(1); } for (i = 0; log_facilities[i].name; i++) - if (strcmp(log_facilities[i].name, cp) == 0) + if (strcasecmp(log_facilities[i].name, cp) == 0) break; if (!log_facilities[i].name) { @@ -498,6 +501,27 @@ void read_server_config(ServerOptions *options, const char *filename) if (options->log_facility == (SyslogFacility)(-1)) options->log_facility = log_facilities[i].facility; break; + + case sLogLevel: + 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; + break; case sAllowUsers: while ((cp = strtok(NULL, WHITESPACE))) diff --git a/servconf.h b/servconf.h index 8c630fce..86bad5bf 100644 --- a/servconf.h +++ b/servconf.h @@ -33,8 +33,6 @@ typedef struct int key_regeneration_time; /* Server key lifetime (seconds). */ int permit_root_login; /* If true, permit root login. */ int ignore_rhosts; /* Ignore .rhosts and .shosts. */ - int quiet_mode; /* If true, don't log anything but fatals. */ - int fascist_logging; /* Perform very verbose logging. */ int print_motd; /* If true, print /etc/motd. */ int check_mail; /* If true, check for new mail. */ int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ @@ -42,6 +40,7 @@ typedef struct int strict_modes; /* If true, require string home dir modes. */ int keepalives; /* If true, set SO_KEEPALIVE. */ SyslogFacility log_facility; /* Facility for system logging. */ + LogLevel log_level; /* Level for system logging. */ int rhosts_authentication; /* If true, permit rhosts authentication. */ int rhosts_rsa_authentication;/* If true, permit rhosts RSA authentication.*/ int rsa_authentication; /* If true, permit RSA authentication. */ diff --git a/ssh.1 b/ssh.1 index b3b2f236..31e4c6db 100644 --- a/ssh.1 +++ b/ssh.1 @@ -602,6 +602,12 @@ this keyword must be .Dq yes or .Dq no . +.It Cm LogLevel +Gives the verbosity level that is used when logging messages from +.Nm ssh . +The possible values are: +QUIET, FATAL, ERROR, INFO, CHAT and DEBUG. +The default is INFO. .It Cm NumberOfPasswordPrompts Specifies the number of password prompts before giving up. The argument to this keyword must be an integer. Default is 3. diff --git a/ssh.c b/ssh.c index a16c5199..a7a1cfef 100644 --- a/ssh.c +++ b/ssh.c @@ -32,9 +32,6 @@ RCSID("$Id$"); command line. */ int debug_flag = 0; -/* Flag indicating whether quiet mode is on. */ -int quiet_flag = 0; - /* Flag indicating whether to allocate a pseudo tty. This can be set on the command line, and is automatically set if no command is given on the command line. */ @@ -306,16 +303,17 @@ main(int ac, char **av) case 'v': case 'V': - debug_flag = 1; fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n", SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR); fprintf(stderr, "Compiled with SSL.\n"); if (opt == 'V') exit(0); + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG; break; case 'q': - quiet_flag = 1; + options.log_level = SYSLOG_LEVEL_QUIET; break; case 'e': @@ -466,7 +464,7 @@ main(int ac, char **av) /* Initialize "log" output. Since we are the client all output actually goes to the terminal. */ - log_init(av[0], 1, debug_flag, quiet_flag, SYSLOG_FACILITY_USER); + log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); /* Read per-user configuration file. */ snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_CONFFILE); @@ -477,6 +475,10 @@ main(int ac, char **av) /* Fill configuration defaults. */ fill_default_options(&options); + + /* reinit */ + log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); + if (options.user == NULL) options.user = xstrdup(pw->pw_name); diff --git a/ssh.h b/ssh.h index 2aaaa52c..28bbd28b 100644 --- a/ssh.h +++ b/ssh.h @@ -20,19 +20,7 @@ Generic header file for ssh. #include /* For struct sockaddr_in */ #include /* For struct pw */ - -#ifndef SHUT_RDWR -enum -{ - SHUT_RD = 0, /* No more receptions. */ -#define SHUT_RD SHUT_RD - SHUT_WR, /* No more transmissions. */ -#define SHUT_WR SHUT_WR - SHUT_RDWR /* No more receptions or transmissions. */ -#define SHUT_RDWR SHUT_RDWR -}; -#endif - +#include /* For va_list */ #include "rsa.h" #include "cipher.h" @@ -234,9 +222,58 @@ only by root, whereas ssh_config should be world-readable. */ #define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */ -/* Includes that need definitions above. */ +/*------------ Definitions for logging. -----------------------*/ + +/* Supported syslog facilities and levels. */ +typedef enum +{ + SYSLOG_FACILITY_DAEMON, + SYSLOG_FACILITY_USER, + SYSLOG_FACILITY_AUTH, + SYSLOG_FACILITY_LOCAL0, + SYSLOG_FACILITY_LOCAL1, + SYSLOG_FACILITY_LOCAL2, + SYSLOG_FACILITY_LOCAL3, + SYSLOG_FACILITY_LOCAL4, + SYSLOG_FACILITY_LOCAL5, + SYSLOG_FACILITY_LOCAL6, + SYSLOG_FACILITY_LOCAL7 +} SyslogFacility; + +typedef enum +{ + SYSLOG_LEVEL_QUIET, + SYSLOG_LEVEL_FATAL, + SYSLOG_LEVEL_ERROR, + SYSLOG_LEVEL_INFO, + SYSLOG_LEVEL_CHAT, + SYSLOG_LEVEL_DEBUG +} LogLevel; + +/* Initializes logging. */ +void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr); + +/* Logging implementation, depending on server or client */ +void do_log(LogLevel level, const char *fmt, va_list args); + +/* Output a message to syslog or stderr */ +void fatal(const char *fmt, ...); +void error(const char *fmt, ...); +void log(const char *fmt, ...); +void chat(const char *fmt, ...); +void debug(const char *fmt, ...); + +/* same as fatal() but w/o logging */ +void fatal_cleanup(void); + +/* Registers a cleanup function to be called by fatal()/fatal_cleanup() before exiting. + It is permissible to call fatal_remove_cleanup for the function itself + from the function. */ +void fatal_add_cleanup(void (*proc)(void *context), void *context); + +/* Removes a cleanup function to be called at fatal(). */ +void fatal_remove_cleanup(void (*proc)(void *context), void *context); -#include "readconf.h" /*------------ definitions for login.c -------------*/ @@ -276,6 +313,10 @@ int ssh_connect(const char *host, struct sockaddr_in *hostaddr, If login fails, this function prints an error and never returns. This initializes the random state, and leaves it initialized (it will also have references from the packet module). */ + +/* for Options */ +#include "readconf.h" + void ssh_login(int host_key_valid, RSA *host_key, const char *host, struct sockaddr_in *hostaddr, Options *options, uid_t original_real_uid); @@ -381,59 +422,6 @@ int load_public_key(const char *filename, RSA *pub, int load_private_key(const char *filename, const char *passphrase, RSA *private_key, char **comment_return); -/*------------ Definitions for logging. -----------------------*/ - -/* Supported syslog facilities. */ -typedef enum -{ - SYSLOG_FACILITY_DAEMON, - SYSLOG_FACILITY_USER, - SYSLOG_FACILITY_AUTH, - SYSLOG_FACILITY_LOCAL0, - SYSLOG_FACILITY_LOCAL1, - SYSLOG_FACILITY_LOCAL2, - SYSLOG_FACILITY_LOCAL3, - SYSLOG_FACILITY_LOCAL4, - SYSLOG_FACILITY_LOCAL5, - SYSLOG_FACILITY_LOCAL6, - SYSLOG_FACILITY_LOCAL7 -} SyslogFacility; - -/* Initializes logging. If debug is non-zero, debug() will output something. - If quiet is non-zero, none of these will log send anything to syslog - (but maybe to stderr). */ -void log_init(char *av0, int on_stderr, int debug, int quiet, - SyslogFacility facility); - -/* Outputs a message to syslog or stderr, depending on the implementation. - The format must guarantee that the final message does not exceed 1024 - characters. The message should not contain newline. */ -void log(const char *fmt, ...); - -/* Outputs a message to syslog or stderr, depending on the implementation. - The format must guarantee that the final message does not exceed 1024 - characters. The message should not contain newline. */ -void debug(const char *fmt, ...); - -/* Outputs a message to syslog or stderr, depending on the implementation. - The format must guarantee that the final message does not exceed 1024 - characters. The message should not contain newline. */ -void error(const char *fmt, ...); - -/* Outputs a message to syslog or stderr, depending on the implementation. - The format must guarantee that the final message does not exceed 1024 - characters. The message should not contain newline. - This call never returns. */ -void fatal(const char *fmt, ...); - -/* Registers a cleanup function to be called by fatal() before exiting. - It is permissible to call fatal_remove_cleanup for the function itself - from the function. */ -void fatal_add_cleanup(void (*proc)(void *context), void *context); - -/* Removes a cleanup frunction to be called at fatal(). */ -void fatal_remove_cleanup(void (*proc)(void *context), void *context); - /*---------------- definitions for channels ------------------*/ /* Sets specific protocol options. */ @@ -547,9 +535,6 @@ void x11_request_forwarding(void); This should be called in the client only. */ void x11_request_forwarding_with_spoofing(const char *proto, const char *data); -/* Local Xauthority file (server only). */ -extern char *xauthfile; - /* Sends a message to the server to request authentication fd forwarding. */ void auth_request_forwarding(void); @@ -596,7 +581,8 @@ struct envstring { 0 if the client could not be authenticated, and 1 if authentication was successful. This may exit if there is a serious protocol violation. */ int auth_krb4(const char *server_user, KTEXT auth, char **client); -int ssh_tf_init(uid_t uid); +int krb4_init(uid_t uid); +void krb4_cleanup_proc(void *ignore); #ifdef AFS #include diff --git a/sshd.8 b/sshd.8 index c01f5712..c8fa828c 100644 --- a/sshd.8 +++ b/sshd.8 @@ -231,15 +231,6 @@ 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. -.Pp -.It Cm FascistLogging -Specifies whether to use verbose logging. Verbose logging violates -the privacy of users and is not recommended. The argument must be -.Dq yes -or -.Dq no . -The default is -.Dq no . .It Cm HostKey Specifies the file containing the private host key (default .Pa /etc/ssh/ssh_host_key ) . @@ -312,6 +303,14 @@ The default is to listen to all local addresses. The server disconnects after this time if the user has not successfully logged in. If the value is 0, there is no time limit. The default is 600 (seconds). +.It Cm LogLevel +Gives the verbosity level that is used when logging messages from +.Nm sshd . +The possible values are: +QUIET, FATAL, ERROR, INFO, CHAT and DEBUG. +The default is INFO. +Logging with level DEBUG violates the privacy of users +and is not recommended. .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is @@ -355,11 +354,6 @@ printed by the shell, .Pa /etc/profile , or equivalent.) The default is .Dq yes . -.It Cm QuietMode -Specifies whether the system runs in quiet mode. In quiet mode, -nothing is logged in the system log, except fatal errors. The default -is -.Dq no . .It Cm RandomSeed Obsolete. Random number generation uses other techniques. .It Cm RhostsAuthentication @@ -622,8 +616,8 @@ 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. -.It Pa "/etc/ssh/ssh_known_hosts" and "$HOME/.ssh/known_hosts" -This file is consulted when using rhosts with RSA host +.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. The key must be listed in one of these files to be accepted. The client uses the same files diff --git a/sshd.c b/sshd.c index cc247dd5..467b6c96 100644 --- a/sshd.c +++ b/sshd.c @@ -43,12 +43,8 @@ int deny_severity = LOG_WARNING; #define O_NOCTTY 0 #endif -#ifdef KRB4 -char *ticket = NULL; -#endif /* KRB4 */ - /* Local Xauthority file. */ -char *xauthfile = NULL; +static char *xauthfile = NULL; /* Server configuration options. */ ServerOptions options; @@ -65,6 +61,9 @@ int debug_flag = 0; /* Flag indicating that the daemon is being started from inetd. */ int inetd_flag = 0; +/* debug goes to stderr unless inetd_flag is set */ +int log_stderr = 0; + /* argv[0] without path. */ char *av0; @@ -400,6 +399,7 @@ main(int ac, char **av) break; case 'd': debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG; break; case 'i': inetd_flag = 1; @@ -408,7 +408,7 @@ main(int ac, char **av) silentrsa = 1; break; case 'q': - options.quiet_mode = 1; + options.log_level = SYSLOG_LEVEL_QUIET; break; case 'b': options.server_key_bits = atoi(optarg); @@ -479,9 +479,11 @@ main(int ac, char **av) } /* Initialize the log (it is reinitialized below in case we forked). */ - log_init(av0, debug_flag && !inetd_flag, - debug_flag || options.fascist_logging, - options.quiet_mode, options.log_facility); + + if (debug_flag && !inetd_flag) + log_stderr = 1; + + log_init(av0, options.log_level, options.log_facility, log_stderr); debug("sshd version %.100s", SSH_VERSION); @@ -496,7 +498,8 @@ main(int ac, char **av) else { int err = errno; - log_init(av0, !inetd_flag, 1, 0, options.log_facility); + /* force logging */ + log_init(av0, SYSLOG_LEVEL_DEBUG, options.log_facility, log_stderr); error("Could not load host key: %.200s: %.100s", options.host_key_file, strerror(err)); } @@ -526,9 +529,7 @@ main(int ac, char **av) } /* Reinitialize the log (because of the fork above). */ - log_init(av0, debug_flag && !inetd_flag, - debug_flag || options.fascist_logging, - options.quiet_mode, options.log_facility); + log_init(av0, options.log_level, options.log_facility, log_stderr); /* Check that server and host key lengths differ sufficiently. This is necessary to make double encryption work with rsaref. Oh, I hate @@ -696,9 +697,7 @@ main(int ac, char **av) close(listen_sock); sock_in = newsock; sock_out = newsock; - log_init(av0, debug_flag && !inetd_flag, - options.fascist_logging || debug_flag, - options.quiet_mode, options.log_facility); + log_init(av0, options.log_level, options.log_facility, log_stderr); break; } } @@ -1605,6 +1604,19 @@ void eat_packets_and_disconnect(const char *user) abort(); } +/* Remove local Xauthority file. */ +static void +xauthfile_cleanup_proc(void *ignore) +{ + debug("xauthfile_cleanup_proc called"); + + if (xauthfile != NULL) { + unlink(xauthfile); + xfree(xauthfile); + xauthfile = NULL; + } +} + /* Prepares for an interactive session. This is called after the user has been successfully authenticated. During this message exchange, pseudo terminals are allocated, X11, TCP/IP, and authentication agent forwardings @@ -1760,6 +1772,7 @@ void do_authenticated(struct passwd *pw) if ((xauthfd = mkstemp(xauthfile)) != -1) { fchown(xauthfd, pw->pw_uid, pw->pw_gid); close(xauthfd); + fatal_add_cleanup(xauthfile_cleanup_proc, NULL); } else { xfree(xauthfile); @@ -1905,8 +1918,7 @@ void do_exec_no_pty(const char *command, struct passwd *pw, if ((pid = fork()) == 0) { /* Child. Reinitialize the log since the pid has changed. */ - log_init(av0, debug_flag && !inetd_flag, debug_flag, - options.quiet_mode, options.log_facility); + log_init(av0, options.log_level, options.log_facility, log_stderr); /* Create a new session and process group since the 4.4BSD setlogin() affects the entire process group. */ @@ -1988,11 +2000,6 @@ void pty_cleanup_proc(void *context) debug("pty_cleanup_proc called"); -#if defined(KRB4) - /* Destroy user's ticket cache file. */ - (void) dest_tkt(); -#endif /* KRB4 */ - /* Record that the user has logged out. */ record_logout(cu->pid, cu->ttyname); @@ -2040,8 +2047,7 @@ void do_exec_pty(const char *command, int ptyfd, int ttyfd, pid = getpid(); /* Child. Reinitialize the log because the pid has changed. */ - log_init(av0, debug_flag && !inetd_flag, debug_flag, options.quiet_mode, - options.log_facility); + log_init(av0, options.log_level, options.log_facility, log_stderr); /* Close the master side of the pseudo tty. */ close(ptyfd); @@ -2395,8 +2401,12 @@ void do_child(const char *command, struct passwd *pw, const char *term, child_set_env(&env, &envsize, "DISPLAY", display); #ifdef KRB4 - if (ticket) - child_set_env(&env, &envsize, "KRBTKFILE", ticket); + { + extern char *ticket; + + if (ticket) + child_set_env(&env, &envsize, "KRBTKFILE", ticket); + } #endif /* KRB4 */ #ifdef HAVE_LIBPAM -- 2.45.2