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 a1bfb2114..4971a4421 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,8 +7,15 @@
7 - [sshd.8] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too 7 - [sshd.8] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too
8 - Fix integer overflow which was messing up scp's progress bar for large 8 - Fix integer overflow which was messing up scp's progress bar for large
9 file transfers. Fix submitted to OpenBSD developers. 9 file transfers. Fix submitted to OpenBSD developers.
10 - Released 1.2pre10 10 - Merged more OpenBSD CVS changes:
11 11 - [auth-krb4.c auth-passwd.c] remove x11- and krb-cleanup from fatal()
12 + krb-cleanup cleanup
13 - [clientloop.c log-client.c log-server.c ]
14 [readconf.c readconf.h servconf.c servconf.h ]
15 [ssh.1 ssh.c ssh.h sshd.8]
16 add LogLevel {QUIET, FATAL, ERROR, INFO, CHAT, DEBUG} to ssh/sshd,
17 obsoletes QuietMode and FascistLogging in sshd.
18
1219991110 1919991110
13 - Merged several minor fixed: 20 - Merged several minor fixed:
14 - ssh-agent commandline parsing 21 - ssh-agent commandline parsing
diff --git a/Makefile.in b/Makefile.in
index 0d239e882..bd7950a51 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 \
30 30
31all: $(OBJS) $(TARGETS) 31all: $(OBJS) $(TARGETS)
32 32
33libssh.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 33libssh.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
34 $(AR) rv $@ $^ 34 $(AR) rv $@ $^
35 $(RANLIB) $@ 35 $(RANLIB) $@
36 36
diff --git a/acconfig.h b/acconfig.h
index 063b91711..56075fd9f 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -20,3 +20,17 @@
20 20
21/* Define is libutil has login() function */ 21/* Define is libutil has login() function */
22#undef HAVE_LIBUTIL_LOGIN 22#undef HAVE_LIBUTIL_LOGIN
23
24
25/* Shouldn't need to edit below this line *************************** */
26#ifndef SHUT_RDWR
27enum
28{
29 SHUT_RD = 0, /* No more receptions. */
30#define SHUT_RD SHUT_RD
31 SHUT_WR, /* No more transmissions. */
32#define SHUT_WR SHUT_WR
33 SHUT_RDWR /* No more receptions or transmissions. */
34#define SHUT_RDWR SHUT_RDWR
35};
36#endif
diff --git a/auth-krb4.c b/auth-krb4.c
index 6e8a6bac4..032052338 100644
--- a/auth-krb4.c
+++ b/auth-krb4.c
@@ -6,7 +6,7 @@
6 6
7 Kerberos v4 authentication and ticket-passing routines. 7 Kerberos v4 authentication and ticket-passing routines.
8 8
9 $Id: auth-krb4.c,v 1.2 1999/11/08 04:49:41 damien Exp $ 9 $Id: auth-krb4.c,v 1.3 1999/11/11 06:57:39 damien Exp $
10*/ 10*/
11 11
12#include "includes.h" 12#include "includes.h"
@@ -15,38 +15,59 @@
15#include "ssh.h" 15#include "ssh.h"
16 16
17#ifdef KRB4 17#ifdef KRB4
18int ssh_tf_init(uid_t uid) 18char *ticket = NULL;
19
20void
21krb4_cleanup_proc(void *ignore)
22{
23 debug("krb4_cleanup_proc called");
24
25 if (ticket) {
26 (void) dest_tkt();
27 xfree(ticket);
28 ticket = NULL;
29 }
30}
31
32int krb4_init(uid_t uid)
19{ 33{
20 extern char *ticket; 34 static int cleanup_registered = 0;
21 char *tkt_root = TKT_ROOT; 35 char *tkt_root = TKT_ROOT;
22 struct stat st; 36 struct stat st;
23 int fd; 37 int fd;
24 38
25 /* Set unique ticket string manually since we're still root. */ 39 if (!ticket) {
26 ticket = xmalloc(MAXPATHLEN); 40 /* Set unique ticket string manually since we're still root. */
41 ticket = xmalloc(MAXPATHLEN);
27#ifdef AFS 42#ifdef AFS
28 if (lstat("/ticket", &st) != -1) 43 if (lstat("/ticket", &st) != -1)
29 tkt_root = "/ticket/"; 44 tkt_root = "/ticket/";
30#endif /* AFS */ 45#endif /* AFS */
31 snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid()); 46 snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid());
32 (void) krb_set_tkt_string(ticket); 47 (void) krb_set_tkt_string(ticket);
33 48 }
34 /* Make sure we own this ticket file, and we created it. */ 49 /* Register ticket cleanup in case of fatal error. */
35 if (lstat(ticket, &st) == -1 && errno == ENOENT) { 50 if (!cleanup_registered) {
36 /* good, no ticket file exists. create it. */ 51 fatal_add_cleanup(krb4_cleanup_proc, NULL);
37 if ((fd = open(ticket, O_RDWR|O_CREAT|O_EXCL, 0600)) != -1) { 52 cleanup_registered = 1;
38 close(fd); 53 }
39 return 1; 54 /* Try to create our ticket file. */
40 } 55 if ((fd = mkstemp(ticket)) != -1) {
56 close(fd);
57 return 1;
41 } 58 }
42 else { 59 /* Ticket file exists - make sure user owns it (just passed ticket). */
43 /* file exists. make sure server_user owns it (e.g. just passed ticket), 60 if (lstat(ticket, &st) != -1) {
44 and that it isn't a symlink, and that it is mode 600. */
45 if (st.st_mode == (S_IFREG|S_IRUSR|S_IWUSR) && st.st_uid == uid) 61 if (st.st_mode == (S_IFREG|S_IRUSR|S_IWUSR) && st.st_uid == uid)
46 return 1; 62 return 1;
47 } 63 }
48 /* Failure. */ 64 /* Failure - cancel cleanup function, leaving bad ticket for inspection. */
49 log("WARNING: bad ticket file %s", ticket); 65 log("WARNING: bad ticket file %s", ticket);
66 fatal_remove_cleanup(krb4_cleanup_proc, NULL);
67 cleanup_registered = 0;
68 xfree(ticket);
69 ticket = NULL;
70
50 return 0; 71 return 0;
51} 72}
52 73
@@ -103,8 +124,7 @@ int auth_krb4(const char *server_user, KTEXT auth, char **client)
103 reply.dat[0] = 0; 124 reply.dat[0] = 0;
104 reply.length = 0; 125 reply.length = 0;
105 } 126 }
106 else 127 else reply.length = r;
107 reply.length = r;
108 128
109 /* Clear session key. */ 129 /* Clear session key. */
110 memset(&adat.session, 0, sizeof(&adat.session)); 130 memset(&adat.session, 0, sizeof(&adat.session));
@@ -121,8 +141,6 @@ int auth_krb4(const char *server_user, KTEXT auth, char **client)
121int auth_kerberos_tgt(struct passwd *pw, const char *string) 141int auth_kerberos_tgt(struct passwd *pw, const char *string)
122{ 142{
123 CREDENTIALS creds; 143 CREDENTIALS creds;
124 extern char *ticket;
125 int r;
126 144
127 if (!radix_to_creds(string, &creds)) { 145 if (!radix_to_creds(string, &creds)) {
128 log("Protocol error decoding Kerberos V4 tgt"); 146 log("Protocol error decoding Kerberos V4 tgt");
@@ -133,37 +151,39 @@ int auth_kerberos_tgt(struct passwd *pw, const char *string)
133 strlcpy(creds.service, "krbtgt", sizeof creds.service); 151 strlcpy(creds.service, "krbtgt", sizeof creds.service);
134 152
135 if (strcmp(creds.service, "krbtgt")) { 153 if (strcmp(creds.service, "krbtgt")) {
136 log("Kerberos V4 tgt (%s%s%s@%s) rejected for uid %d", 154 log("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", creds.pname,
137 creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm, 155 creds.pinst[0] ? "." : "", creds.pinst, creds.realm, pw->pw_name);
138 pw->pw_uid); 156 packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s",
139 packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for uid %d",
140 creds.pname, creds.pinst[0] ? "." : "", creds.pinst, 157 creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
141 creds.realm, pw->pw_uid); 158 creds.realm, pw->pw_name);
142 goto auth_kerberos_tgt_failure; 159 goto auth_kerberos_tgt_failure;
143 } 160 }
144 if (!ssh_tf_init(pw->pw_uid) || 161 if (!krb4_init(pw->pw_uid))
145 (r = in_tkt(creds.pname, creds.pinst)) || 162 goto auth_kerberos_tgt_failure;
146 (r = save_credentials(creds.service, creds.instance, creds.realm, 163
147 creds.session, creds.lifetime, creds.kvno, 164 if (in_tkt(creds.pname, creds.pinst) != KSUCCESS)
148 &creds.ticket_st, creds.issue_date))) { 165 goto auth_kerberos_tgt_failure;
149 xfree(ticket); 166
150 ticket = NULL; 167 if (save_credentials(creds.service, creds.instance, creds.realm,
168 creds.session, creds.lifetime, creds.kvno,
169 &creds.ticket_st, creds.issue_date) != KSUCCESS) {
151 packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials"); 170 packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials");
152 goto auth_kerberos_tgt_failure; 171 goto auth_kerberos_tgt_failure;
153 } 172 }
154 /* Successful authentication, passed all checks. */ 173 /* Successful authentication, passed all checks. */
155 chown(ticket, pw->pw_uid, pw->pw_gid); 174 chown(tkt_string(), pw->pw_uid, pw->pw_gid);
156 packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)",
157 creds.service, creds.instance, creds.realm,
158 creds.pname, creds.pinst[0] ? "." : "",
159 creds.pinst, creds.realm);
160 175
176 packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)",
177 creds.service, creds.instance, creds.realm, creds.pname,
178 creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
179 memset(&creds, 0, sizeof(creds));
161 packet_start(SSH_SMSG_SUCCESS); 180 packet_start(SSH_SMSG_SUCCESS);
162 packet_send(); 181 packet_send();
163 packet_write_wait(); 182 packet_write_wait();
164 return 1; 183 return 1;
165 184
166auth_kerberos_tgt_failure: 185 auth_kerberos_tgt_failure:
186 krb4_cleanup_proc(NULL);
167 memset(&creds, 0, sizeof(creds)); 187 memset(&creds, 0, sizeof(creds));
168 packet_start(SSH_SMSG_FAILURE); 188 packet_start(SSH_SMSG_FAILURE);
169 packet_send(); 189 packet_send();
@@ -191,10 +211,11 @@ int auth_afs_token(struct passwd *pw, const char *token_string)
191 uid = atoi(creds.pname + 7); 211 uid = atoi(creds.pname + 7);
192 212
193 if (kafs_settoken(creds.realm, uid, &creds)) { 213 if (kafs_settoken(creds.realm, uid, &creds)) {
194 log("AFS token (%s@%s) rejected for uid %d", creds.pname, 214 log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm,
195 creds.realm, uid); 215 pw->pw_name);
196 packet_send_debug("AFS token (%s@%s) rejected for uid %d", creds.pname, 216 packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname,
197 creds.realm, uid); 217 creds.realm, pw->pw_name);
218 memset(&creds, 0, sizeof(creds));
198 packet_start(SSH_SMSG_FAILURE); 219 packet_start(SSH_SMSG_FAILURE);
199 packet_send(); 220 packet_send();
200 packet_write_wait(); 221 packet_write_wait();
@@ -202,6 +223,7 @@ int auth_afs_token(struct passwd *pw, const char *token_string)
202 } 223 }
203 packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service, 224 packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service,
204 creds.realm, creds.pname, creds.realm); 225 creds.realm, creds.pname, creds.realm);
226 memset(&creds, 0, sizeof(creds));
205 packet_start(SSH_SMSG_SUCCESS); 227 packet_start(SSH_SMSG_SUCCESS);
206 packet_send(); 228 packet_send();
207 packet_write_wait(); 229 packet_write_wait();
diff --git a/auth-passwd.c b/auth-passwd.c
index 61f66fedd..99d0af2be 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -15,17 +15,13 @@ the password is valid for the user.
15*/ 15*/
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: auth-passwd.c,v 1.2 1999/10/27 13:42:05 damien Exp $"); 18RCSID("$Id: auth-passwd.c,v 1.3 1999/11/11 06:57:39 damien Exp $");
19 19
20#include "packet.h" 20#include "packet.h"
21#include "ssh.h" 21#include "ssh.h"
22#include "servconf.h" 22#include "servconf.h"
23#include "xmalloc.h" 23#include "xmalloc.h"
24 24
25#ifdef KRB4
26extern char *ticket;
27#endif /* KRB4 */
28
29/* Tries to authenticate the user using password. Returns true if 25/* Tries to authenticate the user using password. Returns true if
30 authentication succeeds. */ 26 authentication succeeds. */
31 27
@@ -80,9 +76,9 @@ int auth_password(struct passwd *pw, const char *password)
80 KTEXT_ST tkt; 76 KTEXT_ST tkt;
81 struct hostent *hp; 77 struct hostent *hp;
82 unsigned long faddr; 78 unsigned long faddr;
83 char localhost[MAXHOSTNAMELEN]; /* local host name */ 79 char localhost[MAXHOSTNAMELEN];
84 char phost[INST_SZ]; /* host instance */ 80 char phost[INST_SZ];
85 char realm[REALM_SZ]; /* local Kerberos realm */ 81 char realm[REALM_SZ];
86 int r; 82 int r;
87 83
88 /* Try Kerberos password authentication only for non-root 84 /* Try Kerberos password authentication only for non-root
@@ -90,9 +86,8 @@ int auth_password(struct passwd *pw, const char *password)
90 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { 86 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
91 87
92 /* Set up our ticket file. */ 88 /* Set up our ticket file. */
93 if (!ssh_tf_init(pw->pw_uid)) { 89 if (!krb4_init(pw->pw_uid)) {
94 log("Couldn't initialize Kerberos ticket file for %s!", 90 log("Couldn't initialize Kerberos ticket file for %s!", pw->pw_name);
95 pw->pw_name);
96 goto kerberos_auth_failure; 91 goto kerberos_auth_failure;
97 } 92 }
98 /* Try to get TGT using our password. */ 93 /* Try to get TGT using our password. */
@@ -104,13 +99,12 @@ int auth_password(struct passwd *pw, const char *password)
104 goto kerberos_auth_failure; 99 goto kerberos_auth_failure;
105 } 100 }
106 /* Successful authentication. */ 101 /* Successful authentication. */
107 chown(ticket, pw->pw_uid, pw->pw_gid); 102 chown(tkt_string(), pw->pw_uid, pw->pw_gid);
108
109 (void) gethostname(localhost, sizeof(localhost));
110 (void) strlcpy(phost, (char *)krb_get_phost(localhost), INST_SZ);
111 103
112 /* Now that we have a TGT, try to get a local "rcmd" ticket to 104 /* Now that we have a TGT, try to get a local "rcmd" ticket to
113 ensure that we are not talking to a bogus Kerberos server. */ 105 ensure that we are not talking to a bogus Kerberos server. */
106 (void) gethostname(localhost, sizeof(localhost));
107 (void) strlcpy(phost, (char *)krb_get_phost(localhost), INST_SZ);
114 r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); 108 r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
115 109
116 if (r == KSUCCESS) { 110 if (r == KSUCCESS) {
@@ -150,10 +144,10 @@ int auth_password(struct passwd *pw, const char *password)
150 return 1; 144 return 1;
151 145
152 kerberos_auth_failure: 146 kerberos_auth_failure:
153 (void) dest_tkt(); 147 krb4_cleanup_proc(NULL);
154 xfree(ticket); 148
155 ticket = NULL; 149 if (!options.kerberos_or_local_passwd)
156 if (!options.kerberos_or_local_passwd ) return 0; 150 return 0;
157 } 151 }
158 else { 152 else {
159 /* Logging in as root or no local Kerberos realm. */ 153 /* Logging in as root or no local Kerberos realm. */
diff --git a/clientloop.c b/clientloop.c
index 43373b72e..a236ce9b2 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -15,16 +15,17 @@ The main loop for the interactive session (client side).
15*/ 15*/
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: clientloop.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); 18RCSID("$Id: clientloop.c,v 1.2 1999/11/11 06:57:39 damien Exp $");
19 19
20#include "xmalloc.h" 20#include "xmalloc.h"
21#include "ssh.h" 21#include "ssh.h"
22#include "packet.h" 22#include "packet.h"
23#include "buffer.h" 23#include "buffer.h"
24#include "authfd.h" 24#include "authfd.h"
25#include "readconf.h"
25 26
26/* Flag indicating whether quiet mode is on. */ 27/* Flag indicating whether quiet mode is on. */
27extern int quiet_flag; 28extern Options options;
28 29
29/* Flag indicating that stdin should be redirected from /dev/null. */ 30/* Flag indicating that stdin should be redirected from /dev/null. */
30extern int stdin_null_flag; 31extern int stdin_null_flag;
@@ -866,7 +867,7 @@ int client_loop(int have_pty, int escape_char_arg)
866 867
867 /* In interactive mode (with pseudo tty) display a message indicating that 868 /* In interactive mode (with pseudo tty) display a message indicating that
868 the connection has been closed. */ 869 the connection has been closed. */
869 if (have_pty && !quiet_flag) 870 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET)
870 { 871 {
871 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); 872 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
872 buffer_append(&stderr_buffer, buf, strlen(buf)); 873 buffer_append(&stderr_buffer, buf, strlen(buf));
diff --git a/log-client.c b/log-client.c
index 1792ba847..63cc79445 100644
--- a/log-client.c
+++ b/log-client.c
@@ -10,129 +10,54 @@ Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
10Created: Mon Mar 20 21:13:40 1995 ylo 10Created: Mon Mar 20 21:13:40 1995 ylo
11 11
12Client-side versions of debug(), log(), etc. These print to stderr. 12Client-side versions of debug(), log(), etc. These print to stderr.
13This is a stripped down version of log-server.c.
13 14
14*/ 15*/
15 16
16#include "includes.h" 17#include "includes.h"
17RCSID("$Id: log-client.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); 18RCSID("$Id: log-client.c,v 1.2 1999/11/11 06:57:39 damien Exp $");
18 19
19#include "xmalloc.h" 20#include "xmalloc.h"
20#include "ssh.h" 21#include "ssh.h"
21 22
22static int log_debug = 0; 23static LogLevel log_level = SYSLOG_LEVEL_INFO;
23static int log_quiet = 0;
24 24
25void log_init(char *av0, int on_stderr, int debug, int quiet, 25/* Initialize the log.
26 SyslogFacility facility) 26 av0 program name (should be argv[0])
27{ 27 level logging level
28 log_debug = debug; 28 */
29 log_quiet = quiet;
30}
31
32void log(const char *fmt, ...)
33{
34 va_list args;
35
36 if (log_quiet)
37 return;
38 va_start(args, fmt);
39 vfprintf(stderr, fmt, args);
40 fprintf(stderr, "\r\n");
41 va_end(args);
42}
43
44void debug(const char *fmt, ...)
45{
46 va_list args;
47 if (log_quiet || !log_debug)
48 return;
49 va_start(args, fmt);
50 fprintf(stderr, "debug: ");
51 vfprintf(stderr, fmt, args);
52 fprintf(stderr, "\r\n");
53 va_end(args);
54}
55
56void error(const char *fmt, ...)
57{
58 va_list args;
59 if (log_quiet)
60 return;
61 va_start(args, fmt);
62 vfprintf(stderr, fmt, args);
63 fprintf(stderr, "\r\n");
64 va_end(args);
65}
66
67struct fatal_cleanup
68{
69 struct fatal_cleanup *next;
70 void (*proc)(void *);
71 void *context;
72};
73
74static struct fatal_cleanup *fatal_cleanups = NULL;
75
76/* Registers a cleanup function to be called by fatal() before exiting. */
77
78void fatal_add_cleanup(void (*proc)(void *), void *context)
79{
80 struct fatal_cleanup *cu;
81 29
82 cu = xmalloc(sizeof(*cu)); 30void
83 cu->proc = proc; 31log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2)
84 cu->context = context;
85 cu->next = fatal_cleanups;
86 fatal_cleanups = cu;
87}
88
89/* Removes a cleanup frunction to be called at fatal(). */
90
91void fatal_remove_cleanup(void (*proc)(void *context), void *context)
92{ 32{
93 struct fatal_cleanup **cup, *cu; 33 switch (level)
94
95 for (cup = &fatal_cleanups; *cup; cup = &cu->next)
96 { 34 {
97 cu = *cup; 35 case SYSLOG_LEVEL_QUIET:
98 if (cu->proc == proc && cu->context == context) 36 case SYSLOG_LEVEL_ERROR:
99 { 37 case SYSLOG_LEVEL_FATAL:
100 *cup = cu->next; 38 case SYSLOG_LEVEL_INFO:
101 xfree(cu); 39 case SYSLOG_LEVEL_CHAT:
102 return; 40 case SYSLOG_LEVEL_DEBUG:
103 } 41 log_level = level;
42 break;
43 default:
44 /* unchanged */
45 break;
104 } 46 }
105 fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n",
106 (unsigned long)proc, (unsigned long)context);
107} 47}
108 48
109/* Function to display an error message and exit. This is in this file because 49#define MSGBUFSIZE 1024
110 this needs to restore terminal modes before exiting. See log-client.c
111 for other related functions. */
112 50
113void fatal(const char *fmt, ...) 51void
52do_log(LogLevel level, const char *fmt, va_list args)
114{ 53{
115 va_list args; 54 char msgbuf[MSGBUFSIZE];
116 struct fatal_cleanup *cu, *next_cu;
117 static int fatal_called = 0;
118
119 if (!fatal_called)
120 {
121 fatal_called = 1;
122 55
123 /* Call cleanup functions. */ 56 if (level > log_level)
124 for (cu = fatal_cleanups; cu; cu = next_cu) 57 return;
125 { 58 if (level == SYSLOG_LEVEL_DEBUG)
126 next_cu = cu->next; 59 fprintf(stderr, "debug: ");
127 (*cu->proc)(cu->context); 60 vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
128 } 61 fprintf(stderr, "%s", msgbuf);
129 }
130
131 va_start(args, fmt);
132 vfprintf(stderr, fmt, args);
133 fprintf(stderr, "\r\n"); 62 fprintf(stderr, "\r\n");
134 va_end(args);
135 exit(255);
136} 63}
137
138/* fatal() is in ssh.c so that it can properly reset terminal modes. */
diff --git a/log-server.c b/log-server.c
index fce96b01d..6642dbedf 100644
--- a/log-server.c
+++ b/log-server.c
@@ -15,29 +15,42 @@ to the system log.
15*/ 15*/
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: log-server.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); 18RCSID("$Id: log-server.c,v 1.2 1999/11/11 06:57:39 damien Exp $");
19 19
20#include <syslog.h> 20#include <syslog.h>
21#include "packet.h" 21#include "packet.h"
22#include "xmalloc.h" 22#include "xmalloc.h"
23#include "ssh.h" 23#include "ssh.h"
24 24
25static int log_debug = 0; 25static LogLevel log_level = SYSLOG_LEVEL_INFO;
26static int log_quiet = 0;
27static int log_on_stderr = 0; 26static int log_on_stderr = 0;
28 27
29/* Initialize the log. 28/* Initialize the log.
30 av0 program name (should be argv[0]) 29 av0 program name (should be argv[0])
31 on_stderr print also on stderr 30 on_stderr print also on stderr
32 debug send debugging messages to system log 31 level logging level
33 quiet don\'t log anything
34 */ 32 */
35 33
36void log_init(char *av0, int on_stderr, int debug, int quiet, 34void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
37 SyslogFacility facility)
38{ 35{
39 int log_facility; 36 int log_facility;
40 37
38 switch (level)
39 {
40 case SYSLOG_LEVEL_QUIET:
41 case SYSLOG_LEVEL_ERROR:
42 case SYSLOG_LEVEL_FATAL:
43 case SYSLOG_LEVEL_INFO:
44 case SYSLOG_LEVEL_CHAT:
45 case SYSLOG_LEVEL_DEBUG:
46 log_level = level;
47 break;
48 default:
49 fprintf(stderr, "Unrecognized internal syslog level code %d\n",
50 (int)level);
51 exit(1);
52 }
53
41 switch (facility) 54 switch (facility)
42 { 55 {
43 case SYSLOG_FACILITY_DAEMON: 56 case SYSLOG_FACILITY_DAEMON:
@@ -79,8 +92,6 @@ void log_init(char *av0, int on_stderr, int debug, int quiet,
79 exit(1); 92 exit(1);
80 } 93 }
81 94
82 log_debug = debug;
83 log_quiet = quiet;
84 log_on_stderr = on_stderr; 95 log_on_stderr = on_stderr;
85 closelog(); /* Close any previous log. */ 96 closelog(); /* Close any previous log. */
86 openlog(av0, LOG_PID, log_facility); 97 openlog(av0, LOG_PID, log_facility);
@@ -88,146 +99,49 @@ void log_init(char *av0, int on_stderr, int debug, int quiet,
88 99
89#define MSGBUFSIZE 1024 100#define MSGBUFSIZE 1024
90 101
91#define DECL_MSGBUF char msgbuf[MSGBUFSIZE] 102void
92 103do_log(LogLevel level, const char *fmt, va_list args)
93/* Log this message (information that usually should go to the log). */
94
95void log(const char *fmt, ...)
96{
97 va_list args;
98 DECL_MSGBUF;
99 if (log_quiet)
100 return;
101 va_start(args, fmt);
102 vsnprintf(msgbuf, MSGBUFSIZE, fmt, args);
103 va_end(args);
104 if (log_on_stderr)
105 fprintf(stderr, "log: %s\n", msgbuf);
106 syslog(LOG_INFO, "log: %.500s", msgbuf);
107}
108
109/* Debugging messages that should not be logged during normal operation. */
110
111void debug(const char *fmt, ...)
112{ 104{
113 va_list args; 105 char msgbuf[MSGBUFSIZE];
114 DECL_MSGBUF; 106 char fmtbuf[MSGBUFSIZE];
115 if (!log_debug || log_quiet) 107 char *txt = NULL;
116 return; 108 int pri = LOG_INFO;
117 va_start(args, fmt);
118 vsnprintf(msgbuf, MSGBUFSIZE, fmt, args);
119 va_end(args);
120 if (log_on_stderr)
121 fprintf(stderr, "debug: %s\n", msgbuf);
122 syslog(LOG_DEBUG, "debug: %.500s", msgbuf);
123}
124 109
125/* Error messages that should be logged. */ 110 if (level > log_level)
126
127void error(const char *fmt, ...)
128{
129 va_list args;
130 DECL_MSGBUF;
131 if (log_quiet)
132 return; 111 return;
133 va_start(args, fmt); 112 switch (level)
134 vsnprintf(msgbuf, MSGBUFSIZE, fmt, args);
135 va_end(args);
136 if (log_on_stderr)
137 fprintf(stderr, "error: %s\n", msgbuf);
138 syslog(LOG_ERR, "error: %.500s", msgbuf);
139}
140
141struct fatal_cleanup
142{
143 struct fatal_cleanup *next;
144 void (*proc)(void *);
145 void *context;
146};
147
148static struct fatal_cleanup *fatal_cleanups = NULL;
149
150/* Registers a cleanup function to be called by fatal() before exiting. */
151
152void fatal_add_cleanup(void (*proc)(void *), void *context)
153{
154 struct fatal_cleanup *cu;
155
156 cu = xmalloc(sizeof(*cu));
157 cu->proc = proc;
158 cu->context = context;
159 cu->next = fatal_cleanups;
160 fatal_cleanups = cu;
161}
162
163/* Removes a cleanup frunction to be called at fatal(). */
164
165void fatal_remove_cleanup(void (*proc)(void *context), void *context)
166{
167 struct fatal_cleanup **cup, *cu;
168
169 for (cup = &fatal_cleanups; *cup; cup = &cu->next)
170 { 113 {
171 cu = *cup; 114 case SYSLOG_LEVEL_ERROR:
172 if (cu->proc == proc && cu->context == context) 115 txt = "error";
173 { 116 pri = LOG_ERR;
174 *cup = cu->next; 117 break;
175 xfree(cu); 118 case SYSLOG_LEVEL_FATAL:
176 return; 119 txt = "fatal";
177 } 120 pri = LOG_ERR;
121 break;
122 case SYSLOG_LEVEL_INFO:
123 pri = LOG_INFO;
124 break;
125 case SYSLOG_LEVEL_CHAT:
126 pri = LOG_INFO;
127 break;
128 case SYSLOG_LEVEL_DEBUG:
129 txt = "debug";
130 pri = LOG_DEBUG;
131 break;
132 default:
133 txt = "internal error";
134 pri = LOG_ERR;
135 break;
178 } 136 }
179 fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n",
180 (unsigned long)proc, (unsigned long)context);
181}
182
183/* Fatal messages. This function never returns. */
184 137
185void fatal(const char *fmt, ...) 138 if (txt != NULL) {
186{ 139 snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt);
187 va_list args; 140 vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args);
188 struct fatal_cleanup *cu, *next_cu; 141 }else{
189 static int fatal_called = 0; 142 vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
190#if defined(KRB4) 143 }
191 extern char *ticket;
192#endif /* KRB4 */
193 DECL_MSGBUF;
194
195 if (log_quiet)
196 exit(1);
197 va_start(args, fmt);
198 vsnprintf(msgbuf, MSGBUFSIZE, fmt, args);
199 va_end(args);
200 if (log_on_stderr) 144 if (log_on_stderr)
201 fprintf(stderr, "fatal: %s\n", msgbuf); 145 fprintf(stderr, "%s\n", msgbuf);
202 syslog(LOG_ERR, "fatal: %.500s", msgbuf); 146 syslog(pri, "%.500s", msgbuf);
203
204 if (fatal_called)
205 exit(1);
206 fatal_called = 1;
207
208 /* Call cleanup functions. */
209 for (cu = fatal_cleanups; cu; cu = next_cu)
210 {
211 next_cu = cu->next;
212 debug("Calling cleanup 0x%lx(0x%lx)",
213 (unsigned long)cu->proc, (unsigned long)cu->context);
214 (*cu->proc)(cu->context);
215 }
216#if defined(KRB4)
217 /* If you forwarded a ticket you get one shot for proper
218 authentication. */
219 /* If tgt was passed unlink file */
220 if (ticket)
221 {
222 if (strcmp(ticket,"none"))
223 unlink(ticket);
224 else
225 ticket = NULL;
226 }
227#endif /* KRB4 */
228
229 /* If local XAUTHORITY was created, remove it. */
230 if (xauthfile) unlink(xauthfile);
231
232 exit(1);
233} 147}
diff --git a/log.c b/log.c
new file mode 100644
index 000000000..3e840ecb5
--- /dev/null
+++ b/log.c
@@ -0,0 +1,135 @@
1/*
2
3Shared versions of debug(), log(), etc.
4
5*/
6
7#include "includes.h"
8RCSID("$OpenBSD: log.c,v 1.1 1999/11/10 23:36:44 markus Exp $");
9
10#include "ssh.h"
11#include "xmalloc.h"
12
13/* Fatal messages. This function never returns. */
14
15void
16fatal(const char *fmt, ...)
17{
18 va_list args;
19 va_start(args, fmt);
20 do_log(SYSLOG_LEVEL_FATAL, fmt, args);
21 va_end(args);
22 fatal_cleanup();
23}
24
25/* Error messages that should be logged. */
26
27void
28error(const char *fmt, ...)
29{
30 va_list args;
31 va_start(args, fmt);
32 do_log(SYSLOG_LEVEL_ERROR, fmt, args);
33 va_end(args);
34}
35
36/* Log this message (information that usually should go to the log). */
37
38void
39log(const char *fmt, ...)
40{
41 va_list args;
42 va_start(args, fmt);
43 do_log(SYSLOG_LEVEL_INFO, fmt, args);
44 va_end(args);
45}
46
47/* More detailed messages (information that does not need to go to the log). */
48
49void
50chat(const char *fmt, ...)
51{
52 va_list args;
53 va_start(args, fmt);
54 do_log(SYSLOG_LEVEL_CHAT, fmt, args);
55 va_end(args);
56}
57
58/* Debugging messages that should not be logged during normal operation. */
59
60void
61debug(const char *fmt, ...)
62{
63 va_list args;
64 va_start(args, fmt);
65 do_log(SYSLOG_LEVEL_DEBUG, fmt, args);
66 va_end(args);
67}
68
69/* Fatal cleanup */
70
71struct fatal_cleanup
72{
73 struct fatal_cleanup *next;
74 void (*proc)(void *);
75 void *context;
76};
77
78static struct fatal_cleanup *fatal_cleanups = NULL;
79
80/* Registers a cleanup function to be called by fatal() before exiting. */
81
82void
83fatal_add_cleanup(void (*proc)(void *), void *context)
84{
85 struct fatal_cleanup *cu;
86
87 cu = xmalloc(sizeof(*cu));
88 cu->proc = proc;
89 cu->context = context;
90 cu->next = fatal_cleanups;
91 fatal_cleanups = cu;
92}
93
94/* Removes a cleanup frunction to be called at fatal(). */
95
96void
97fatal_remove_cleanup(void (*proc)(void *context), void *context)
98{
99 struct fatal_cleanup **cup, *cu;
100
101 for (cup = &fatal_cleanups; *cup; cup = &cu->next)
102 {
103 cu = *cup;
104 if (cu->proc == proc && cu->context == context)
105 {
106 *cup = cu->next;
107 xfree(cu);
108 return;
109 }
110 }
111 fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n",
112 (unsigned long)proc, (unsigned long)context);
113}
114
115/* Cleanup and exit */
116void
117fatal_cleanup(void)
118{
119 struct fatal_cleanup *cu, *next_cu;
120 static int called = 0;
121 if (called)
122 exit(255);
123 called = 1;
124
125 /* Call cleanup functions. */
126 for (cu = fatal_cleanups; cu; cu = next_cu)
127 {
128 next_cu = cu->next;
129 debug("Calling cleanup 0x%lx(0x%lx)",
130 (unsigned long)cu->proc, (unsigned long)cu->context);
131 (*cu->proc)(cu->context);
132 }
133
134 exit(255);
135}
diff --git a/readconf.c b/readconf.c
index 281548d2a..2a99266aa 100644
--- a/readconf.c
+++ b/readconf.c
@@ -14,7 +14,7 @@ Functions for reading the configuration files.
14*/ 14*/
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: readconf.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); 17RCSID("$Id: readconf.c,v 1.2 1999/11/11 06:57:39 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "cipher.h" 20#include "cipher.h"
@@ -101,7 +101,7 @@ typedef enum
101 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 101 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
102 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 102 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
103 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, 103 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
104 oUsePrivilegedPort 104 oUsePrivilegedPort, oLogLevel
105} OpCodes; 105} OpCodes;
106 106
107/* Textual representations of the tokens. */ 107/* Textual representations of the tokens. */
@@ -150,6 +150,24 @@ static struct
150 { "keepalive", oKeepAlives }, 150 { "keepalive", oKeepAlives },
151 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 151 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
152 { "tisauthentication", oTISAuthentication }, 152 { "tisauthentication", oTISAuthentication },
153 { "loglevel", oLogLevel },
154 { NULL, 0 }
155};
156
157/* textual representation of log-levels */
158
159static struct
160{
161 const char *name;
162 LogLevel level;
163} log_levels[] =
164{
165 { "QUIET", SYSLOG_LEVEL_QUIET },
166 { "FATAL", SYSLOG_LEVEL_FATAL },
167 { "ERROR", SYSLOG_LEVEL_ERROR },
168 { "INFO", SYSLOG_LEVEL_INFO },
169 { "CHAT", SYSLOG_LEVEL_CHAT },
170 { "DEBUG", SYSLOG_LEVEL_DEBUG },
153 { NULL, 0 } 171 { NULL, 0 }
154}; 172};
155 173
@@ -218,7 +236,7 @@ void process_config_line(Options *options, const char *host,
218 int *activep) 236 int *activep)
219{ 237{
220 char buf[256], *cp, *string, **charptr; 238 char buf[256], *cp, *string, **charptr;
221 int opcode, *intptr, value, fwd_port, fwd_host_port; 239 int opcode, *intptr, value, fwd_port, fwd_host_port, i;
222 240
223 /* Skip leading whitespace. */ 241 /* Skip leading whitespace. */
224 cp = line + strspn(line, WHITESPACE); 242 cp = line + strspn(line, WHITESPACE);
@@ -445,6 +463,27 @@ void process_config_line(Options *options, const char *host,
445 if (*activep && *intptr == -1) 463 if (*activep && *intptr == -1)
446 *intptr = value; 464 *intptr = value;
447 break; 465 break;
466
467 case oLogLevel:
468 cp = strtok(NULL, WHITESPACE);
469 if (!cp)
470 {
471 fprintf(stderr, "%s line %d: missing level name.\n",
472 filename, linenum);
473 exit(1);
474 }
475 for (i = 0; log_levels[i].name; i++)
476 if (strcasecmp(log_levels[i].name, cp) == 0)
477 break;
478 if (!log_levels[i].name)
479 {
480 fprintf(stderr, "%s line %d: unsupported log level %s\n",
481 filename, linenum, cp);
482 exit(1);
483 }
484 if (options->log_level == (LogLevel)(-1))
485 options->log_level = log_levels[i].level;
486 break;
448 487
449 case oRemoteForward: 488 case oRemoteForward:
450 cp = strtok(NULL, WHITESPACE); 489 cp = strtok(NULL, WHITESPACE);
@@ -607,6 +646,7 @@ void initialize_options(Options *options)
607 options->user_hostfile = NULL; 646 options->user_hostfile = NULL;
608 options->num_local_forwards = 0; 647 options->num_local_forwards = 0;
609 options->num_remote_forwards = 0; 648 options->num_remote_forwards = 0;
649 options->log_level = (LogLevel)-1;
610} 650}
611 651
612/* Called after processing other sources of option data, this fills those 652/* Called after processing other sources of option data, this fills those
@@ -677,6 +717,8 @@ void fill_default_options(Options *options)
677 options->system_hostfile = SSH_SYSTEM_HOSTFILE; 717 options->system_hostfile = SSH_SYSTEM_HOSTFILE;
678 if (options->user_hostfile == NULL) 718 if (options->user_hostfile == NULL)
679 options->user_hostfile = SSH_USER_HOSTFILE; 719 options->user_hostfile = SSH_USER_HOSTFILE;
720 if (options->log_level == (LogLevel)-1)
721 options->log_level = SYSLOG_LEVEL_INFO;
680 /* options->proxy_command should not be set by default */ 722 /* options->proxy_command should not be set by default */
681 /* options->user will be set in the main program if appropriate */ 723 /* options->user will be set in the main program if appropriate */
682 /* options->hostname will be set in the main program if appropriate */ 724 /* options->hostname will be set in the main program if appropriate */
diff --git a/readconf.h b/readconf.h
index 71655bd28..8839a1bd5 100644
--- a/readconf.h
+++ b/readconf.h
@@ -13,7 +13,7 @@ Functions for reading the configuration file.
13 13
14*/ 14*/
15 15
16/* RCSID("$Id: readconf.h,v 1.1 1999/10/27 03:42:44 damien Exp $"); */ 16/* RCSID("$Id: readconf.h,v 1.2 1999/11/11 06:57:39 damien Exp $"); */
17 17
18#ifndef READCONF_H 18#ifndef READCONF_H
19#define READCONF_H 19#define READCONF_H
@@ -54,6 +54,7 @@ typedef struct
54 int compression; /* Compress packets in both directions. */ 54 int compression; /* Compress packets in both directions. */
55 int compression_level; /* Compression level 1 (fast) to 9 (best). */ 55 int compression_level; /* Compression level 1 (fast) to 9 (best). */
56 int keepalives; /* Set SO_KEEPALIVE. */ 56 int keepalives; /* Set SO_KEEPALIVE. */
57 LogLevel log_level; /* Level for logging. */
57 58
58 int port; /* Port to connect. */ 59 int port; /* Port to connect. */
59 int connection_attempts; /* Max attempts (seconds) before giving up */ 60 int connection_attempts; /* Max attempts (seconds) before giving up */
diff --git a/servconf.c b/servconf.c
index 5fa48790f..d7f54a62f 100644
--- a/servconf.c
+++ b/servconf.c
@@ -12,7 +12,7 @@ Created: Mon Aug 21 15:48:58 1995 ylo
12*/ 12*/
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$Id: servconf.c,v 1.1 1999/10/27 03:42:45 damien Exp $"); 15RCSID("$Id: servconf.c,v 1.2 1999/11/11 06:57:39 damien Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "servconf.h" 18#include "servconf.h"
@@ -31,8 +31,6 @@ void initialize_server_options(ServerOptions *options)
31 options->key_regeneration_time = -1; 31 options->key_regeneration_time = -1;
32 options->permit_root_login = -1; 32 options->permit_root_login = -1;
33 options->ignore_rhosts = -1; 33 options->ignore_rhosts = -1;
34 options->quiet_mode = -1;
35 options->fascist_logging = -1;
36 options->print_motd = -1; 34 options->print_motd = -1;
37 options->check_mail = -1; 35 options->check_mail = -1;
38 options->x11_forwarding = -1; 36 options->x11_forwarding = -1;
@@ -40,6 +38,7 @@ void initialize_server_options(ServerOptions *options)
40 options->strict_modes = -1; 38 options->strict_modes = -1;
41 options->keepalives = -1; 39 options->keepalives = -1;
42 options->log_facility = (SyslogFacility)-1; 40 options->log_facility = (SyslogFacility)-1;
41 options->log_level = (LogLevel)-1;
43 options->rhosts_authentication = -1; 42 options->rhosts_authentication = -1;
44 options->rhosts_rsa_authentication = -1; 43 options->rhosts_rsa_authentication = -1;
45 options->rsa_authentication = -1; 44 options->rsa_authentication = -1;
@@ -89,12 +88,8 @@ void fill_default_server_options(ServerOptions *options)
89 options->permit_root_login = 1; /* yes */ 88 options->permit_root_login = 1; /* yes */
90 if (options->ignore_rhosts == -1) 89 if (options->ignore_rhosts == -1)
91 options->ignore_rhosts = 0; 90 options->ignore_rhosts = 0;
92 if (options->quiet_mode == -1)
93 options->quiet_mode = 0;
94 if (options->check_mail == -1) 91 if (options->check_mail == -1)
95 options->check_mail = 0; 92 options->check_mail = 0;
96 if (options->fascist_logging == -1)
97 options->fascist_logging = 1;
98 if (options->print_motd == -1) 93 if (options->print_motd == -1)
99 options->print_motd = 1; 94 options->print_motd = 1;
100 if (options->x11_forwarding == -1) 95 if (options->x11_forwarding == -1)
@@ -107,6 +102,8 @@ void fill_default_server_options(ServerOptions *options)
107 options->keepalives = 1; 102 options->keepalives = 1;
108 if (options->log_facility == (SyslogFacility)(-1)) 103 if (options->log_facility == (SyslogFacility)(-1))
109 options->log_facility = SYSLOG_FACILITY_AUTH; 104 options->log_facility = SYSLOG_FACILITY_AUTH;
105 if (options->log_level == (LogLevel)(-1))
106 options->log_level = SYSLOG_LEVEL_INFO;
110 if (options->rhosts_authentication == -1) 107 if (options->rhosts_authentication == -1)
111 options->rhosts_authentication = 0; 108 options->rhosts_authentication = 0;
112 if (options->rhosts_rsa_authentication == -1) 109 if (options->rhosts_rsa_authentication == -1)
@@ -145,7 +142,7 @@ void fill_default_server_options(ServerOptions *options)
145typedef enum 142typedef enum
146{ 143{
147 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, 144 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
148 sPermitRootLogin, sQuietMode, sFascistLogging, sLogFacility, 145 sPermitRootLogin, sLogFacility, sLogLevel,
149 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, 146 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
150#ifdef KRB4 147#ifdef KRB4
151 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 148 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
@@ -176,9 +173,8 @@ static struct
176 { "logingracetime", sLoginGraceTime }, 173 { "logingracetime", sLoginGraceTime },
177 { "keyregenerationinterval", sKeyRegenerationTime }, 174 { "keyregenerationinterval", sKeyRegenerationTime },
178 { "permitrootlogin", sPermitRootLogin }, 175 { "permitrootlogin", sPermitRootLogin },
179 { "quietmode", sQuietMode },
180 { "fascistlogging", sFascistLogging },
181 { "syslogfacility", sLogFacility }, 176 { "syslogfacility", sLogFacility },
177 { "loglevel", sLogLevel },
182 { "rhostsauthentication", sRhostsAuthentication }, 178 { "rhostsauthentication", sRhostsAuthentication },
183 { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 179 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
184 { "rsaauthentication", sRSAAuthentication }, 180 { "rsaauthentication", sRSAAuthentication },
@@ -233,6 +229,21 @@ static struct
233 { NULL, 0 } 229 { NULL, 0 }
234}; 230};
235 231
232static struct
233{
234 const char *name;
235 LogLevel level;
236} log_levels[] =
237{
238 { "QUIET", SYSLOG_LEVEL_QUIET },
239 { "FATAL", SYSLOG_LEVEL_FATAL },
240 { "ERROR", SYSLOG_LEVEL_ERROR },
241 { "INFO", SYSLOG_LEVEL_INFO },
242 { "CHAT", SYSLOG_LEVEL_CHAT },
243 { "DEBUG", SYSLOG_LEVEL_DEBUG },
244 { NULL, 0 }
245};
246
236/* Returns the number of the token pointed to by cp of length len. 247/* Returns the number of the token pointed to by cp of length len.
237 Never returns if the token is not known. */ 248 Never returns if the token is not known. */
238 249
@@ -392,14 +403,6 @@ void read_server_config(ServerOptions *options, const char *filename)
392 *intptr = value; 403 *intptr = value;
393 break; 404 break;
394 405
395 case sQuietMode:
396 intptr = &options->quiet_mode;
397 goto parse_flag;
398
399 case sFascistLogging:
400 intptr = &options->fascist_logging;
401 goto parse_flag;
402
403 case sRhostsAuthentication: 406 case sRhostsAuthentication:
404 intptr = &options->rhosts_authentication; 407 intptr = &options->rhosts_authentication;
405 goto parse_flag; 408 goto parse_flag;
@@ -487,7 +490,7 @@ void read_server_config(ServerOptions *options, const char *filename)
487 exit(1); 490 exit(1);
488 } 491 }
489 for (i = 0; log_facilities[i].name; i++) 492 for (i = 0; log_facilities[i].name; i++)
490 if (strcmp(log_facilities[i].name, cp) == 0) 493 if (strcasecmp(log_facilities[i].name, cp) == 0)
491 break; 494 break;
492 if (!log_facilities[i].name) 495 if (!log_facilities[i].name)
493 { 496 {
@@ -498,6 +501,27 @@ void read_server_config(ServerOptions *options, const char *filename)
498 if (options->log_facility == (SyslogFacility)(-1)) 501 if (options->log_facility == (SyslogFacility)(-1))
499 options->log_facility = log_facilities[i].facility; 502 options->log_facility = log_facilities[i].facility;
500 break; 503 break;
504
505 case sLogLevel:
506 cp = strtok(NULL, WHITESPACE);
507 if (!cp)
508 {
509 fprintf(stderr, "%s line %d: missing level name.\n",
510 filename, linenum);
511 exit(1);
512 }
513 for (i = 0; log_levels[i].name; i++)
514 if (strcasecmp(log_levels[i].name, cp) == 0)
515 break;
516 if (!log_levels[i].name)
517 {
518 fprintf(stderr, "%s line %d: unsupported log level %s\n",
519 filename, linenum, cp);
520 exit(1);
521 }
522 if (options->log_level == (LogLevel)(-1))
523 options->log_level = log_levels[i].level;
524 break;
501 525
502 case sAllowUsers: 526 case sAllowUsers:
503 while ((cp = strtok(NULL, WHITESPACE))) 527 while ((cp = strtok(NULL, WHITESPACE)))
diff --git a/servconf.h b/servconf.h
index 22c73fd73..584935bad 100644
--- a/servconf.h
+++ b/servconf.h
@@ -13,7 +13,7 @@ Definitions for server configuration data and for the functions reading it.
13 13
14*/ 14*/
15 15
16/* RCSID("$Id: servconf.h,v 1.1 1999/10/27 03:42:45 damien Exp $"); */ 16/* RCSID("$Id: servconf.h,v 1.2 1999/11/11 06:57:40 damien Exp $"); */
17 17
18#ifndef SERVCONF_H 18#ifndef SERVCONF_H
19#define SERVCONF_H 19#define SERVCONF_H
@@ -33,8 +33,6 @@ typedef struct
33 int key_regeneration_time; /* Server key lifetime (seconds). */ 33 int key_regeneration_time; /* Server key lifetime (seconds). */
34 int permit_root_login; /* If true, permit root login. */ 34 int permit_root_login; /* If true, permit root login. */
35 int ignore_rhosts; /* Ignore .rhosts and .shosts. */ 35 int ignore_rhosts; /* Ignore .rhosts and .shosts. */
36 int quiet_mode; /* If true, don't log anything but fatals. */
37 int fascist_logging; /* Perform very verbose logging. */
38 int print_motd; /* If true, print /etc/motd. */ 36 int print_motd; /* If true, print /etc/motd. */
39 int check_mail; /* If true, check for new mail. */ 37 int check_mail; /* If true, check for new mail. */
40 int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ 38 int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */
@@ -42,6 +40,7 @@ typedef struct
42 int strict_modes; /* If true, require string home dir modes. */ 40 int strict_modes; /* If true, require string home dir modes. */
43 int keepalives; /* If true, set SO_KEEPALIVE. */ 41 int keepalives; /* If true, set SO_KEEPALIVE. */
44 SyslogFacility log_facility; /* Facility for system logging. */ 42 SyslogFacility log_facility; /* Facility for system logging. */
43 LogLevel log_level; /* Level for system logging. */
45 int rhosts_authentication; /* If true, permit rhosts authentication. */ 44 int rhosts_authentication; /* If true, permit rhosts authentication. */
46 int rhosts_rsa_authentication;/* If true, permit rhosts RSA authentication.*/ 45 int rhosts_rsa_authentication;/* If true, permit rhosts RSA authentication.*/
47 int rsa_authentication; /* If true, permit RSA authentication. */ 46 int rsa_authentication; /* If true, permit RSA authentication. */
diff --git a/ssh.1 b/ssh.1
index 3ea1c27b6..34a8ce96f 100644
--- a/ssh.1
+++ b/ssh.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 21:55:14 1995 ylo 10.\" Created: Sat Apr 22 21:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: ssh.1,v 1.5 1999/11/11 00:43:13 damien Exp $ 12.\" $Id: ssh.1,v 1.6 1999/11/11 06:57:40 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH 1 15.Dt SSH 1
@@ -602,6 +602,12 @@ this keyword must be
602.Dq yes 602.Dq yes
603or 603or
604.Dq no . 604.Dq no .
605.It Cm LogLevel
606Gives the verbosity level that is used when logging messages from
607.Nm ssh .
608The possible values are:
609QUIET, FATAL, ERROR, INFO, CHAT and DEBUG.
610The default is INFO.
605.It Cm NumberOfPasswordPrompts 611.It Cm NumberOfPasswordPrompts
606Specifies the number of password prompts before giving up. The 612Specifies the number of password prompts before giving up. The
607argument to this keyword must be an integer. Default is 3. 613argument to this keyword must be an integer. Default is 3.
diff --git a/ssh.c b/ssh.c
index 763004892..be5ad2cc7 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.
18*/ 18*/
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: ssh.c,v 1.4 1999/10/30 01:39:56 damien Exp $"); 21RCSID("$Id: ssh.c,v 1.5 1999/11/11 06:57:40 damien Exp $");
22 22
23#include "xmalloc.h" 23#include "xmalloc.h"
24#include "ssh.h" 24#include "ssh.h"
@@ -32,9 +32,6 @@ RCSID("$Id: ssh.c,v 1.4 1999/10/30 01:39:56 damien Exp $");
32 command line. */ 32 command line. */
33int debug_flag = 0; 33int debug_flag = 0;
34 34
35/* Flag indicating whether quiet mode is on. */
36int quiet_flag = 0;
37
38/* Flag indicating whether to allocate a pseudo tty. This can be set on the 35/* Flag indicating whether to allocate a pseudo tty. This can be set on the
39 command line, and is automatically set if no command is given on the command 36 command line, and is automatically set if no command is given on the command
40 line. */ 37 line. */
@@ -306,16 +303,17 @@ main(int ac, char **av)
306 303
307 case 'v': 304 case 'v':
308 case 'V': 305 case 'V':
309 debug_flag = 1;
310 fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n", 306 fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n",
311 SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR); 307 SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR);
312 fprintf(stderr, "Compiled with SSL.\n"); 308 fprintf(stderr, "Compiled with SSL.\n");
313 if (opt == 'V') 309 if (opt == 'V')
314 exit(0); 310 exit(0);
311 debug_flag = 1;
312 options.log_level = SYSLOG_LEVEL_DEBUG;
315 break; 313 break;
316 314
317 case 'q': 315 case 'q':
318 quiet_flag = 1; 316 options.log_level = SYSLOG_LEVEL_QUIET;
319 break; 317 break;
320 318
321 case 'e': 319 case 'e':
@@ -466,7 +464,7 @@ main(int ac, char **av)
466 464
467 /* Initialize "log" output. Since we are the client all output actually 465 /* Initialize "log" output. Since we are the client all output actually
468 goes to the terminal. */ 466 goes to the terminal. */
469 log_init(av[0], 1, debug_flag, quiet_flag, SYSLOG_FACILITY_USER); 467 log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0);
470 468
471 /* Read per-user configuration file. */ 469 /* Read per-user configuration file. */
472 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_CONFFILE); 470 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_CONFFILE);
@@ -477,6 +475,10 @@ main(int ac, char **av)
477 475
478 /* Fill configuration defaults. */ 476 /* Fill configuration defaults. */
479 fill_default_options(&options); 477 fill_default_options(&options);
478
479 /* reinit */
480 log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0);
481
480 if (options.user == NULL) 482 if (options.user == NULL)
481 options.user = xstrdup(pw->pw_name); 483 options.user = xstrdup(pw->pw_name);
482 484
diff --git a/ssh.h b/ssh.h
index a91312a81..da818b225 100644
--- a/ssh.h
+++ b/ssh.h
@@ -13,26 +13,14 @@ Generic header file for ssh.
13 13
14*/ 14*/
15 15
16/* RCSID("$Id: ssh.h,v 1.9 1999/11/10 23:40:23 damien Exp $"); */ 16/* RCSID("$Id: ssh.h,v 1.10 1999/11/11 06:57:40 damien Exp $"); */
17 17
18#ifndef SSH_H 18#ifndef SSH_H
19#define SSH_H 19#define SSH_H
20 20
21#include <netinet/in.h> /* For struct sockaddr_in */ 21#include <netinet/in.h> /* For struct sockaddr_in */
22#include <pwd.h> /* For struct pw */ 22#include <pwd.h> /* For struct pw */
23 23#include <stdarg.h> /* For va_list */
24#ifndef SHUT_RDWR
25enum
26{
27 SHUT_RD = 0, /* No more receptions. */
28#define SHUT_RD SHUT_RD
29 SHUT_WR, /* No more transmissions. */
30#define SHUT_WR SHUT_WR
31 SHUT_RDWR /* No more receptions or transmissions. */
32#define SHUT_RDWR SHUT_RDWR
33};
34#endif
35
36 24
37#include "rsa.h" 25#include "rsa.h"
38#include "cipher.h" 26#include "cipher.h"
@@ -234,9 +222,58 @@ only by root, whereas ssh_config should be world-readable. */
234#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */ 222#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */
235 223
236 224
237/* Includes that need definitions above. */ 225/*------------ Definitions for logging. -----------------------*/
226
227/* Supported syslog facilities and levels. */
228typedef enum
229{
230 SYSLOG_FACILITY_DAEMON,
231 SYSLOG_FACILITY_USER,
232 SYSLOG_FACILITY_AUTH,
233 SYSLOG_FACILITY_LOCAL0,
234 SYSLOG_FACILITY_LOCAL1,
235 SYSLOG_FACILITY_LOCAL2,
236 SYSLOG_FACILITY_LOCAL3,
237 SYSLOG_FACILITY_LOCAL4,
238 SYSLOG_FACILITY_LOCAL5,
239 SYSLOG_FACILITY_LOCAL6,
240 SYSLOG_FACILITY_LOCAL7
241} SyslogFacility;
242
243typedef enum
244{
245 SYSLOG_LEVEL_QUIET,
246 SYSLOG_LEVEL_FATAL,
247 SYSLOG_LEVEL_ERROR,
248 SYSLOG_LEVEL_INFO,
249 SYSLOG_LEVEL_CHAT,
250 SYSLOG_LEVEL_DEBUG
251} LogLevel;
252
253/* Initializes logging. */
254void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr);
255
256/* Logging implementation, depending on server or client */
257void do_log(LogLevel level, const char *fmt, va_list args);
258
259/* Output a message to syslog or stderr */
260void fatal(const char *fmt, ...);
261void error(const char *fmt, ...);
262void log(const char *fmt, ...);
263void chat(const char *fmt, ...);
264void debug(const char *fmt, ...);
265
266/* same as fatal() but w/o logging */
267void fatal_cleanup(void);
268
269/* Registers a cleanup function to be called by fatal()/fatal_cleanup() before exiting.
270 It is permissible to call fatal_remove_cleanup for the function itself
271 from the function. */
272void fatal_add_cleanup(void (*proc)(void *context), void *context);
273
274/* Removes a cleanup function to be called at fatal(). */
275void fatal_remove_cleanup(void (*proc)(void *context), void *context);
238 276
239#include "readconf.h"
240 277
241/*------------ definitions for login.c -------------*/ 278/*------------ definitions for login.c -------------*/
242 279
@@ -276,6 +313,10 @@ int ssh_connect(const char *host, struct sockaddr_in *hostaddr,
276 If login fails, this function prints an error and never returns. 313 If login fails, this function prints an error and never returns.
277 This initializes the random state, and leaves it initialized (it will also 314 This initializes the random state, and leaves it initialized (it will also
278 have references from the packet module). */ 315 have references from the packet module). */
316
317/* for Options */
318#include "readconf.h"
319
279void ssh_login(int host_key_valid, RSA *host_key, const char *host, 320void ssh_login(int host_key_valid, RSA *host_key, const char *host,
280 struct sockaddr_in *hostaddr, Options *options, 321 struct sockaddr_in *hostaddr, Options *options,
281 uid_t original_real_uid); 322 uid_t original_real_uid);
@@ -381,59 +422,6 @@ int load_public_key(const char *filename, RSA *pub,
381int load_private_key(const char *filename, const char *passphrase, 422int load_private_key(const char *filename, const char *passphrase,
382 RSA *private_key, char **comment_return); 423 RSA *private_key, char **comment_return);
383 424
384/*------------ Definitions for logging. -----------------------*/
385
386/* Supported syslog facilities. */
387typedef enum
388{
389 SYSLOG_FACILITY_DAEMON,
390 SYSLOG_FACILITY_USER,
391 SYSLOG_FACILITY_AUTH,
392 SYSLOG_FACILITY_LOCAL0,
393 SYSLOG_FACILITY_LOCAL1,
394 SYSLOG_FACILITY_LOCAL2,
395 SYSLOG_FACILITY_LOCAL3,
396 SYSLOG_FACILITY_LOCAL4,
397 SYSLOG_FACILITY_LOCAL5,
398 SYSLOG_FACILITY_LOCAL6,
399 SYSLOG_FACILITY_LOCAL7
400} SyslogFacility;
401
402/* Initializes logging. If debug is non-zero, debug() will output something.
403 If quiet is non-zero, none of these will log send anything to syslog
404 (but maybe to stderr). */
405void log_init(char *av0, int on_stderr, int debug, int quiet,
406 SyslogFacility facility);
407
408/* Outputs a message to syslog or stderr, depending on the implementation.
409 The format must guarantee that the final message does not exceed 1024
410 characters. The message should not contain newline. */
411void log(const char *fmt, ...);
412
413/* Outputs a message to syslog or stderr, depending on the implementation.
414 The format must guarantee that the final message does not exceed 1024
415 characters. The message should not contain newline. */
416void debug(const char *fmt, ...);
417
418/* Outputs a message to syslog or stderr, depending on the implementation.
419 The format must guarantee that the final message does not exceed 1024
420 characters. The message should not contain newline. */
421void error(const char *fmt, ...);
422
423/* Outputs a message to syslog or stderr, depending on the implementation.
424 The format must guarantee that the final message does not exceed 1024
425 characters. The message should not contain newline.
426 This call never returns. */
427void fatal(const char *fmt, ...);
428
429/* Registers a cleanup function to be called by fatal() before exiting.
430 It is permissible to call fatal_remove_cleanup for the function itself
431 from the function. */
432void fatal_add_cleanup(void (*proc)(void *context), void *context);
433
434/* Removes a cleanup frunction to be called at fatal(). */
435void fatal_remove_cleanup(void (*proc)(void *context), void *context);
436
437/*---------------- definitions for channels ------------------*/ 425/*---------------- definitions for channels ------------------*/
438 426
439/* Sets specific protocol options. */ 427/* Sets specific protocol options. */
@@ -547,9 +535,6 @@ void x11_request_forwarding(void);
547 This should be called in the client only. */ 535 This should be called in the client only. */
548void x11_request_forwarding_with_spoofing(const char *proto, const char *data); 536void x11_request_forwarding_with_spoofing(const char *proto, const char *data);
549 537
550/* Local Xauthority file (server only). */
551extern char *xauthfile;
552
553/* Sends a message to the server to request authentication fd forwarding. */ 538/* Sends a message to the server to request authentication fd forwarding. */
554void auth_request_forwarding(void); 539void auth_request_forwarding(void);
555 540
@@ -596,7 +581,8 @@ struct envstring {
596 0 if the client could not be authenticated, and 1 if authentication was 581 0 if the client could not be authenticated, and 1 if authentication was
597 successful. This may exit if there is a serious protocol violation. */ 582 successful. This may exit if there is a serious protocol violation. */
598int auth_krb4(const char *server_user, KTEXT auth, char **client); 583int auth_krb4(const char *server_user, KTEXT auth, char **client);
599int ssh_tf_init(uid_t uid); 584int krb4_init(uid_t uid);
585void krb4_cleanup_proc(void *ignore);
600 586
601#ifdef AFS 587#ifdef AFS
602#include <kafs.h> 588#include <kafs.h>
diff --git a/sshd.8 b/sshd.8
index fd1f7f02b..20e9712a5 100644
--- a/sshd.8
+++ b/sshd.8
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 21:55:14 1995 ylo 10.\" Created: Sat Apr 22 21:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: sshd.8,v 1.5 1999/11/11 00:43:13 damien Exp $ 12.\" $Id: sshd.8,v 1.6 1999/11/11 06:57:40 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSHD 8 15.Dt SSHD 8
@@ -231,15 +231,6 @@ can be used as
231wildcards in the patterns. Only user names are valid, a numerical user 231wildcards in the patterns. Only user names are valid, a numerical user
232id isn't recognized. By default login is allowed regardless of 232id isn't recognized. By default login is allowed regardless of
233the user name. 233the user name.
234.Pp
235.It Cm FascistLogging
236Specifies whether to use verbose logging. Verbose logging violates
237the privacy of users and is not recommended. The argument must be
238.Dq yes
239or
240.Dq no .
241The default is
242.Dq no .
243.It Cm HostKey 234.It Cm HostKey
244Specifies the file containing the private host key (default 235Specifies the file containing the private host key (default
245.Pa /etc/ssh/ssh_host_key ) . 236.Pa /etc/ssh/ssh_host_key ) .
@@ -312,6 +303,14 @@ The default is to listen to all local addresses.
312The server disconnects after this time if the user has not 303The server disconnects after this time if the user has not
313successfully logged in. If the value is 0, there is no time limit. 304successfully logged in. If the value is 0, there is no time limit.
314The default is 600 (seconds). 305The default is 600 (seconds).
306.It Cm LogLevel
307Gives the verbosity level that is used when logging messages from
308.Nm sshd .
309The possible values are:
310QUIET, FATAL, ERROR, INFO, CHAT and DEBUG.
311The default is INFO.
312Logging with level DEBUG violates the privacy of users
313and is not recommended.
315.It Cm PasswordAuthentication 314.It Cm PasswordAuthentication
316Specifies whether password authentication is allowed. 315Specifies whether password authentication is allowed.
317The default is 316The default is
@@ -355,11 +354,6 @@ printed by the shell,
355.Pa /etc/profile , 354.Pa /etc/profile ,
356or equivalent.) The default is 355or equivalent.) The default is
357.Dq yes . 356.Dq yes .
358.It Cm QuietMode
359Specifies whether the system runs in quiet mode. In quiet mode,
360nothing is logged in the system log, except fatal errors. The default
361is
362.Dq no .
363.It Cm RandomSeed 357.It Cm RandomSeed
364Obsolete. Random number generation uses other techniques. 358Obsolete. Random number generation uses other techniques.
365.It Cm RhostsAuthentication 359.It Cm RhostsAuthentication
@@ -622,8 +616,8 @@ This file must be readable by root (which may on some machines imply
622it being world-readable if the user's home directory resides on an NFS 616it being world-readable if the user's home directory resides on an NFS
623volume). It is recommended that it not be accessible by others. The 617volume). It is recommended that it not be accessible by others. The
624format of this file is described above. 618format of this file is described above.
625.It Pa "/etc/ssh/ssh_known_hosts" and "$HOME/.ssh/known_hosts" 619.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts"
626This file is consulted when using rhosts with RSA host 620These files are consulted when using rhosts with RSA host
627authentication to check the public key of the host. The key must be 621authentication to check the public key of the host. The key must be
628listed in one of these files to be accepted. 622listed in one of these files to be accepted.
629The client uses the same files 623The client uses the same files
diff --git a/sshd.c b/sshd.c
index a1f9449e2..75ea61ead 100644
--- a/sshd.c
+++ b/sshd.c
@@ -18,7 +18,7 @@ agent connections.
18*/ 18*/
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: sshd.c,v 1.12 1999/11/08 05:15:55 damien Exp $"); 21RCSID("$Id: sshd.c,v 1.13 1999/11/11 06:57:40 damien Exp $");
22 22
23#include "xmalloc.h" 23#include "xmalloc.h"
24#include "rsa.h" 24#include "rsa.h"
@@ -43,12 +43,8 @@ int deny_severity = LOG_WARNING;
43#define O_NOCTTY 0 43#define O_NOCTTY 0
44#endif 44#endif
45 45
46#ifdef KRB4
47char *ticket = NULL;
48#endif /* KRB4 */
49
50/* Local Xauthority file. */ 46/* Local Xauthority file. */
51char *xauthfile = NULL; 47static char *xauthfile = NULL;
52 48
53/* Server configuration options. */ 49/* Server configuration options. */
54ServerOptions options; 50ServerOptions options;
@@ -65,6 +61,9 @@ int debug_flag = 0;
65/* Flag indicating that the daemon is being started from inetd. */ 61/* Flag indicating that the daemon is being started from inetd. */
66int inetd_flag = 0; 62int inetd_flag = 0;
67 63
64/* debug goes to stderr unless inetd_flag is set */
65int log_stderr = 0;
66
68/* argv[0] without path. */ 67/* argv[0] without path. */
69char *av0; 68char *av0;
70 69
@@ -400,6 +399,7 @@ main(int ac, char **av)
400 break; 399 break;
401 case 'd': 400 case 'd':
402 debug_flag = 1; 401 debug_flag = 1;
402 options.log_level = SYSLOG_LEVEL_DEBUG;
403 break; 403 break;
404 case 'i': 404 case 'i':
405 inetd_flag = 1; 405 inetd_flag = 1;
@@ -408,7 +408,7 @@ main(int ac, char **av)
408 silentrsa = 1; 408 silentrsa = 1;
409 break; 409 break;
410 case 'q': 410 case 'q':
411 options.quiet_mode = 1; 411 options.log_level = SYSLOG_LEVEL_QUIET;
412 break; 412 break;
413 case 'b': 413 case 'b':
414 options.server_key_bits = atoi(optarg); 414 options.server_key_bits = atoi(optarg);
@@ -479,9 +479,11 @@ main(int ac, char **av)
479 } 479 }
480 480
481 /* Initialize the log (it is reinitialized below in case we forked). */ 481 /* Initialize the log (it is reinitialized below in case we forked). */
482 log_init(av0, debug_flag && !inetd_flag, 482
483 debug_flag || options.fascist_logging, 483 if (debug_flag && !inetd_flag)
484 options.quiet_mode, options.log_facility); 484 log_stderr = 1;
485
486 log_init(av0, options.log_level, options.log_facility, log_stderr);
485 487
486 debug("sshd version %.100s", SSH_VERSION); 488 debug("sshd version %.100s", SSH_VERSION);
487 489
@@ -496,7 +498,8 @@ main(int ac, char **av)
496 else 498 else
497 { 499 {
498 int err = errno; 500 int err = errno;
499 log_init(av0, !inetd_flag, 1, 0, options.log_facility); 501 /* force logging */
502 log_init(av0, SYSLOG_LEVEL_DEBUG, options.log_facility, log_stderr);
500 error("Could not load host key: %.200s: %.100s", 503 error("Could not load host key: %.200s: %.100s",
501 options.host_key_file, strerror(err)); 504 options.host_key_file, strerror(err));
502 } 505 }
@@ -526,9 +529,7 @@ main(int ac, char **av)
526 } 529 }
527 530
528 /* Reinitialize the log (because of the fork above). */ 531 /* Reinitialize the log (because of the fork above). */
529 log_init(av0, debug_flag && !inetd_flag, 532 log_init(av0, options.log_level, options.log_facility, log_stderr);
530 debug_flag || options.fascist_logging,
531 options.quiet_mode, options.log_facility);
532 533
533 /* Check that server and host key lengths differ sufficiently. This is 534 /* Check that server and host key lengths differ sufficiently. This is
534 necessary to make double encryption work with rsaref. Oh, I hate 535 necessary to make double encryption work with rsaref. Oh, I hate
@@ -696,9 +697,7 @@ main(int ac, char **av)
696 close(listen_sock); 697 close(listen_sock);
697 sock_in = newsock; 698 sock_in = newsock;
698 sock_out = newsock; 699 sock_out = newsock;
699 log_init(av0, debug_flag && !inetd_flag, 700 log_init(av0, options.log_level, options.log_facility, log_stderr);
700 options.fascist_logging || debug_flag,
701 options.quiet_mode, options.log_facility);
702 break; 701 break;
703 } 702 }
704 } 703 }
@@ -1605,6 +1604,19 @@ void eat_packets_and_disconnect(const char *user)
1605 abort(); 1604 abort();
1606} 1605}
1607 1606
1607/* Remove local Xauthority file. */
1608static void
1609xauthfile_cleanup_proc(void *ignore)
1610{
1611 debug("xauthfile_cleanup_proc called");
1612
1613 if (xauthfile != NULL) {
1614 unlink(xauthfile);
1615 xfree(xauthfile);
1616 xauthfile = NULL;
1617 }
1618}
1619
1608/* Prepares for an interactive session. This is called after the user has 1620/* Prepares for an interactive session. This is called after the user has
1609 been successfully authenticated. During this message exchange, pseudo 1621 been successfully authenticated. During this message exchange, pseudo
1610 terminals are allocated, X11, TCP/IP, and authentication agent forwardings 1622 terminals are allocated, X11, TCP/IP, and authentication agent forwardings
@@ -1760,6 +1772,7 @@ void do_authenticated(struct passwd *pw)
1760 if ((xauthfd = mkstemp(xauthfile)) != -1) { 1772 if ((xauthfd = mkstemp(xauthfile)) != -1) {
1761 fchown(xauthfd, pw->pw_uid, pw->pw_gid); 1773 fchown(xauthfd, pw->pw_uid, pw->pw_gid);
1762 close(xauthfd); 1774 close(xauthfd);
1775 fatal_add_cleanup(xauthfile_cleanup_proc, NULL);
1763 } 1776 }
1764 else { 1777 else {
1765 xfree(xauthfile); 1778 xfree(xauthfile);
@@ -1905,8 +1918,7 @@ void do_exec_no_pty(const char *command, struct passwd *pw,
1905 if ((pid = fork()) == 0) 1918 if ((pid = fork()) == 0)
1906 { 1919 {
1907 /* Child. Reinitialize the log since the pid has changed. */ 1920 /* Child. Reinitialize the log since the pid has changed. */
1908 log_init(av0, debug_flag && !inetd_flag, debug_flag, 1921 log_init(av0, options.log_level, options.log_facility, log_stderr);
1909 options.quiet_mode, options.log_facility);
1910 1922
1911 /* Create a new session and process group since the 4.4BSD setlogin() 1923 /* Create a new session and process group since the 4.4BSD setlogin()
1912 affects the entire process group. */ 1924 affects the entire process group. */
@@ -1988,11 +2000,6 @@ void pty_cleanup_proc(void *context)
1988 2000
1989 debug("pty_cleanup_proc called"); 2001 debug("pty_cleanup_proc called");
1990 2002
1991#if defined(KRB4)
1992 /* Destroy user's ticket cache file. */
1993 (void) dest_tkt();
1994#endif /* KRB4 */
1995
1996 /* Record that the user has logged out. */ 2003 /* Record that the user has logged out. */
1997 record_logout(cu->pid, cu->ttyname); 2004 record_logout(cu->pid, cu->ttyname);
1998 2005
@@ -2040,8 +2047,7 @@ void do_exec_pty(const char *command, int ptyfd, int ttyfd,
2040 pid = getpid(); 2047 pid = getpid();
2041 2048
2042 /* Child. Reinitialize the log because the pid has changed. */ 2049 /* Child. Reinitialize the log because the pid has changed. */
2043 log_init(av0, debug_flag && !inetd_flag, debug_flag, options.quiet_mode, 2050 log_init(av0, options.log_level, options.log_facility, log_stderr);
2044 options.log_facility);
2045 2051
2046 /* Close the master side of the pseudo tty. */ 2052 /* Close the master side of the pseudo tty. */
2047 close(ptyfd); 2053 close(ptyfd);
@@ -2395,8 +2401,12 @@ void do_child(const char *command, struct passwd *pw, const char *term,
2395 child_set_env(&env, &envsize, "DISPLAY", display); 2401 child_set_env(&env, &envsize, "DISPLAY", display);
2396 2402
2397#ifdef KRB4 2403#ifdef KRB4
2398 if (ticket) 2404 {
2399 child_set_env(&env, &envsize, "KRBTKFILE", ticket); 2405 extern char *ticket;
2406
2407 if (ticket)
2408 child_set_env(&env, &envsize, "KRBTKFILE", ticket);
2409 }
2400#endif /* KRB4 */ 2410#endif /* KRB4 */
2401 2411
2402#ifdef HAVE_LIBPAM 2412#ifdef HAVE_LIBPAM