diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | acconfig.h | 14 | ||||
-rw-r--r-- | auth-krb4.c | 120 | ||||
-rw-r--r-- | auth-passwd.c | 32 | ||||
-rw-r--r-- | clientloop.c | 7 | ||||
-rw-r--r-- | log-client.c | 137 | ||||
-rw-r--r-- | log-server.c | 202 | ||||
-rw-r--r-- | log.c | 135 | ||||
-rw-r--r-- | readconf.c | 48 | ||||
-rw-r--r-- | readconf.h | 3 | ||||
-rw-r--r-- | servconf.c | 62 | ||||
-rw-r--r-- | servconf.h | 5 | ||||
-rw-r--r-- | ssh.1 | 8 | ||||
-rw-r--r-- | ssh.c | 16 | ||||
-rw-r--r-- | ssh.h | 132 | ||||
-rw-r--r-- | sshd.8 | 28 | ||||
-rw-r--r-- | sshd.c | 66 |
18 files changed, 552 insertions, 476 deletions
@@ -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) $@ @@ -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 6e8a6bac..03205233 100644 --- a/auth-krb4.c +++ b/auth-krb4.c @@ -6,7 +6,7 @@ Kerberos v4 authentication and ticket-passing routines. - $Id: auth-krb4.c,v 1.2 1999/11/08 04:49:41 damien Exp $ + $Id: auth-krb4.c,v 1.3 1999/11/11 06:57:39 damien Exp $ */ #include "includes.h" @@ -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 61f66fed..99d0af2b 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -15,17 +15,13 @@ the password is valid for the user. */ #include "includes.h" -RCSID("$Id: auth-passwd.c,v 1.2 1999/10/27 13:42:05 damien Exp $"); +RCSID("$Id: auth-passwd.c,v 1.3 1999/11/11 06:57:39 damien Exp $"); #include "packet.h" #include "ssh.h" #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 43373b72..a236ce9b 100644 --- a/clientloop.c +++ b/clientloop.c @@ -15,16 +15,17 @@ The main loop for the interactive session (client side). */ #include "includes.h" -RCSID("$Id: clientloop.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); +RCSID("$Id: clientloop.c,v 1.2 1999/11/11 06:57:39 damien Exp $"); #include "xmalloc.h" #include "ssh.h" #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 1792ba84..63cc7944 100644 --- a/log-client.c +++ b/log-client.c @@ -10,129 +10,54 @@ Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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. */ #include "includes.h" -RCSID("$Id: log-client.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); +RCSID("$Id: log-client.c,v 1.2 1999/11/11 06:57:39 damien Exp $"); #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 fce96b01..6642dbed 100644 --- a/log-server.c +++ b/log-server.c @@ -15,29 +15,42 @@ to the system log. */ #include "includes.h" -RCSID("$Id: log-server.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); +RCSID("$Id: log-server.c,v 1.2 1999/11/11 06:57:39 damien Exp $"); #include <syslog.h> #include "packet.h" #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); } @@ -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); +} @@ -14,7 +14,7 @@ Functions for reading the configuration files. */ #include "includes.h" -RCSID("$Id: readconf.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); +RCSID("$Id: readconf.c,v 1.2 1999/11/11 06:57:39 damien Exp $"); #include "ssh.h" #include "cipher.h" @@ -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); |