summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--Makefile.in2
-rw-r--r--acconfig.h14
-rw-r--r--auth-krb4.c120
-rw-r--r--auth-passwd.c32
-rw-r--r--clientloop.c7
-rw-r--r--log-client.c137
-rw-r--r--log-server.c202
-rw-r--r--log.c135
-rw-r--r--readconf.c48
-rw-r--r--readconf.h3
-rw-r--r--servconf.c62
-rw-r--r--servconf.h5
-rw-r--r--ssh.18
-rw-r--r--ssh.c16
-rw-r--r--ssh.h132
-rw-r--r--sshd.828
-rw-r--r--sshd.c66
18 files changed, 552 insertions, 476 deletions
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 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);
}
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 281548d2..2a99266a 100644
--- a/readconf.c
+++ b/readconf.c
@@ -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);
@@ -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 71655bd2..8839a1bd 100644
--- a/readconf.h
+++ b/readconf.h
@@ -13,7 +13,7 @@ Functions for reading the configuration file.
*/
-/* RCSID("$Id: readconf.h,v 1.1 1999/10/27 03:42:44 damien Exp $"); */
+/* RCSID("$Id: readconf.h,v 1.2 1999/11/11 06:57:39 damien Exp $"); */
#ifndef READCONF_H
#define 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 5fa48790..d7f54a62 100644
--- a/servconf.c
+++ b/servconf.c
@@ -12,7 +12,7 @@ Created: Mon Aug 21 15:48:58 1995 ylo
*/
#include "includes.h"
-RCSID("$Id: servconf.c,v 1.1 1999/10/27 03:42:45 damien Exp $");
+RCSID("$Id: servconf.c,v 1.2 1999/11/11 06:57:39 damien Exp $");
#include "ssh.h"
#include "servconf.h"
@@ -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 22c73fd7..584935ba 100644
--- a/servconf.h
+++ b/servconf.h
@@ -13,7 +13,7 @@ Definitions for server configuration data and for the functions reading it.
*/
-/* RCSID("$Id: servconf.h,v 1.1 1999/10/27 03:42:45 damien Exp $"); */
+/* RCSID("$Id: servconf.h,v 1.2 1999/11/11 06:57:40 damien Exp $"); */
#ifndef SERVCONF_H
#define 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 3ea1c27b..34a8ce96 100644
--- a/ssh.1
+++ b/ssh.1
@@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 21:55:14 1995 ylo
.\"
-.\" $Id: ssh.1,v 1.5 1999/11/11 00:43:13 damien Exp $
+.\" $Id: ssh.1,v 1.6 1999/11/11 06:57:40 damien Exp $
.\"
.Dd September 25, 1999
.Dt 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 76300489..be5ad2cc 100644
--- a/ssh.c
+++ b/ssh.c
@@ -18,7 +18,7 @@ Modified to work with SSL by Niels Provos <provos@citi.umich.edu> in Canada.
*/
#include "includes.h"
-RCSID("$Id: ssh.c,v 1.4 1999/10/30 01:39:56 damien Exp $");
+RCSID("$Id: ssh.c,v 1.5 1999/11/11 06:57:40 damien Exp $");
#include "xmalloc.h"
#include "ssh.h"
@@ -32,9 +32,6 @@ RCSID("$Id: ssh.c,v 1.4 1999/10/30 01:39:56 damien Exp $");
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 a91312a8..da818b22 100644
--- a/ssh.h
+++ b/ssh.h
@@ -13,26 +13,14 @@ Generic header file for ssh.
*/
-/* RCSID("$Id: ssh.h,v 1.9 1999/11/10 23:40:23 damien Exp $"); */
+/* RCSID("$Id: ssh.h,v 1.10 1999/11/11 06:57:40 damien Exp $"); */
#ifndef SSH_H
#define SSH_H
#include <netinet/in.h> /* For struct sockaddr_in */
#include <pwd.h> /* 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 <stdarg.h> /* 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 <kafs.h>
diff --git a/sshd.8 b/sshd.8
index fd1f7f02..20e9712a 100644
--- a/sshd.8
+++ b/sshd.8
@@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 21:55:14 1995 ylo
.\"
-.\" $Id: sshd.8,v 1.5 1999/11/11 00:43:13 damien Exp $
+.\" $Id: sshd.8,v 1.6 1999/11/11 06:57:40 damien Exp $
.\"
.Dd September 25, 1999
.Dt 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 a1f9449e..75ea61ea 100644
--- a/sshd.c
+++ b/sshd.c
@@ -18,7 +18,7 @@ agent connections.
*/
#include "includes.h"
-RCSID("$Id: sshd.c,v 1.12 1999/11/08 05:15:55 damien Exp $");
+RCSID("$Id: sshd.c,v 1.13 1999/11/11 06:57:40 damien Exp $");
#include "xmalloc.h"
#include "rsa.h"
@@ -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