summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auth-passwd.c38
-rw-r--r--auth-rh-rsa.c20
-rw-r--r--auth-rhosts.c57
-rw-r--r--auth-rsa.c95
-rw-r--r--auth-skey.c8
-rw-r--r--authfd.c127
-rw-r--r--authfd.h82
-rw-r--r--authfile.c63
-rw-r--r--bufaux.c4
-rw-r--r--bufaux.h22
-rw-r--r--buffer.c22
-rw-r--r--buffer.h16
-rw-r--r--canohost.c79
-rw-r--r--channels.c380
-rw-r--r--channels.h27
-rw-r--r--cipher.c43
-rw-r--r--cipher.h36
-rw-r--r--clientloop.c317
-rw-r--r--compat.c31
-rw-r--r--compat.h30
-rw-r--r--compress.c46
-rw-r--r--compress.h38
-rw-r--r--crc32.h8
-rw-r--r--fingerprint.c31
-rw-r--r--fingerprint.h30
-rw-r--r--hostfile.c119
-rw-r--r--includes.h6
-rw-r--r--log.c6
-rw-r--r--login.c29
-rw-r--r--match.c35
-rw-r--r--mpaux.h10
-rw-r--r--nchan.c34
-rw-r--r--nchan.h31
-rw-r--r--nchan.ms28
-rw-r--r--packet.c181
-rw-r--r--packet.h118
-rw-r--r--pty.c44
-rw-r--r--pty.h24
-rw-r--r--radix.c8
-rw-r--r--readconf.c92
-rw-r--r--readconf.h47
-rw-r--r--readpass.c24
-rw-r--r--rsa.c10
-rw-r--r--rsa.h8
-rw-r--r--scp.c20
-rw-r--r--servconf.c17
-rw-r--r--servconf.h14
-rw-r--r--serverloop.c114
-rw-r--r--ssh-add.19
-rw-r--r--ssh-add.c167
-rw-r--r--ssh-agent.c37
-rw-r--r--ssh-keygen.c55
-rw-r--r--ssh.14
-rw-r--r--ssh.c181
-rw-r--r--ssh.h518
-rw-r--r--sshconnect.c187
-rw-r--r--sshd.c499
-rw-r--r--tildexpand.c8
-rw-r--r--ttymodes.c3
-rw-r--r--ttymodes.h139
-rw-r--r--uidswap.c11
61 files changed, 2685 insertions, 1802 deletions
diff --git a/auth-passwd.c b/auth-passwd.c
index d3914fca3..e5574ffbe 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -11,7 +11,7 @@
11 11
12#ifndef HAVE_PAM 12#ifndef HAVE_PAM
13 13
14RCSID("$Id: auth-passwd.c,v 1.6 1999/11/24 13:26:21 damien Exp $"); 14RCSID("$Id: auth-passwd.c,v 1.7 1999/11/25 00:54:57 damien Exp $");
15 15
16#include "packet.h" 16#include "packet.h"
17#include "ssh.h" 17#include "ssh.h"
@@ -39,14 +39,10 @@ auth_password(struct passwd * pw, const char *password)
39 struct spwd *spw; 39 struct spwd *spw;
40#endif 40#endif
41 41
42 if (pw->pw_uid == 0 && options.permit_root_login == 2) { 42 if (pw->pw_uid == 0 && options.permit_root_login == 2)
43 /* Server does not permit root login with password */
44 return 0; 43 return 0;
45 } 44 if (*password == '\0' && options.permit_empty_passwd == 0)
46 if (*password == '\0' && options.permit_empty_passwd == 0) {
47 /* Server does not permit empty password login */
48 return 0; 45 return 0;
49 }
50 /* deny if no user. */ 46 /* deny if no user. */
51 if (pw == NULL) 47 if (pw == NULL)
52 return 0; 48 return 0;
@@ -74,8 +70,10 @@ auth_password(struct passwd * pw, const char *password)
74#endif 70#endif
75 71
76#if defined(KRB4) 72#if defined(KRB4)
77 /* Support for Kerberos v4 authentication - Dug Song 73 /*
78 <dugsong@UMICH.EDU> */ 74 * Support for Kerberos v4 authentication
75 * - Dug Song <dugsong@UMICH.EDU>
76 */
79 if (options.kerberos_authentication) { 77 if (options.kerberos_authentication) {
80 AUTH_DAT adata; 78 AUTH_DAT adata;
81 KTEXT_ST tkt; 79 KTEXT_ST tkt;
@@ -86,8 +84,10 @@ auth_password(struct passwd * pw, const char *password)
86 char realm[REALM_SZ]; 84 char realm[REALM_SZ];
87 int r; 85 int r;
88 86
89 /* Try Kerberos password authentication only for non-root 87 /*
90 users and only if Kerberos is installed. */ 88 * Try Kerberos password authentication only for non-root
89 * users and only if Kerberos is installed.
90 */
91 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { 91 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
92 92
93 /* Set up our ticket file. */ 93 /* Set up our ticket file. */
@@ -144,14 +144,17 @@ auth_password(struct passwd * pw, const char *password)
144 goto kerberos_auth_failure; 144 goto kerberos_auth_failure;
145 } 145 }
146 } else if (r == KDC_PR_UNKNOWN) { 146 } else if (r == KDC_PR_UNKNOWN) {
147 /* Allow login if no rcmd service exists, 147 /*
148 but log the error. */ 148 * Allow login if no rcmd service exists, but
149 * log the error.
150 */
149 log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s " 151 log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
150 "not registered, or srvtab is wrong?", pw->pw_name, 152 "not registered, or srvtab is wrong?", pw->pw_name,
151 krb_err_txt[r], KRB4_SERVICE_NAME, phost); 153 krb_err_txt[r], KRB4_SERVICE_NAME, phost);
152 } else { 154 } else {
153 /* TGT is bad, forget it. Possibly 155 /*
154 spoofed! */ 156 * TGT is bad, forget it. Possibly spoofed!
157 */
155 packet_send_debug("WARNING: Kerberos V4 TGT " 158 packet_send_debug("WARNING: Kerberos V4 TGT "
156 "possibly spoofed for %s: %s", 159 "possibly spoofed for %s: %s",
157 pw->pw_name, krb_err_txt[r]); 160 pw->pw_name, krb_err_txt[r]);
@@ -175,11 +178,8 @@ auth_password(struct passwd * pw, const char *password)
175#endif /* KRB4 */ 178#endif /* KRB4 */
176 179
177 /* Check for users with no password. */ 180 /* Check for users with no password. */
178 if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) { 181 if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
179 packet_send_debug("Login permitted without a password "
180 "because the account has no password.");
181 return 1; 182 return 1;
182 }
183 183
184#ifdef HAVE_SHADOW_H 184#ifdef HAVE_SHADOW_H
185 spw = getspnam(pw->pw_name); 185 spw = getspnam(pw->pw_name);
diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c
index 4e9a383a2..1392455cb 100644
--- a/auth-rh-rsa.c
+++ b/auth-rh-rsa.c
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: auth-rh-rsa.c,v 1.6 1999/11/24 13:26:21 damien Exp $"); 18RCSID("$Id: auth-rh-rsa.c,v 1.7 1999/11/25 00:54:57 damien Exp $");
19 19
20#include "packet.h" 20#include "packet.h"
21#include "ssh.h" 21#include "ssh.h"
@@ -23,8 +23,10 @@ RCSID("$Id: auth-rh-rsa.c,v 1.6 1999/11/24 13:26:21 damien Exp $");
23#include "uidswap.h" 23#include "uidswap.h"
24#include "servconf.h" 24#include "servconf.h"
25 25
26/* Tries to authenticate the user using the .rhosts file and the host using 26/*
27 its host key. Returns true if authentication succeeds. */ 27 * Tries to authenticate the user using the .rhosts file and the host using
28 * its host key. Returns true if authentication succeeds.
29 */
28 30
29int 31int
30auth_rhosts_rsa(struct passwd *pw, const char *client_user, 32auth_rhosts_rsa(struct passwd *pw, const char *client_user,
@@ -57,8 +59,10 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user,
57 if (host_status != HOST_OK && !options.ignore_user_known_hosts) { 59 if (host_status != HOST_OK && !options.ignore_user_known_hosts) {
58 struct stat st; 60 struct stat st;
59 char *user_hostfile = tilde_expand_filename(SSH_USER_HOSTFILE, pw->pw_uid); 61 char *user_hostfile = tilde_expand_filename(SSH_USER_HOSTFILE, pw->pw_uid);
60 /* Check file permissions of SSH_USER_HOSTFILE, auth_rsa() 62 /*
61 did already check pw->pw_dir, but there is a race XXX */ 63 * Check file permissions of SSH_USER_HOSTFILE, auth_rsa()
64 * did already check pw->pw_dir, but there is a race XXX
65 */
62 if (options.strict_modes && 66 if (options.strict_modes &&
63 (stat(user_hostfile, &st) == 0) && 67 (stat(user_hostfile, &st) == 0) &&
64 ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || 68 ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
@@ -91,8 +95,10 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user,
91 canonical_hostname); 95 canonical_hostname);
92 return 0; 96 return 0;
93 } 97 }
94 /* We have authenticated the user using .rhosts or /etc/hosts.equiv, and the host using RSA. 98 /*
95 We accept the authentication. */ 99 * We have authenticated the user using .rhosts or /etc/hosts.equiv,
100 * and the host using RSA. We accept the authentication.
101 */
96 102
97 verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.", 103 verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.",
98 pw->pw_name, client_user, canonical_hostname); 104 pw->pw_name, client_user, canonical_hostname);
diff --git a/auth-rhosts.c b/auth-rhosts.c
index 500dcebb1..2f12f1347 100644
--- a/auth-rhosts.c
+++ b/auth-rhosts.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: auth-rhosts.c,v 1.5 1999/11/24 13:26:21 damien Exp $"); 19RCSID("$Id: auth-rhosts.c,v 1.6 1999/11/25 00:54:57 damien Exp $");
20 20
21#include "packet.h" 21#include "packet.h"
22#include "ssh.h" 22#include "ssh.h"
@@ -24,9 +24,11 @@ RCSID("$Id: auth-rhosts.c,v 1.5 1999/11/24 13:26:21 damien Exp $");
24#include "uidswap.h" 24#include "uidswap.h"
25#include "servconf.h" 25#include "servconf.h"
26 26
27/* This function processes an rhosts-style file (.rhosts, .shosts, or 27/*
28 /etc/hosts.equiv). This returns true if authentication can be granted 28 * This function processes an rhosts-style file (.rhosts, .shosts, or
29 based on the file, and returns zero otherwise. */ 29 * /etc/hosts.equiv). This returns true if authentication can be granted
30 * based on the file, and returns zero otherwise.
31 */
30 32
31int 33int
32check_rhosts_file(const char *filename, const char *hostname, 34check_rhosts_file(const char *filename, const char *hostname,
@@ -41,7 +43,6 @@ check_rhosts_file(const char *filename, const char *hostname,
41 if (!f) 43 if (!f)
42 return 0; 44 return 0;
43 45
44 /* Go through the file, checking every entry. */
45 while (fgets(buf, sizeof(buf), f)) { 46 while (fgets(buf, sizeof(buf), f)) {
46 /* All three must be at least as big as buf to avoid overflows. */ 47 /* All three must be at least as big as buf to avoid overflows. */
47 char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; 48 char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp;
@@ -52,13 +53,17 @@ check_rhosts_file(const char *filename, const char *hostname,
52 if (*cp == '#' || *cp == '\n' || !*cp) 53 if (*cp == '#' || *cp == '\n' || !*cp)
53 continue; 54 continue;
54 55
55 /* NO_PLUS is supported at least on OSF/1. We skip it (we 56 /*
56 don't ever support the plus syntax). */ 57 * NO_PLUS is supported at least on OSF/1. We skip it (we
58 * don't ever support the plus syntax).
59 */
57 if (strncmp(cp, "NO_PLUS", 7) == 0) 60 if (strncmp(cp, "NO_PLUS", 7) == 0)
58 continue; 61 continue;
59 62
60 /* This should be safe because each buffer is as big as 63 /*
61 the whole string, and thus cannot be overwritten. */ 64 * This should be safe because each buffer is as big as the
65 * whole string, and thus cannot be overwritten.
66 */
62 switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy)) { 67 switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy)) {
63 case 0: 68 case 0:
64 packet_send_debug("Found empty line in %.100s.", filename); 69 packet_send_debug("Found empty line in %.100s.", filename);
@@ -135,10 +140,11 @@ check_rhosts_file(const char *filename, const char *hostname,
135 return 0; 140 return 0;
136} 141}
137 142
138/* Tries to authenticate the user using the .shosts or .rhosts file. 143/*
139 Returns true if authentication succeeds. If ignore_rhosts is 144 * Tries to authenticate the user using the .shosts or .rhosts file. Returns
140 true, only /etc/hosts.equiv will be considered (.rhosts and .shosts 145 * true if authentication succeeds. If ignore_rhosts is true, only
141 are ignored). */ 146 * /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored).
147 */
142 148
143int 149int
144auth_rhosts(struct passwd *pw, const char *client_user) 150auth_rhosts(struct passwd *pw, const char *client_user)
@@ -150,11 +156,13 @@ auth_rhosts(struct passwd *pw, const char *client_user)
150 static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; 156 static const char *rhosts_files[] = {".shosts", ".rhosts", NULL};
151 unsigned int rhosts_file_index; 157 unsigned int rhosts_file_index;
152 158
153 /* Quick check: if the user has no .shosts or .rhosts files,
154 return failure immediately without doing costly lookups from
155 name servers. */
156 /* Switch to the user's uid. */ 159 /* Switch to the user's uid. */
157 temporarily_use_uid(pw->pw_uid); 160 temporarily_use_uid(pw->pw_uid);
161 /*
162 * Quick check: if the user has no .shosts or .rhosts files, return
163 * failure immediately without doing costly lookups from name
164 * servers.
165 */
158 for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; 166 for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
159 rhosts_file_index++) { 167 rhosts_file_index++) {
160 /* Check users .rhosts or .shosts. */ 168 /* Check users .rhosts or .shosts. */
@@ -172,7 +180,6 @@ auth_rhosts(struct passwd *pw, const char *client_user)
172 stat(SSH_HOSTS_EQUIV, &st) < 0) 180 stat(SSH_HOSTS_EQUIV, &st) < 0)
173 return 0; 181 return 0;
174 182
175 /* Get the name, address, and port of the remote host. */
176 hostname = get_canonical_hostname(); 183 hostname = get_canonical_hostname();
177 ipaddr = get_remote_ipaddr(); 184 ipaddr = get_remote_ipaddr();
178 185
@@ -191,8 +198,10 @@ auth_rhosts(struct passwd *pw, const char *client_user)
191 return 1; 198 return 1;
192 } 199 }
193 } 200 }
194 /* Check that the home directory is owned by root or the user, and 201 /*
195 is not group or world writable. */ 202 * Check that the home directory is owned by root or the user, and is
203 * not group or world writable.
204 */
196 if (stat(pw->pw_dir, &st) < 0) { 205 if (stat(pw->pw_dir, &st) < 0) {
197 log("Rhosts authentication refused for %.100s: no home directory %.200s", 206 log("Rhosts authentication refused for %.100s: no home directory %.200s",
198 pw->pw_name, pw->pw_dir); 207 pw->pw_name, pw->pw_dir);
@@ -221,10 +230,12 @@ auth_rhosts(struct passwd *pw, const char *client_user)
221 if (stat(buf, &st) < 0) 230 if (stat(buf, &st) < 0)
222 continue; 231 continue;
223 232
224 /* Make sure that the file is either owned by the user or 233 /*
225 by root, and make sure it is not writable by anyone but 234 * Make sure that the file is either owned by the user or by
226 the owner. This is to help avoid novices accidentally 235 * root, and make sure it is not writable by anyone but the
227 allowing access to their account by anyone. */ 236 * owner. This is to help avoid novices accidentally
237 * allowing access to their account by anyone.
238 */
228 if (options.strict_modes && 239 if (options.strict_modes &&
229 ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || 240 ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
230 (st.st_mode & 022) != 0)) { 241 (st.st_mode & 022) != 0)) {
diff --git a/auth-rsa.c b/auth-rsa.c
index 88841482b..88dc2e76c 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: auth-rsa.c,v 1.9 1999/11/24 13:26:21 damien Exp $"); 19RCSID("$Id: auth-rsa.c,v 1.10 1999/11/25 00:54:57 damien Exp $");
20 20
21#include "rsa.h" 21#include "rsa.h"
22#include "packet.h" 22#include "packet.h"
@@ -43,22 +43,27 @@ extern int no_pty_flag;
43extern char *forced_command; 43extern char *forced_command;
44extern struct envstring *custom_environment; 44extern struct envstring *custom_environment;
45 45
46/* Session identifier that is used to bind key exchange and authentication 46/*
47 responses to a particular session. */ 47 * Session identifier that is used to bind key exchange and authentication
48 * responses to a particular session.
49 */
48extern unsigned char session_id[16]; 50extern unsigned char session_id[16];
49 51
50/* The .ssh/authorized_keys file contains public keys, one per line, in the 52/*
51 following format: 53 * The .ssh/authorized_keys file contains public keys, one per line, in the
52 options bits e n comment 54 * following format:
53 where bits, e and n are decimal numbers, 55 * options bits e n comment
54 and comment is any string of characters up to newline. The maximum 56 * where bits, e and n are decimal numbers,
55 length of a line is 8000 characters. See the documentation for a 57 * and comment is any string of characters up to newline. The maximum
56 description of the options. 58 * length of a line is 8000 characters. See the documentation for a
57*/ 59 * description of the options.
60 */
58 61
59/* Performs the RSA authentication challenge-response dialog with the client, 62/*
60 and returns true (non-zero) if the client gave the correct answer to 63 * Performs the RSA authentication challenge-response dialog with the client,
61 our challenge; returns zero if the client gives a wrong answer. */ 64 * and returns true (non-zero) if the client gave the correct answer to
65 * our challenge; returns zero if the client gives a wrong answer.
66 */
62 67
63int 68int
64auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n) 69auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n)
@@ -128,9 +133,11 @@ auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n)
128 return 1; 133 return 1;
129} 134}
130 135
131/* Performs the RSA authentication dialog with the client. This returns 136/*
132 0 if the client could not be authenticated, and 1 if authentication was 137 * Performs the RSA authentication dialog with the client. This returns
133 successful. This may exit if there is a serious protocol violation. */ 138 * 0 if the client could not be authenticated, and 1 if authentication was
139 * successful. This may exit if there is a serious protocol violation.
140 */
134 141
135int 142int
136auth_rsa(struct passwd *pw, BIGNUM *client_n) 143auth_rsa(struct passwd *pw, BIGNUM *client_n)
@@ -204,30 +211,32 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
204 /* Flag indicating whether authentication has succeeded. */ 211 /* Flag indicating whether authentication has succeeded. */
205 authenticated = 0; 212 authenticated = 0;
206 213
207 /* Initialize mp-int variables. */
208 e = BN_new(); 214 e = BN_new();
209 n = BN_new(); 215 n = BN_new();
210 216
211 /* Go though the accepted keys, looking for the current key. If 217 /*
212 found, perform a challenge-response dialog to verify that the 218 * Go though the accepted keys, looking for the current key. If
213 user really has the corresponding private key. */ 219 * found, perform a challenge-response dialog to verify that the
220 * user really has the corresponding private key.
221 */
214 while (fgets(line, sizeof(line), f)) { 222 while (fgets(line, sizeof(line), f)) {
215 char *cp; 223 char *cp;
216 char *options; 224 char *options;
217 225
218 linenum++; 226 linenum++;
219 227
220 /* Skip leading whitespace. */ 228 /* Skip leading whitespace, empty and comment lines. */
221 for (cp = line; *cp == ' ' || *cp == '\t'; cp++); 229 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
222 230 ;
223 /* Skip empty and comment lines. */
224 if (!*cp || *cp == '\n' || *cp == '#') 231 if (!*cp || *cp == '\n' || *cp == '#')
225 continue; 232 continue;
226 233
227 /* Check if there are options for this key, and if so, 234 /*
228 save their starting address and skip the option part 235 * Check if there are options for this key, and if so,
229 for now. If there are no options, set the starting 236 * save their starting address and skip the option part
230 address to NULL. */ 237 * for now. If there are no options, set the starting
238 * address to NULL.
239 */
231 if (*cp < '0' || *cp > '9') { 240 if (*cp < '0' || *cp > '9') {
232 int quoted = 0; 241 int quoted = 0;
233 options = cp; 242 options = cp;
@@ -258,7 +267,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
258 267
259 /* Check if the we have found the desired key (identified by its modulus). */ 268 /* Check if the we have found the desired key (identified by its modulus). */
260 if (BN_cmp(n, client_n) != 0) 269 if (BN_cmp(n, client_n) != 0)
261 continue; /* Wrong key. */ 270 continue;
262 271
263 /* We have found the desired key. */ 272 /* We have found the desired key. */
264 273
@@ -269,10 +278,12 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
269 packet_send_debug("Wrong response to RSA authentication challenge."); 278 packet_send_debug("Wrong response to RSA authentication challenge.");
270 continue; 279 continue;
271 } 280 }
272 /* Correct response. The client has been successfully 281 /*
273 authenticated. Note that we have not yet processed the 282 * Correct response. The client has been successfully
274 options; this will be reset if the options cause the 283 * authenticated. Note that we have not yet processed the
275 authentication to be rejected. */ 284 * options; this will be reset if the options cause the
285 * authentication to be rejected.
286 */
276 authenticated = 1; 287 authenticated = 1;
277 288
278 /* RSA part of authentication was accepted. Now process the options. */ 289 /* RSA part of authentication was accepted. Now process the options. */
@@ -412,7 +423,6 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
412 goto next_option; 423 goto next_option;
413 } 424 }
414 bad_option: 425 bad_option:
415 /* Unknown option. */
416 log("Bad options in %.100s file, line %lu: %.50s", 426 log("Bad options in %.100s file, line %lu: %.50s",
417 SSH_USER_PERMITTED_KEYS, linenum, options); 427 SSH_USER_PERMITTED_KEYS, linenum, options);
418 packet_send_debug("Bad options in %.100s file, line %lu: %.50s", 428 packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
@@ -421,12 +431,14 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
421 break; 431 break;
422 432
423 next_option: 433 next_option:
424 /* Skip the comma, and move to the next option 434 /*
425 (or break out if there are no more). */ 435 * Skip the comma, and move to the next option
436 * (or break out if there are no more).
437 */
426 if (!*options) 438 if (!*options)
427 fatal("Bugs in auth-rsa.c option processing."); 439 fatal("Bugs in auth-rsa.c option processing.");
428 if (*options == ' ' || *options == '\t') 440 if (*options == ' ' || *options == '\t')
429 break; /* End of options. */ 441 break; /* End of options. */
430 if (*options != ',') 442 if (*options != ',')
431 goto bad_option; 443 goto bad_option;
432 options++; 444 options++;
@@ -434,8 +446,10 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
434 continue; 446 continue;
435 } 447 }
436 } 448 }
437 /* Break out of the loop if authentication was successful; 449 /*
438 otherwise continue searching. */ 450 * Break out of the loop if authentication was successful;
451 * otherwise continue searching.
452 */
439 if (authenticated) 453 if (authenticated)
440 break; 454 break;
441 } 455 }
@@ -446,7 +460,6 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
446 /* Close the file. */ 460 /* Close the file. */
447 fclose(f); 461 fclose(f);
448 462
449 /* Clear any mp-int variables. */
450 BN_clear_free(n); 463 BN_clear_free(n);
451 BN_clear_free(e); 464 BN_clear_free(e);
452 465
diff --git a/auth-skey.c b/auth-skey.c
index 457100ccc..a0d786cb2 100644
--- a/auth-skey.c
+++ b/auth-skey.c
@@ -1,11 +1,15 @@
1#include "includes.h" 1#include "includes.h"
2 2
3#ifdef SKEY 3#ifdef SKEY
4
5RCSID("$Id: auth-skey.c,v 1.3 1999/11/23 22:25:52 markus Exp $"); 4RCSID("$Id: auth-skey.c,v 1.3 1999/11/23 22:25:52 markus Exp $");
6 5
7#include "ssh.h" 6#include "ssh.h"
8#include <sha1.h> 7#ifdef HAVE_OPENSSL
8#include <openssl/sha1.h>
9#endif
10#ifdef HAVE_SSL
11#include <ssl/sha1.h>
12#endif
9 13
10/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ 14/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
11 15
diff --git a/authfd.c b/authfd.c
index 17b0668be..ee6473d32 100644
--- a/authfd.c
+++ b/authfd.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: authfd.c,v 1.7 1999/11/24 13:26:21 damien Exp $"); 17RCSID("$Id: authfd.c,v 1.8 1999/11/25 00:54:57 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "rsa.h" 20#include "rsa.h"
@@ -63,9 +63,11 @@ ssh_get_authentication_socket()
63 return sock; 63 return sock;
64} 64}
65 65
66/* Closes the agent socket if it should be closed (depends on how it was 66/*
67 obtained). The argument must have been returned by 67 * Closes the agent socket if it should be closed (depends on how it was
68 ssh_get_authentication_socket(). */ 68 * obtained). The argument must have been returned by
69 * ssh_get_authentication_socket().
70 */
69 71
70void 72void
71ssh_close_authentication_socket(int sock) 73ssh_close_authentication_socket(int sock)
@@ -74,11 +76,13 @@ ssh_close_authentication_socket(int sock)
74 close(sock); 76 close(sock);
75} 77}
76 78
77/* Opens and connects a private socket for communication with the 79/*
78 authentication agent. Returns the file descriptor (which must be 80 * Opens and connects a private socket for communication with the
79 shut down and closed by the caller when no longer needed). 81 * authentication agent. Returns the file descriptor (which must be
80 Returns NULL if an error occurred and the connection could not be 82 * shut down and closed by the caller when no longer needed).
81 opened. */ 83 * Returns NULL if an error occurred and the connection could not be
84 * opened.
85 */
82 86
83AuthenticationConnection * 87AuthenticationConnection *
84ssh_get_authentication_connection() 88ssh_get_authentication_connection()
@@ -88,12 +92,13 @@ ssh_get_authentication_connection()
88 92
89 sock = ssh_get_authentication_socket(); 93 sock = ssh_get_authentication_socket();
90 94
91 /* Fail if we couldn't obtain a connection. This happens if we 95 /*
92 exited due to a timeout. */ 96 * Fail if we couldn't obtain a connection. This happens if we
97 * exited due to a timeout.
98 */
93 if (sock < 0) 99 if (sock < 0)
94 return NULL; 100 return NULL;
95 101
96 /* Applocate the connection structure and initialize it. */
97 auth = xmalloc(sizeof(*auth)); 102 auth = xmalloc(sizeof(*auth));
98 auth->fd = sock; 103 auth->fd = sock;
99 buffer_init(&auth->packet); 104 buffer_init(&auth->packet);
@@ -103,8 +108,10 @@ ssh_get_authentication_connection()
103 return auth; 108 return auth;
104} 109}
105 110
106/* Closes the connection to the authentication agent and frees any associated 111/*
107 memory. */ 112 * Closes the connection to the authentication agent and frees any associated
113 * memory.
114 */
108 115
109void 116void
110ssh_close_authentication_connection(AuthenticationConnection *ac) 117ssh_close_authentication_connection(AuthenticationConnection *ac)
@@ -115,10 +122,12 @@ ssh_close_authentication_connection(AuthenticationConnection *ac)
115 xfree(ac); 122 xfree(ac);
116} 123}
117 124
118/* Returns the first authentication identity held by the agent. 125/*
119 Returns true if an identity is available, 0 otherwise. 126 * Returns the first authentication identity held by the agent.
120 The caller must initialize the integers before the call, and free the 127 * Returns true if an identity is available, 0 otherwise.
121 comment after a successful call (before calling ssh_get_next_identity). */ 128 * The caller must initialize the integers before the call, and free the
129 * comment after a successful call (before calling ssh_get_next_identity).
130 */
122 131
123int 132int
124ssh_get_first_identity(AuthenticationConnection *auth, 133ssh_get_first_identity(AuthenticationConnection *auth,
@@ -127,8 +136,10 @@ ssh_get_first_identity(AuthenticationConnection *auth,
127 unsigned char msg[8192]; 136 unsigned char msg[8192];
128 int len, l; 137 int len, l;
129 138
130 /* Send a message to the agent requesting for a list of the 139 /*
131 identities it can represent. */ 140 * Send a message to the agent requesting for a list of the
141 * identities it can represent.
142 */
132 msg[0] = 0; 143 msg[0] = 0;
133 msg[1] = 0; 144 msg[1] = 0;
134 msg[2] = 0; 145 msg[2] = 0;
@@ -149,8 +160,10 @@ ssh_get_first_identity(AuthenticationConnection *auth,
149 len -= l; 160 len -= l;
150 } 161 }
151 162
152 /* Extract the length, and check it for sanity. (We cannot trust 163 /*
153 authentication agents). */ 164 * Extract the length, and check it for sanity. (We cannot trust
165 * authentication agents).
166 */
154 len = GET_32BIT(msg); 167 len = GET_32BIT(msg);
155 if (len < 1 || len > 256 * 1024) 168 if (len < 1 || len > 256 * 1024)
156 fatal("Authentication reply message too long: %d\n", len); 169 fatal("Authentication reply message too long: %d\n", len);
@@ -182,10 +195,12 @@ ssh_get_first_identity(AuthenticationConnection *auth,
182 return ssh_get_next_identity(auth, e, n, comment); 195 return ssh_get_next_identity(auth, e, n, comment);
183} 196}
184 197
185/* Returns the next authentication identity for the agent. Other functions 198/*
186 can be called between this and ssh_get_first_identity or two calls of this 199 * Returns the next authentication identity for the agent. Other functions
187 function. This returns 0 if there are no more identities. The caller 200 * can be called between this and ssh_get_first_identity or two calls of this
188 must free comment after a successful return. */ 201 * function. This returns 0 if there are no more identities. The caller
202 * must free comment after a successful return.
203 */
189 204
190int 205int
191ssh_get_next_identity(AuthenticationConnection *auth, 206ssh_get_next_identity(AuthenticationConnection *auth,
@@ -197,8 +212,10 @@ ssh_get_next_identity(AuthenticationConnection *auth,
197 if (auth->howmany <= 0) 212 if (auth->howmany <= 0)
198 return 0; 213 return 0;
199 214
200 /* Get the next entry from the packet. These will abort with a 215 /*
201 fatal error if the packet is too short or contains corrupt data. */ 216 * Get the next entry from the packet. These will abort with a fatal
217 * error if the packet is too short or contains corrupt data.
218 */
202 bits = buffer_get_int(&auth->identities); 219 bits = buffer_get_int(&auth->identities);
203 buffer_get_bignum(&auth->identities, e); 220 buffer_get_bignum(&auth->identities, e);
204 buffer_get_bignum(&auth->identities, n); 221 buffer_get_bignum(&auth->identities, n);
@@ -214,11 +231,13 @@ ssh_get_next_identity(AuthenticationConnection *auth,
214 return 1; 231 return 1;
215} 232}
216 233
217/* Generates a random challenge, sends it to the agent, and waits for response 234/*
218 from the agent. Returns true (non-zero) if the agent gave the correct 235 * Generates a random challenge, sends it to the agent, and waits for
219 answer, zero otherwise. Response type selects the style of response 236 * response from the agent. Returns true (non-zero) if the agent gave the
220 desired, with 0 corresponding to protocol version 1.0 (no longer supported) 237 * correct answer, zero otherwise. Response type selects the style of
221 and 1 corresponding to protocol version 1.1. */ 238 * response desired, with 0 corresponding to protocol version 1.0 (no longer
239 * supported) and 1 corresponding to protocol version 1.1.
240 */
222 241
223int 242int
224ssh_decrypt_challenge(AuthenticationConnection *auth, 243ssh_decrypt_challenge(AuthenticationConnection *auth,
@@ -259,8 +278,10 @@ error_cleanup:
259 buffer_free(&buffer); 278 buffer_free(&buffer);
260 return 0; 279 return 0;
261 } 280 }
262 /* Wait for response from the agent. First read the length of the 281 /*
263 response packet. */ 282 * Wait for response from the agent. First read the length of the
283 * response packet.
284 */
264 len = 4; 285 len = 4;
265 while (len > 0) { 286 while (len > 0) {
266 l = read(auth->fd, buf + 4 - len, len); 287 l = read(auth->fd, buf + 4 - len, len);
@@ -303,8 +324,10 @@ error_cleanup:
303 if (buf[0] != SSH_AGENT_RSA_RESPONSE) 324 if (buf[0] != SSH_AGENT_RSA_RESPONSE)
304 fatal("Bad authentication response: %d", buf[0]); 325 fatal("Bad authentication response: %d", buf[0]);
305 326
306 /* Get the response from the packet. This will abort with a fatal 327 /*
307 error if the packet is corrupt. */ 328 * Get the response from the packet. This will abort with a fatal
329 * error if the packet is corrupt.
330 */
308 for (i = 0; i < 16; i++) 331 for (i = 0; i < 16; i++)
309 response[i] = buffer_get_char(&buffer); 332 response[i] = buffer_get_char(&buffer);
310 333
@@ -315,8 +338,10 @@ error_cleanup:
315 return 1; 338 return 1;
316} 339}
317 340
318/* Adds an identity to the authentication server. This call is not meant to 341/*
319 be used by normal applications. */ 342 * Adds an identity to the authentication server. This call is not meant to
343 * be used by normal applications.
344 */
320 345
321int 346int
322ssh_add_identity(AuthenticationConnection *auth, 347ssh_add_identity(AuthenticationConnection *auth,
@@ -401,8 +426,10 @@ error_cleanup:
401 return 0; 426 return 0;
402} 427}
403 428
404/* Removes an identity from the authentication server. This call is not meant 429/*
405 to be used by normal applications. */ 430 * Removes an identity from the authentication server. This call is not
431 * meant to be used by normal applications.
432 */
406 433
407int 434int
408ssh_remove_identity(AuthenticationConnection *auth, RSA *key) 435ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
@@ -431,8 +458,10 @@ error_cleanup:
431 buffer_free(&buffer); 458 buffer_free(&buffer);
432 return 0; 459 return 0;
433 } 460 }
434 /* Wait for response from the agent. First read the length of the 461 /*
435 response packet. */ 462 * Wait for response from the agent. First read the length of the
463 * response packet.
464 */
436 len = 4; 465 len = 4;
437 while (len > 0) { 466 while (len > 0) {
438 l = read(auth->fd, buf + 4 - len, len); 467 l = read(auth->fd, buf + 4 - len, len);
@@ -480,8 +509,10 @@ error_cleanup:
480 return 0; 509 return 0;
481} 510}
482 511
483/* Removes all identities from the agent. This call is not meant 512/*
484 to be used by normal applications. */ 513 * Removes all identities from the agent. This call is not meant to be used
514 * by normal applications.
515 */
485 516
486int 517int
487ssh_remove_all_identities(AuthenticationConnection *auth) 518ssh_remove_all_identities(AuthenticationConnection *auth)
@@ -499,8 +530,10 @@ ssh_remove_all_identities(AuthenticationConnection *auth)
499 error("Error writing to authentication socket."); 530 error("Error writing to authentication socket.");
500 return 0; 531 return 0;
501 } 532 }
502 /* Wait for response from the agent. First read the length of the 533 /*
503 response packet. */ 534 * Wait for response from the agent. First read the length of the
535 * response packet.
536 */
504 len = 4; 537 len = 4;
505 while (len > 0) { 538 while (len > 0) {
506 l = read(auth->fd, buf + 4 - len, len); 539 l = read(auth->fd, buf + 4 - len, len);
diff --git a/authfd.h b/authfd.h
index bddb8bab8..01cfd93a5 100644
--- a/authfd.h
+++ b/authfd.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: authfd.h,v 1.3 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: authfd.h,v 1.4 1999/11/25 00:54:58 damien Exp $"); */
17 17
18#ifndef AUTHFD_H 18#ifndef AUTHFD_H
19#define AUTHFD_H 19#define AUTHFD_H
@@ -40,33 +40,43 @@ typedef struct {
40/* Returns the number of the authentication fd, or -1 if there is none. */ 40/* Returns the number of the authentication fd, or -1 if there is none. */
41int ssh_get_authentication_socket(); 41int ssh_get_authentication_socket();
42 42
43/* This should be called for any descriptor returned by 43/*
44 ssh_get_authentication_socket(). Depending on the way the descriptor was 44 * This should be called for any descriptor returned by
45 obtained, this may close the descriptor. */ 45 * ssh_get_authentication_socket(). Depending on the way the descriptor was
46 * obtained, this may close the descriptor.
47 */
46void ssh_close_authentication_socket(int authfd); 48void ssh_close_authentication_socket(int authfd);
47 49
48/* Opens and connects a private socket for communication with the 50/*
49 authentication agent. Returns NULL if an error occurred and the 51 * Opens and connects a private socket for communication with the
50 connection could not be opened. The connection should be closed by 52 * authentication agent. Returns NULL if an error occurred and the
51 the caller by calling ssh_close_authentication_connection(). */ 53 * connection could not be opened. The connection should be closed by the
54 * caller by calling ssh_close_authentication_connection().
55 */
52AuthenticationConnection *ssh_get_authentication_connection(); 56AuthenticationConnection *ssh_get_authentication_connection();
53 57
54/* Closes the connection to the authentication agent and frees any associated 58/*
55 memory. */ 59 * Closes the connection to the authentication agent and frees any associated
60 * memory.
61 */
56void ssh_close_authentication_connection(AuthenticationConnection * ac); 62void ssh_close_authentication_connection(AuthenticationConnection * ac);
57 63
58/* Returns the first authentication identity held by the agent. 64/*
59 Returns true if an identity is available, 0 otherwise. 65 * Returns the first authentication identity held by the agent. Returns true
60 The caller must initialize the integers before the call, and free the 66 * if an identity is available, 0 otherwise. The caller must initialize the
61 comment after a successful call (before calling ssh_get_next_identity). */ 67 * integers before the call, and free the comment after a successful call
68 * (before calling ssh_get_next_identity).
69 */
62int 70int
63ssh_get_first_identity(AuthenticationConnection * connection, 71ssh_get_first_identity(AuthenticationConnection * connection,
64 BIGNUM * e, BIGNUM * n, char **comment); 72 BIGNUM * e, BIGNUM * n, char **comment);
65 73
66/* Returns the next authentication identity for the agent. Other functions 74/*
67 can be called between this and ssh_get_first_identity or two calls of this 75 * Returns the next authentication identity for the agent. Other functions
68 function. This returns 0 if there are no more identities. The caller 76 * can be called between this and ssh_get_first_identity or two calls of this
69 must free comment after a successful return. */ 77 * function. This returns 0 if there are no more identities. The caller
78 * must free comment after a successful return.
79 */
70int 80int
71ssh_get_next_identity(AuthenticationConnection * connection, 81ssh_get_next_identity(AuthenticationConnection * connection,
72 BIGNUM * e, BIGNUM * n, char **comment); 82 BIGNUM * e, BIGNUM * n, char **comment);
@@ -80,24 +90,30 @@ ssh_decrypt_challenge(AuthenticationConnection * auth,
80 unsigned int response_type, 90 unsigned int response_type,
81 unsigned char response[16]); 91 unsigned char response[16]);
82 92
83/* Adds an identity to the authentication server. This call is not meant to 93/*
84 be used by normal applications. This returns true if the identity 94 * Adds an identity to the authentication server. This call is not meant to
85 was successfully added. */ 95 * be used by normal applications. This returns true if the identity was
86 int ssh_add_identity(AuthenticationConnection * connection, 96 * successfully added.
87 RSA * key, const char *comment); 97 */
98int
99ssh_add_identity(AuthenticationConnection * connection, RSA * key,
100 const char *comment);
88 101
89/* Removes the identity from the authentication server. This call is 102/*
90 not meant to be used by normal applications. This returns true if the 103 * Removes the identity from the authentication server. This call is not
91 identity was successfully added. */ 104 * meant to be used by normal applications. This returns true if the
92 int ssh_remove_identity(AuthenticationConnection * connection, 105 * identity was successfully added.
93 RSA * key); 106 */
107int ssh_remove_identity(AuthenticationConnection * connection, RSA * key);
94 108
95/* Removes all identities from the authentication agent. This call is not 109/*
96 meant to be used by normal applications. This returns true if the 110 * Removes all identities from the authentication agent. This call is not
97 operation was successful. */ 111 * meant to be used by normal applications. This returns true if the
98 int ssh_remove_all_identities(AuthenticationConnection * connection); 112 * operation was successful.
113 */
114int ssh_remove_all_identities(AuthenticationConnection * connection);
99 115
100/* Closes the connection to the authentication agent. */ 116/* Closes the connection to the authentication agent. */
101 void ssh_close_authentication(AuthenticationConnection * connection); 117void ssh_close_authentication(AuthenticationConnection * connection);
102 118
103#endif /* AUTHFD_H */ 119#endif /* AUTHFD_H */
diff --git a/authfile.c b/authfile.c
index 35a05d389..97d0a8783 100644
--- a/authfile.c
+++ b/authfile.c
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: authfile.c,v 1.4 1999/11/24 13:26:22 damien Exp $"); 18RCSID("$Id: authfile.c,v 1.5 1999/11/25 00:54:58 damien Exp $");
19 19
20#ifdef HAVE_OPENSSL 20#ifdef HAVE_OPENSSL
21#include <openssl/bn.h> 21#include <openssl/bn.h>
@@ -33,10 +33,12 @@ RCSID("$Id: authfile.c,v 1.4 1999/11/24 13:26:22 damien Exp $");
33/* Version identification string for identity files. */ 33/* Version identification string for identity files. */
34#define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n" 34#define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n"
35 35
36/* Saves the authentication (private) key in a file, encrypting it with 36/*
37 passphrase. The identification of the file (lowest 64 bits of n) 37 * Saves the authentication (private) key in a file, encrypting it with
38 will precede the key to provide identification of the key without 38 * passphrase. The identification of the file (lowest 64 bits of n) will
39 needing a passphrase. */ 39 * precede the key to provide identification of the key without needing a
40 * passphrase.
41 */
40 42
41int 43int
42save_private_key(const char *filename, const char *passphrase, 44save_private_key(const char *filename, const char *passphrase,
@@ -49,9 +51,10 @@ save_private_key(const char *filename, const char *passphrase,
49 int cipher_type; 51 int cipher_type;
50 u_int32_t rand; 52 u_int32_t rand;
51 53
52 /* If the passphrase is empty, use SSH_CIPHER_NONE to ease 54 /*
53 converting to another cipher; otherwise use 55 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
54 SSH_AUTHFILE_CIPHER. */ 56 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
57 */
55 if (strcmp(passphrase, "") == 0) 58 if (strcmp(passphrase, "") == 0)
56 cipher_type = SSH_CIPHER_NONE; 59 cipher_type = SSH_CIPHER_NONE;
57 else 60 else
@@ -68,9 +71,11 @@ save_private_key(const char *filename, const char *passphrase,
68 buf[3] = buf[1]; 71 buf[3] = buf[1];
69 buffer_append(&buffer, buf, 4); 72 buffer_append(&buffer, buf, 4);
70 73
71 /* Store the private key (n and e will not be stored because they 74 /*
72 will be stored in plain text, and storing them also in 75 * Store the private key (n and e will not be stored because they
73 encrypted format would just give known plaintext). */ 76 * will be stored in plain text, and storing them also in encrypted
77 * format would just give known plaintext).
78 */
74 buffer_put_bignum(&buffer, key->d); 79 buffer_put_bignum(&buffer, key->d);
75 buffer_put_bignum(&buffer, key->iqmp); 80 buffer_put_bignum(&buffer, key->iqmp);
76 buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */ 81 buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */
@@ -112,11 +117,9 @@ save_private_key(const char *filename, const char *passphrase,
112 memset(buf, 0, sizeof(buf)); 117 memset(buf, 0, sizeof(buf));
113 buffer_free(&buffer); 118 buffer_free(&buffer);
114 119
115 /* Write to a file. */
116 f = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 120 f = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
117 if (f < 0) 121 if (f < 0)
118 return 0; 122 return 0;
119
120 if (write(f, buffer_ptr(&encrypted), buffer_len(&encrypted)) != 123 if (write(f, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
121 buffer_len(&encrypted)) { 124 buffer_len(&encrypted)) {
122 debug("Write to key file %.200s failed: %.100s", filename, 125 debug("Write to key file %.200s failed: %.100s", filename,
@@ -131,9 +134,11 @@ save_private_key(const char *filename, const char *passphrase,
131 return 1; 134 return 1;
132} 135}
133 136
134/* Loads the public part of the key file. Returns 0 if an error 137/*
135 was encountered (the file does not exist or is not readable), and 138 * Loads the public part of the key file. Returns 0 if an error was
136 non-zero otherwise. */ 139 * encountered (the file does not exist or is not readable), and non-zero
140 * otherwise.
141 */
137 142
138int 143int
139load_public_key(const char *filename, RSA * pub, 144load_public_key(const char *filename, RSA * pub,
@@ -144,11 +149,9 @@ load_public_key(const char *filename, RSA * pub,
144 Buffer buffer; 149 Buffer buffer;
145 char *cp; 150 char *cp;
146 151
147 /* Read data from the file into the buffer. */
148 f = open(filename, O_RDONLY); 152 f = open(filename, O_RDONLY);
149 if (f < 0) 153 if (f < 0)
150 return 0; 154 return 0;
151
152 len = lseek(f, (off_t) 0, SEEK_END); 155 len = lseek(f, (off_t) 0, SEEK_END);
153 lseek(f, (off_t) 0, SEEK_SET); 156 lseek(f, (off_t) 0, SEEK_SET);
154 157
@@ -170,8 +173,10 @@ load_public_key(const char *filename, RSA * pub,
170 buffer_free(&buffer); 173 buffer_free(&buffer);
171 return 0; 174 return 0;
172 } 175 }
173 /* Make sure it begins with the id string. Consume the id string 176 /*
174 from the buffer. */ 177 * Make sure it begins with the id string. Consume the id string
178 * from the buffer.
179 */
175 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) 180 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
176 if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { 181 if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) {
177 debug("Bad key file %.200s.", filename); 182 debug("Bad key file %.200s.", filename);
@@ -197,9 +202,12 @@ load_public_key(const char *filename, RSA * pub,
197 return 1; 202 return 1;
198} 203}
199 204
200/* Loads the private key from the file. Returns 0 if an error is encountered 205/*
201 (file does not exist or is not readable, or passphrase is bad). 206 * Loads the private key from the file. Returns 0 if an error is encountered
202 This initializes the private key. */ 207 * (file does not exist or is not readable, or passphrase is bad). This
208 * initializes the private key.
209 * Assumes we are called under uid of the owner of the file.
210 */
203 211
204int 212int
205load_private_key(const char *filename, const char *passphrase, 213load_private_key(const char *filename, const char *passphrase,
@@ -214,12 +222,11 @@ load_private_key(const char *filename, const char *passphrase,
214 BIGNUM *aux; 222 BIGNUM *aux;
215 struct stat st; 223 struct stat st;
216 224
217 /* Read the file into the buffer. */
218 f = open(filename, O_RDONLY); 225 f = open(filename, O_RDONLY);
219 if (f < 0) 226 if (f < 0)
220 return 0; 227 return 0;
221 228
222 /* We assume we are called under uid of the owner of the file */ 229 /* check owner and modes */
223 if (fstat(f, &st) < 0 || 230 if (fstat(f, &st) < 0 ||
224 (st.st_uid != 0 && st.st_uid != getuid()) || 231 (st.st_uid != 0 && st.st_uid != getuid()) ||
225 (st.st_mode & 077) != 0) { 232 (st.st_mode & 077) != 0) {
@@ -252,8 +259,10 @@ load_private_key(const char *filename, const char *passphrase,
252 buffer_free(&buffer); 259 buffer_free(&buffer);
253 return 0; 260 return 0;
254 } 261 }
255 /* Make sure it begins with the id string. Consume the id string 262 /*
256 from the buffer. */ 263 * Make sure it begins with the id string. Consume the id string
264 * from the buffer.
265 */
257 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) 266 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
258 if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { 267 if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) {
259 debug("Bad key file %.200s.", filename); 268 debug("Bad key file %.200s.", filename);
diff --git a/bufaux.c b/bufaux.c
index d953a2ad2..34a89d47a 100644
--- a/bufaux.c
+++ b/bufaux.c
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: bufaux.c,v 1.6 1999/11/24 13:26:22 damien Exp $"); 18RCSID("$Id: bufaux.c,v 1.7 1999/11/25 00:54:58 damien Exp $");
19 19
20#include "ssh.h" 20#include "ssh.h"
21 21
@@ -54,7 +54,7 @@ buffer_put_bignum(Buffer *buffer, BIGNUM *value)
54 buffer_append(buffer, msg, 2); 54 buffer_append(buffer, msg, 2);
55 /* Store the binary data. */ 55 /* Store the binary data. */
56 buffer_append(buffer, buf, oi); 56 buffer_append(buffer, buf, oi);
57 /* Clear the temporary data. */ 57
58 memset(buf, 0, bin_size); 58 memset(buf, 0, bin_size);
59 xfree(buf); 59 xfree(buf);
60} 60}
diff --git a/bufaux.h b/bufaux.h
index 0b17a8ac7..8884c17f4 100644
--- a/bufaux.h
+++ b/bufaux.h
@@ -11,15 +11,17 @@
11 * 11 *
12 */ 12 */
13 13
14/* RCSID("$Id: bufaux.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ 14/* RCSID("$Id: bufaux.h,v 1.3 1999/11/25 00:54:58 damien Exp $"); */
15 15
16#ifndef BUFAUX_H 16#ifndef BUFAUX_H
17#define BUFAUX_H 17#define BUFAUX_H
18 18
19#include "buffer.h" 19#include "buffer.h"
20 20
21/* Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed 21/*
22 by (bits+7)/8 bytes of binary data, msb first. */ 22 * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
23 * by (bits+7)/8 bytes of binary data, msb first.
24 */
23void buffer_put_bignum(Buffer * buffer, BIGNUM * value); 25void buffer_put_bignum(Buffer * buffer, BIGNUM * value);
24 26
25/* Retrieves an BIGNUM from the buffer. */ 27/* Retrieves an BIGNUM from the buffer. */
@@ -37,12 +39,14 @@ int buffer_get_char(Buffer * buffer);
37/* Stores a character in the buffer. */ 39/* Stores a character in the buffer. */
38void buffer_put_char(Buffer * buffer, int value); 40void buffer_put_char(Buffer * buffer, int value);
39 41
40/* Returns an arbitrary binary string from the buffer. The string cannot 42/*
41 be longer than 256k. The returned value points to memory allocated 43 * Returns an arbitrary binary string from the buffer. The string cannot be
42 with xmalloc; it is the responsibility of the calling function to free 44 * longer than 256k. The returned value points to memory allocated with
43 the data. If length_ptr is non-NULL, the length of the returned data 45 * xmalloc; it is the responsibility of the calling function to free the
44 will be stored there. A null character will be automatically appended 46 * data. If length_ptr is non-NULL, the length of the returned data will be
45 to the returned string, and is not counted in length. */ 47 * stored there. A null character will be automatically appended to the
48 * returned string, and is not counted in length.
49 */
46char *buffer_get_string(Buffer * buffer, unsigned int *length_ptr); 50char *buffer_get_string(Buffer * buffer, unsigned int *length_ptr);
47 51
48/* Stores and arbitrary binary string in the buffer. */ 52/* Stores and arbitrary binary string in the buffer. */
diff --git a/buffer.c b/buffer.c
index 6ad9bb2e9..b4c166d0e 100644
--- a/buffer.c
+++ b/buffer.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: buffer.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); 17RCSID("$Id: buffer.c,v 1.3 1999/11/25 00:54:58 damien Exp $");
18 18
19#include "xmalloc.h" 19#include "xmalloc.h"
20#include "buffer.h" 20#include "buffer.h"
@@ -40,8 +40,10 @@ buffer_free(Buffer *buffer)
40 xfree(buffer->buf); 40 xfree(buffer->buf);
41} 41}
42 42
43/* Clears any data from the buffer, making it empty. This does not actually 43/*
44 zero the memory. */ 44 * Clears any data from the buffer, making it empty. This does not actually
45 * zero the memory.
46 */
45 47
46void 48void
47buffer_clear(Buffer *buffer) 49buffer_clear(Buffer *buffer)
@@ -60,9 +62,11 @@ buffer_append(Buffer *buffer, const char *data, unsigned int len)
60 memcpy(cp, data, len); 62 memcpy(cp, data, len);
61} 63}
62 64
63/* Appends space to the buffer, expanding the buffer if necessary. 65/*
64 This does not actually copy the data into the buffer, but instead 66 * Appends space to the buffer, expanding the buffer if necessary. This does
65 returns a pointer to the allocated region. */ 67 * not actually copy the data into the buffer, but instead returns a pointer
68 * to the allocated region.
69 */
66 70
67void 71void
68buffer_append_space(Buffer *buffer, char **datap, unsigned int len) 72buffer_append_space(Buffer *buffer, char **datap, unsigned int len)
@@ -79,8 +83,10 @@ restart:
79 buffer->end += len; 83 buffer->end += len;
80 return; 84 return;
81 } 85 }
82 /* If the buffer is quite empty, but all data is at the end, move 86 /*
83 the data to the beginning and retry. */ 87 * If the buffer is quite empty, but all data is at the end, move the
88 * data to the beginning and retry.
89 */
84 if (buffer->offset > buffer->alloc / 2) { 90 if (buffer->offset > buffer->alloc / 2) {
85 memmove(buffer->buf, buffer->buf + buffer->offset, 91 memmove(buffer->buf, buffer->buf + buffer->offset,
86 buffer->end - buffer->offset); 92 buffer->end - buffer->offset);
diff --git a/buffer.h b/buffer.h
index affe1012c..bae740545 100644
--- a/buffer.h
+++ b/buffer.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: buffer.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: buffer.h,v 1.3 1999/11/25 00:54:58 damien Exp $"); */
17 17
18#ifndef BUFFER_H 18#ifndef BUFFER_H
19#define BUFFER_H 19#define BUFFER_H
@@ -37,9 +37,11 @@ void buffer_clear(Buffer * buffer);
37/* Appends data to the buffer, expanding it if necessary. */ 37/* Appends data to the buffer, expanding it if necessary. */
38void buffer_append(Buffer * buffer, const char *data, unsigned int len); 38void buffer_append(Buffer * buffer, const char *data, unsigned int len);
39 39
40/* Appends space to the buffer, expanding the buffer if necessary. 40/*
41 This does not actually copy the data into the buffer, but instead 41 * Appends space to the buffer, expanding the buffer if necessary. This does
42 returns a pointer to the allocated region. */ 42 * not actually copy the data into the buffer, but instead returns a pointer
43 * to the allocated region.
44 */
43void buffer_append_space(Buffer * buffer, char **datap, unsigned int len); 45void buffer_append_space(Buffer * buffer, char **datap, unsigned int len);
44 46
45/* Returns the number of bytes of data in the buffer. */ 47/* Returns the number of bytes of data in the buffer. */
@@ -57,8 +59,10 @@ void buffer_consume_end(Buffer * buffer, unsigned int bytes);
57/* Returns a pointer to the first used byte in the buffer. */ 59/* Returns a pointer to the first used byte in the buffer. */
58char *buffer_ptr(Buffer * buffer); 60char *buffer_ptr(Buffer * buffer);
59 61
60/* Dumps the contents of the buffer to stderr in hex. This intended for 62/*
61 debugging purposes only. */ 63 * Dumps the contents of the buffer to stderr in hex. This intended for
64 * debugging purposes only.
65 */
62void buffer_dump(Buffer * buffer); 66void buffer_dump(Buffer * buffer);
63 67
64#endif /* BUFFER_H */ 68#endif /* BUFFER_H */
diff --git a/canohost.c b/canohost.c
index 3179ddc25..4209b6ab8 100644
--- a/canohost.c
+++ b/canohost.c
@@ -14,14 +14,16 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: canohost.c,v 1.3 1999/11/24 13:26:22 damien Exp $"); 17RCSID("$Id: canohost.c,v 1.4 1999/11/25 00:54:58 damien Exp $");
18 18
19#include "packet.h" 19#include "packet.h"
20#include "xmalloc.h" 20#include "xmalloc.h"
21#include "ssh.h" 21#include "ssh.h"
22 22
23/* Return the canonical name of the host at the other end of the socket. 23/*
24 The caller should free the returned string with xfree. */ 24 * Return the canonical name of the host at the other end of the socket. The
25 * caller should free the returned string with xfree.
26 */
25 27
26char * 28char *
27get_remote_hostname(int socket) 29get_remote_hostname(int socket)
@@ -52,19 +54,23 @@ get_remote_hostname(int socket)
52 else 54 else
53 strlcpy(name, hp->h_name, sizeof(name)); 55 strlcpy(name, hp->h_name, sizeof(name));
54 56
55 /* Convert it to all lowercase (which is expected by the 57 /*
56 rest of this software). */ 58 * Convert it to all lowercase (which is expected by the rest
59 * of this software).
60 */
57 for (i = 0; name[i]; i++) 61 for (i = 0; name[i]; i++)
58 if (isupper(name[i])) 62 if (isupper(name[i]))
59 name[i] = tolower(name[i]); 63 name[i] = tolower(name[i]);
60 64
61 /* Map it back to an IP address and check that the given 65 /*
62 address actually is an address of this host. This is 66 * Map it back to an IP address and check that the given
63 necessary because anyone with access to a name server 67 * address actually is an address of this host. This is
64 can define arbitrary names for an IP address. Mapping 68 * necessary because anyone with access to a name server can
65 from name to IP address can be trusted better (but can 69 * define arbitrary names for an IP address. Mapping from
66 still be fooled if the intruder has access to the name 70 * name to IP address can be trusted better (but can still be
67 server of the domain). */ 71 * fooled if the intruder has access to the name server of
72 * the domain).
73 */
68 hp = gethostbyname(name); 74 hp = gethostbyname(name);
69 if (!hp) { 75 if (!hp) {
70 log("reverse mapping checking gethostbyname for %.700s failed - POSSIBLE BREAKIN ATTEMPT!", name); 76 log("reverse mapping checking gethostbyname for %.700s failed - POSSIBLE BREAKIN ATTEMPT!", name);
@@ -76,8 +82,10 @@ get_remote_hostname(int socket)
76 if (memcmp(hp->h_addr_list[i], &from.sin_addr, sizeof(from.sin_addr)) 82 if (memcmp(hp->h_addr_list[i], &from.sin_addr, sizeof(from.sin_addr))
77 == 0) 83 == 0)
78 break; 84 break;
79 /* If we reached the end of the list, the address was not 85 /*
80 there. */ 86 * If we reached the end of the list, the address was not
87 * there.
88 */
81 if (!hp->h_addr_list[i]) { 89 if (!hp->h_addr_list[i]) {
82 /* Address not found for the host name. */ 90 /* Address not found for the host name. */
83 log("Address %.100s maps to %.600s, but this does not map back to the address - POSSIBLE BREAKIN ATTEMPT!", 91 log("Address %.100s maps to %.600s, but this does not map back to the address - POSSIBLE BREAKIN ATTEMPT!",
@@ -94,16 +102,17 @@ get_remote_hostname(int socket)
94 102
95check_ip_options: 103check_ip_options:
96 104
97 /* If IP options are supported, make sure there are none (log and 105 /*
98 disconnect them if any are found). Basically we are worried 106 * If IP options are supported, make sure there are none (log and
99 about source routing; it can be used to pretend you are 107 * disconnect them if any are found). Basically we are worried about
100 somebody (ip-address) you are not. That itself may be "almost 108 * source routing; it can be used to pretend you are somebody
101 acceptable" under certain circumstances, but rhosts 109 * (ip-address) you are not. That itself may be "almost acceptable"
102 autentication is useless if source routing is accepted. Notice 110 * under certain circumstances, but rhosts autentication is useless
103 also that if we just dropped source routing here, the other 111 * if source routing is accepted. Notice also that if we just dropped
104 side could use IP spoofing to do rest of the interaction and 112 * source routing here, the other side could use IP spoofing to do
105 could still bypass security. So we exit here if we detect any 113 * rest of the interaction and could still bypass security. So we
106 IP options. */ 114 * exit here if we detect any IP options.
115 */
107 { 116 {
108 unsigned char options[200], *ucp; 117 unsigned char options[200], *ucp;
109 char text[1024], *cp; 118 char text[1024], *cp;
@@ -134,9 +143,11 @@ check_ip_options:
134static char *canonical_host_name = NULL; 143static char *canonical_host_name = NULL;
135static char *canonical_host_ip = NULL; 144static char *canonical_host_ip = NULL;
136 145
137/* Return the canonical name of the host in the other side of the current 146/*
138 connection. The host name is cached, so it is efficient to call this 147 * Return the canonical name of the host in the other side of the current
139 several times. */ 148 * connection. The host name is cached, so it is efficient to call this
149 * several times.
150 */
140 151
141const char * 152const char *
142get_canonical_hostname() 153get_canonical_hostname()
@@ -154,8 +165,10 @@ get_canonical_hostname()
154 return canonical_host_name; 165 return canonical_host_name;
155} 166}
156 167
157/* Returns the IP-address of the remote host as a string. The returned 168/*
158 string need not be freed. */ 169 * Returns the IP-address of the remote host as a string. The returned
170 * string need not be freed.
171 */
159 172
160const char * 173const char *
161get_remote_ipaddr() 174get_remote_ipaddr()
@@ -163,7 +176,7 @@ get_remote_ipaddr()
163 struct sockaddr_in from; 176 struct sockaddr_in from;
164 int fromlen, socket; 177 int fromlen, socket;
165 178
166 /* Check if we have previously retrieved this same name. */ 179 /* Check whether we have chached the name. */
167 if (canonical_host_ip != NULL) 180 if (canonical_host_ip != NULL)
168 return canonical_host_ip; 181 return canonical_host_ip;
169 182
@@ -215,8 +228,10 @@ get_remote_port()
215{ 228{
216 int socket; 229 int socket;
217 230
218 /* If the connection is not a socket, return 65535. This is 231 /*
219 intentionally chosen to be an unprivileged port number. */ 232 * If the connection is not a socket, return 65535. This is
233 * intentionally chosen to be an unprivileged port number.
234 */
220 if (packet_get_connection_in() != packet_get_connection_out()) 235 if (packet_get_connection_in() != packet_get_connection_out())
221 return 65535; 236 return 65535;
222 237
diff --git a/channels.c b/channels.c
index 0a37d1abd..61ba76dec 100644
--- a/channels.c
+++ b/channels.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: channels.c,v 1.7 1999/11/24 13:26:22 damien Exp $"); 19RCSID("$Id: channels.c,v 1.8 1999/11/25 00:54:58 damien Exp $");
20 20
21#include "ssh.h" 21#include "ssh.h"
22#include "packet.h" 22#include "packet.h"
@@ -37,17 +37,23 @@ RCSID("$Id: channels.c,v 1.7 1999/11/24 13:26:22 damien Exp $");
37/* Max len of agent socket */ 37/* Max len of agent socket */
38#define MAX_SOCKET_NAME 100 38#define MAX_SOCKET_NAME 100
39 39
40/* Pointer to an array containing all allocated channels. The array is 40/*
41 dynamically extended as needed. */ 41 * Pointer to an array containing all allocated channels. The array is
42 * dynamically extended as needed.
43 */
42static Channel *channels = NULL; 44static Channel *channels = NULL;
43 45
44/* Size of the channel array. All slots of the array must always be 46/*
45 initialized (at least the type field); unused slots are marked with 47 * Size of the channel array. All slots of the array must always be
46 type SSH_CHANNEL_FREE. */ 48 * initialized (at least the type field); unused slots are marked with type
49 * SSH_CHANNEL_FREE.
50 */
47static int channels_alloc = 0; 51static int channels_alloc = 0;
48 52
49/* Maximum file descriptor value used in any of the channels. This is updated 53/*
50 in channel_allocate. */ 54 * Maximum file descriptor value used in any of the channels. This is
55 * updated in channel_allocate.
56 */
51static int channel_max_fd_value = 0; 57static int channel_max_fd_value = 0;
52 58
53/* Name and directory of socket for authentication agent forwarding. */ 59/* Name and directory of socket for authentication agent forwarding. */
@@ -61,15 +67,19 @@ char *x11_saved_proto = NULL;
61char *x11_saved_data = NULL; 67char *x11_saved_data = NULL;
62unsigned int x11_saved_data_len = 0; 68unsigned int x11_saved_data_len = 0;
63 69
64/* Fake X11 authentication data. This is what the server will be sending 70/*
65 us; we should replace any occurrences of this by the real data. */ 71 * Fake X11 authentication data. This is what the server will be sending us;
72 * we should replace any occurrences of this by the real data.
73 */
66char *x11_fake_data = NULL; 74char *x11_fake_data = NULL;
67unsigned int x11_fake_data_len; 75unsigned int x11_fake_data_len;
68 76
69/* Data structure for storing which hosts are permitted for forward requests. 77/*
70 The local sides of any remote forwards are stored in this array to prevent 78 * Data structure for storing which hosts are permitted for forward requests.
71 a corrupt remote server from accessing arbitrary TCP/IP ports on our 79 * The local sides of any remote forwards are stored in this array to prevent
72 local network (which might be behind a firewall). */ 80 * a corrupt remote server from accessing arbitrary TCP/IP ports on our local
81 * network (which might be behind a firewall).
82 */
73typedef struct { 83typedef struct {
74 char *host; /* Host name. */ 84 char *host; /* Host name. */
75 int port; /* Port number. */ 85 int port; /* Port number. */
@@ -79,9 +89,11 @@ typedef struct {
79static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; 89static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
80/* Number of permitted host/port pairs in the array. */ 90/* Number of permitted host/port pairs in the array. */
81static int num_permitted_opens = 0; 91static int num_permitted_opens = 0;
82/* If this is true, all opens are permitted. This is the case on the 92/*
83 server on which we have to trust the client anyway, and the user could 93 * If this is true, all opens are permitted. This is the case on the server
84 do anything after logging in anyway. */ 94 * on which we have to trust the client anyway, and the user could do
95 * anything after logging in anyway.
96 */
85static int all_opens_permitted = 0; 97static int all_opens_permitted = 0;
86 98
87/* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */ 99/* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */
@@ -95,9 +107,11 @@ channel_set_options(int hostname_in_open)
95 have_hostname_in_open = hostname_in_open; 107 have_hostname_in_open = hostname_in_open;
96} 108}
97 109
98/* Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually 110/*
99 called by the server, because the user could connect to any port anyway, 111 * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually
100 and the server has no way to know but to trust the client anyway. */ 112 * called by the server, because the user could connect to any port anyway,
113 * and the server has no way to know but to trust the client anyway.
114 */
101 115
102void 116void
103channel_permit_all_opens() 117channel_permit_all_opens()
@@ -105,8 +119,10 @@ channel_permit_all_opens()
105 all_opens_permitted = 1; 119 all_opens_permitted = 1;
106} 120}
107 121
108/* Allocate a new channel object and set its type and socket. 122/*
109 This will cause remote_name to be freed. */ 123 * Allocate a new channel object and set its type and socket. This will cause
124 * remote_name to be freed.
125 */
110 126
111int 127int
112channel_allocate(int type, int sock, char *remote_name) 128channel_allocate(int type, int sock, char *remote_name)
@@ -117,6 +133,7 @@ channel_allocate(int type, int sock, char *remote_name)
117 /* Update the maximum file descriptor value. */ 133 /* Update the maximum file descriptor value. */
118 if (sock > channel_max_fd_value) 134 if (sock > channel_max_fd_value)
119 channel_max_fd_value = sock; 135 channel_max_fd_value = sock;
136 /* XXX set close-on-exec -markus */
120 137
121 /* Do initial allocation if this is the first call. */ 138 /* Do initial allocation if this is the first call. */
122 if (channels_alloc == 0) { 139 if (channels_alloc == 0) {
@@ -124,9 +141,10 @@ channel_allocate(int type, int sock, char *remote_name)
124 channels = xmalloc(channels_alloc * sizeof(Channel)); 141 channels = xmalloc(channels_alloc * sizeof(Channel));
125 for (i = 0; i < channels_alloc; i++) 142 for (i = 0; i < channels_alloc; i++)
126 channels[i].type = SSH_CHANNEL_FREE; 143 channels[i].type = SSH_CHANNEL_FREE;
127 144 /*
128 /* Kludge: arrange a call to channel_stop_listening if we 145 * Kludge: arrange a call to channel_stop_listening if we
129 terminate with fatal(). */ 146 * terminate with fatal().
147 */
130 fatal_add_cleanup((void (*) (void *)) channel_stop_listening, NULL); 148 fatal_add_cleanup((void (*) (void *)) channel_stop_listening, NULL);
131 } 149 }
132 /* Try to find a free slot where to put the new channel. */ 150 /* Try to find a free slot where to put the new channel. */
@@ -137,8 +155,7 @@ channel_allocate(int type, int sock, char *remote_name)
137 break; 155 break;
138 } 156 }
139 if (found == -1) { 157 if (found == -1) {
140 /* There are no free slots. Take last+1 slot and expand 158 /* There are no free slots. Take last+1 slot and expand the array. */
141 the array. */
142 found = channels_alloc; 159 found = channels_alloc;
143 channels_alloc += 10; 160 channels_alloc += 10;
144 debug("channel: expanding %d", channels_alloc); 161 debug("channel: expanding %d", channels_alloc);
@@ -181,8 +198,10 @@ channel_free(int channel)
181 } 198 }
182} 199}
183 200
184/* This is called just before select() to add any bits relevant to 201/*
185 channels in the select bitmasks. */ 202 * This is called just before select() to add any bits relevant to channels
203 * in the select bitmasks.
204 */
186 205
187void 206void
188channel_prepare_select(fd_set * readset, fd_set * writeset) 207channel_prepare_select(fd_set * readset, fd_set * writeset)
@@ -248,15 +267,16 @@ redo:
248 break; 267 break;
249 268
250 case SSH_CHANNEL_X11_OPEN: 269 case SSH_CHANNEL_X11_OPEN:
251 /* This is a special state for X11 authentication 270 /*
252 spoofing. An opened X11 connection (when 271 * This is a special state for X11 authentication
253 authentication spoofing is being done) remains 272 * spoofing. An opened X11 connection (when
254 in this state until the first packet has been 273 * authentication spoofing is being done) remains in
255 completely read. The authentication data in 274 * this state until the first packet has been
256 that packet is then substituted by the real 275 * completely read. The authentication data in that
257 data if it matches the fake data, and the 276 * packet is then substituted by the real data if it
258 channel is put into normal mode. */ 277 * matches the fake data, and the channel is put into
259 278 * normal mode.
279 */
260 /* Check if the fixed size part of the packet is in buffer. */ 280 /* Check if the fixed size part of the packet is in buffer. */
261 if (buffer_len(&ch->output) < 12) 281 if (buffer_len(&ch->output) < 12)
262 break; 282 break;
@@ -303,9 +323,11 @@ redo:
303 ch->type = SSH_CHANNEL_OPEN; 323 ch->type = SSH_CHANNEL_OPEN;
304 goto reject; 324 goto reject;
305 } 325 }
306 /* Received authentication protocol and data match 326 /*
307 our fake data. Substitute the fake data with 327 * Received authentication protocol and data match
308 real data. */ 328 * our fake data. Substitute the fake data with real
329 * data.
330 */
309 memcpy(ucp + 12 + ((proto_len + 3) & ~3), 331 memcpy(ucp + 12 + ((proto_len + 3) & ~3),
310 x11_saved_data, x11_saved_data_len); 332 x11_saved_data, x11_saved_data_len);
311 333
@@ -314,8 +336,10 @@ redo:
314 goto redo; 336 goto redo;
315 337
316 reject: 338 reject:
317 /* We have received an X11 connection that has bad 339 /*
318 authentication information. */ 340 * We have received an X11 connection that has bad
341 * authentication information.
342 */
319 log("X11 connection rejected because of wrong authentication.\r\n"); 343 log("X11 connection rejected because of wrong authentication.\r\n");
320 buffer_clear(&ch->input); 344 buffer_clear(&ch->input);
321 buffer_clear(&ch->output); 345 buffer_clear(&ch->output);
@@ -341,8 +365,10 @@ redo:
341 } 365 }
342} 366}
343 367
344/* After select, perform any appropriate operations for channels which 368/*
345 have events pending. */ 369 * After select, perform any appropriate operations for channels which have
370 * events pending.
371 */
346 372
347void 373void
348channel_after_select(fd_set * readset, fd_set * writeset) 374channel_after_select(fd_set * readset, fd_set * writeset)
@@ -381,8 +407,10 @@ channel_after_select(fd_set * readset, fd_set * writeset)
381 break; 407 break;
382 408
383 case SSH_CHANNEL_PORT_LISTENER: 409 case SSH_CHANNEL_PORT_LISTENER:
384 /* This socket is listening for connections to a 410 /*
385 forwarded TCP/IP port. */ 411 * This socket is listening for connections to a
412 * forwarded TCP/IP port.
413 */
386 if (FD_ISSET(ch->sock, readset)) { 414 if (FD_ISSET(ch->sock, readset)) {
387 debug("Connection to port %d forwarding to %.100s:%d requested.", 415 debug("Connection to port %d forwarding to %.100s:%d requested.",
388 ch->listening_port, ch->path, ch->host_port); 416 ch->listening_port, ch->path, ch->host_port);
@@ -410,8 +438,10 @@ channel_after_select(fd_set * readset, fd_set * writeset)
410 break; 438 break;
411 439
412 case SSH_CHANNEL_AUTH_SOCKET: 440 case SSH_CHANNEL_AUTH_SOCKET:
413 /* This is the authentication agent socket 441 /*
414 listening for connections from clients. */ 442 * This is the authentication agent socket listening
443 * for connections from clients.
444 */
415 if (FD_ISSET(ch->sock, readset)) { 445 if (FD_ISSET(ch->sock, readset)) {
416 int nchan; 446 int nchan;
417 len = sizeof(addr); 447 len = sizeof(addr);
@@ -429,13 +459,16 @@ channel_after_select(fd_set * readset, fd_set * writeset)
429 break; 459 break;
430 460
431 case SSH_CHANNEL_OPEN: 461 case SSH_CHANNEL_OPEN:
432 /* This is an open two-way communication channel. 462 /*
433 It is not of interest to us at this point what 463 * This is an open two-way communication channel. It
434 kind of data is being transmitted. */ 464 * is not of interest to us at this point what kind
435 465 * of data is being transmitted.
436 /* Read available incoming data and append it to 466 */
437 buffer; shutdown socket, if read or write 467
438 failes */ 468 /*
469 * Read available incoming data and append it to
470 * buffer; shutdown socket, if read or write failes
471 */
439 if (FD_ISSET(ch->sock, readset)) { 472 if (FD_ISSET(ch->sock, readset)) {
440 len = read(ch->sock, buf, sizeof(buf)); 473 len = read(ch->sock, buf, sizeof(buf));
441 if (len <= 0) { 474 if (len <= 0) {
@@ -500,8 +533,7 @@ channel_output_poll()
500 533
501 for (i = 0; i < channels_alloc; i++) { 534 for (i = 0; i < channels_alloc; i++) {
502 ch = &channels[i]; 535 ch = &channels[i];
503 /* We are only interested in channels that can have 536 /* We are only interested in channels that can have buffered incoming data. */
504 buffered incoming data. */
505 if (ch->type != SSH_CHANNEL_OPEN && 537 if (ch->type != SSH_CHANNEL_OPEN &&
506 ch->type != SSH_CHANNEL_INPUT_DRAINING) 538 ch->type != SSH_CHANNEL_INPUT_DRAINING)
507 continue; 539 continue;
@@ -509,8 +541,7 @@ channel_output_poll()
509 /* Get the amount of buffered data for this channel. */ 541 /* Get the amount of buffered data for this channel. */
510 len = buffer_len(&ch->input); 542 len = buffer_len(&ch->input);
511 if (len > 0) { 543 if (len > 0) {
512 /* Send some data for the other side over the 544 /* Send some data for the other side over the secure connection. */
513 secure connection. */
514 if (packet_is_interactive()) { 545 if (packet_is_interactive()) {
515 if (len > 1024) 546 if (len > 1024)
516 len = 512; 547 len = 512;
@@ -527,17 +558,20 @@ channel_output_poll()
527 } else if (ch->istate == CHAN_INPUT_WAIT_DRAIN) { 558 } else if (ch->istate == CHAN_INPUT_WAIT_DRAIN) {
528 if (compat13) 559 if (compat13)
529 fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3"); 560 fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
530 /* input-buffer is empty and read-socket shutdown: 561 /*
531 tell peer, that we will not send more data: 562 * input-buffer is empty and read-socket shutdown:
532 send IEOF */ 563 * tell peer, that we will not send more data: send IEOF
564 */
533 chan_ibuf_empty(ch); 565 chan_ibuf_empty(ch);
534 } 566 }
535 } 567 }
536} 568}
537 569
538/* This is called when a packet of type CHANNEL_DATA has just been received. 570/*
539 The message type has already been consumed, but channel number and data 571 * This is called when a packet of type CHANNEL_DATA has just been received.
540 is still there. */ 572 * The message type has already been consumed, but channel number and data is
573 * still there.
574 */
541 575
542void 576void
543channel_input_data(int payload_len) 577channel_input_data(int payload_len)
@@ -564,8 +598,10 @@ channel_input_data(int payload_len)
564 xfree(data); 598 xfree(data);
565} 599}
566 600
567/* Returns true if no channel has too much buffered data, and false if 601/*
568 one or more channel is overfull. */ 602 * Returns true if no channel has too much buffered data, and false if one or
603 * more channel is overfull.
604 */
569 605
570int 606int
571channel_not_very_much_buffered_data() 607channel_not_very_much_buffered_data()
@@ -615,20 +651,27 @@ channel_input_close()
615 chan_rcvd_ieof(&channels[channel]); 651 chan_rcvd_ieof(&channels[channel]);
616 return; 652 return;
617 } 653 }
618 /* Send a confirmation that we have closed the channel and no more 654
619 data is coming for it. */ 655 /*
656 * Send a confirmation that we have closed the channel and no more
657 * data is coming for it.
658 */
620 packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION); 659 packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION);
621 packet_put_int(channels[channel].remote_id); 660 packet_put_int(channels[channel].remote_id);
622 packet_send(); 661 packet_send();
623 662
624 /* If the channel is in closed state, we have sent a close 663 /*
625 request, and the other side will eventually respond with a 664 * If the channel is in closed state, we have sent a close request,
626 confirmation. Thus, we cannot free the channel here, because 665 * and the other side will eventually respond with a confirmation.
627 then there would be no-one to receive the confirmation. The 666 * Thus, we cannot free the channel here, because then there would be
628 channel gets freed when the confirmation arrives. */ 667 * no-one to receive the confirmation. The channel gets freed when
668 * the confirmation arrives.
669 */
629 if (channels[channel].type != SSH_CHANNEL_CLOSED) { 670 if (channels[channel].type != SSH_CHANNEL_CLOSED) {
630 /* Not a closed channel - mark it as draining, which will 671 /*
631 cause it to be freed later. */ 672 * Not a closed channel - mark it as draining, which will
673 * cause it to be freed later.
674 */
632 buffer_consume(&channels[channel].input, 675 buffer_consume(&channels[channel].input,
633 buffer_len(&channels[channel].input)); 676 buffer_len(&channels[channel].input));
634 channels[channel].type = SSH_CHANNEL_OUTPUT_DRAINING; 677 channels[channel].type = SSH_CHANNEL_OUTPUT_DRAINING;
@@ -678,8 +721,7 @@ channel_input_open_confirmation()
678 /* Get remote side's id for this channel. */ 721 /* Get remote side's id for this channel. */
679 remote_channel = packet_get_int(); 722 remote_channel = packet_get_int();
680 723
681 /* Record the remote channel number and mark that the channel is 724 /* Record the remote channel number and mark that the channel is now open. */
682 now open. */
683 channels[channel].remote_id = remote_channel; 725 channels[channel].remote_id = remote_channel;
684 channels[channel].type = SSH_CHANNEL_OPEN; 726 channels[channel].type = SSH_CHANNEL_OPEN;
685} 727}
@@ -702,8 +744,10 @@ channel_input_open_failure()
702 channel_free(channel); 744 channel_free(channel);
703} 745}
704 746
705/* Stops listening for channels, and removes any unix domain sockets that 747/*
706 we might have. */ 748 * Stops listening for channels, and removes any unix domain sockets that we
749 * might have.
750 */
707 751
708void 752void
709channel_stop_listening() 753channel_stop_listening()
@@ -727,8 +771,10 @@ channel_stop_listening()
727 } 771 }
728} 772}
729 773
730/* Closes the sockets of all channels. This is used to close extra file 774/*
731 descriptors after a fork. */ 775 * Closes the sockets of all channels. This is used to close extra file
776 * descriptors after a fork.
777 */
732 778
733void 779void
734channel_close_all() 780channel_close_all()
@@ -778,9 +824,11 @@ channel_still_open()
778 return 0; 824 return 0;
779} 825}
780 826
781/* Returns a message describing the currently open forwarded 827/*
782 connections, suitable for sending to the client. The message 828 * Returns a message describing the currently open forwarded connections,
783 contains crlf pairs for newlines. */ 829 * suitable for sending to the client. The message contains crlf pairs for
830 * newlines.
831 */
784 832
785char * 833char *
786channel_open_message() 834channel_open_message()
@@ -822,16 +870,19 @@ channel_open_message()
822 return cp; 870 return cp;
823} 871}
824 872
825/* Initiate forwarding of connections to local port "port" through the secure 873/*
826 channel to host:port from remote side. */ 874 * Initiate forwarding of connections to local port "port" through the secure
875 * channel to host:port from remote side.
876 */
827 877
828void 878void
829channel_request_local_forwarding(int port, const char *host, 879channel_request_local_forwarding(int port, const char *host,
830 int host_port) 880 int host_port)
831{ 881{
832 int ch, sock; 882 int ch, sock, on = 1;
833 struct sockaddr_in sin; 883 struct sockaddr_in sin;
834 extern Options options; 884 extern Options options;
885 struct linger linger;
835 886
836 if (strlen(host) > sizeof(channels[0].path) - 1) 887 if (strlen(host) > sizeof(channels[0].path) - 1)
837 packet_disconnect("Forward host name too long."); 888 packet_disconnect("Forward host name too long.");
@@ -850,6 +901,15 @@ channel_request_local_forwarding(int port, const char *host,
850 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 901 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
851 sin.sin_port = htons(port); 902 sin.sin_port = htons(port);
852 903
904 /*
905 * Set socket options. We would like the socket to disappear as soon
906 * as it has been closed for whatever reason.
907 */
908 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
909 linger.l_onoff = 1;
910 linger.l_linger = 5;
911 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
912
853 /* Bind the socket to the address. */ 913 /* Bind the socket to the address. */
854 if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) 914 if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
855 packet_disconnect("bind: %.100s", strerror(errno)); 915 packet_disconnect("bind: %.100s", strerror(errno));
@@ -866,8 +926,10 @@ channel_request_local_forwarding(int port, const char *host,
866 channels[ch].listening_port = port; 926 channels[ch].listening_port = port;
867} 927}
868 928
869/* Initiate forwarding of connections to port "port" on remote host through 929/*
870 the secure channel to host:port from local side. */ 930 * Initiate forwarding of connections to port "port" on remote host through
931 * the secure channel to host:port from local side.
932 */
871 933
872void 934void
873channel_request_remote_forwarding(int port, const char *host, 935channel_request_remote_forwarding(int port, const char *host,
@@ -890,15 +952,18 @@ channel_request_remote_forwarding(int port, const char *host,
890 packet_send(); 952 packet_send();
891 packet_write_wait(); 953 packet_write_wait();
892 954
893 /* Wait for response from the remote side. It will send a 955 /*
894 disconnect message on failure, and we will never see it here. */ 956 * Wait for response from the remote side. It will send a disconnect
957 * message on failure, and we will never see it here.
958 */
895 packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); 959 packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
896} 960}
897 961
898/* This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates 962/*
899 listening for the port, and sends back a success reply (or disconnect 963 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
900 message if there was an error). This never returns if there was an 964 * listening for the port, and sends back a success reply (or disconnect
901 error. */ 965 * message if there was an error). This never returns if there was an error.
966 */
902 967
903void 968void
904channel_input_port_forward_request(int is_root) 969channel_input_port_forward_request(int is_root)
@@ -915,8 +980,10 @@ channel_input_port_forward_request(int is_root)
915 if ((port & 0xffff) != port) 980 if ((port & 0xffff) != port)
916 packet_disconnect("Requested forwarding of nonexistent port %d.", port); 981 packet_disconnect("Requested forwarding of nonexistent port %d.", port);
917 982
918 /* Check that an unprivileged user is not trying to forward a 983 /*
919 privileged port. */ 984 * Check that an unprivileged user is not trying to forward a
985 * privileged port.
986 */
920 if (port < IPPORT_RESERVED && !is_root) 987 if (port < IPPORT_RESERVED && !is_root)
921 packet_disconnect("Requested forwarding of port %d but user is not root.", 988 packet_disconnect("Requested forwarding of port %d but user is not root.",
922 port); 989 port);
@@ -928,9 +995,11 @@ channel_input_port_forward_request(int is_root)
928 xfree(hostname); 995 xfree(hostname);
929} 996}
930 997
931/* This is called after receiving PORT_OPEN message. This attempts to connect 998/*
932 to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION or 999 * This is called after receiving PORT_OPEN message. This attempts to
933 CHANNEL_OPEN_FAILURE. */ 1000 * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION
1001 * or CHANNEL_OPEN_FAILURE.
1002 */
934 1003
935void 1004void
936channel_input_port_open(int payload_len) 1005channel_input_port_open(int payload_len)
@@ -951,13 +1020,16 @@ channel_input_port_open(int payload_len)
951 host_port = packet_get_int(); 1020 host_port = packet_get_int();
952 1021
953 /* Get remote originator name. */ 1022 /* Get remote originator name. */
954 if (have_hostname_in_open) 1023 if (have_hostname_in_open) {
955 originator_string = packet_get_string(&originator_len); 1024 originator_string = packet_get_string(&originator_len);
956 else 1025 originator_len += 4; /* size of packet_int */
1026 } else {
957 originator_string = xstrdup("unknown (remote did not supply name)"); 1027 originator_string = xstrdup("unknown (remote did not supply name)");
1028 originator_len = 0; /* no originator supplied */
1029 }
958 1030
959 packet_integrity_check(payload_len, 1031 packet_integrity_check(payload_len,
960 4 + 4 + host_len + 4 + 4 + originator_len, 1032 4 + 4 + host_len + 4 + originator_len,
961 SSH_MSG_PORT_OPEN); 1033 SSH_MSG_PORT_OPEN);
962 1034
963 /* Check if opening that port is permitted. */ 1035 /* Check if opening that port is permitted. */
@@ -1040,9 +1112,11 @@ fail:
1040 packet_send(); 1112 packet_send();
1041} 1113}
1042 1114
1043/* Creates an internet domain socket for listening for X11 connections. 1115/*
1044 Returns a suitable value for the DISPLAY variable, or NULL if an error 1116 * Creates an internet domain socket for listening for X11 connections.
1045 occurs. */ 1117 * Returns a suitable value for the DISPLAY variable, or NULL if an error
1118 * occurs.
1119 */
1046 1120
1047char * 1121char *
1048x11_create_display_inet(int screen_number) 1122x11_create_display_inet(int screen_number)
@@ -1134,9 +1208,11 @@ connect_local_xsocket(unsigned dnr)
1134} 1208}
1135 1209
1136 1210
1137/* This is called when SSH_SMSG_X11_OPEN is received. The packet contains 1211/*
1138 the remote channel number. We should do whatever we want, and respond 1212 * This is called when SSH_SMSG_X11_OPEN is received. The packet contains
1139 with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. */ 1213 * the remote channel number. We should do whatever we want, and respond
1214 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
1215 */
1140 1216
1141void 1217void
1142x11_input_open(int payload_len) 1218x11_input_open(int payload_len)
@@ -1152,13 +1228,16 @@ x11_input_open(int payload_len)
1152 remote_channel = packet_get_int(); 1228 remote_channel = packet_get_int();
1153 1229
1154 /* Get remote originator name. */ 1230 /* Get remote originator name. */
1155 if (have_hostname_in_open) 1231 if (have_hostname_in_open) {
1156 remote_host = packet_get_string(&remote_len); 1232 remote_host = packet_get_string(&remote_len);
1157 else 1233 remote_len += 4;
1234 } else {
1158 remote_host = xstrdup("unknown (remote did not supply name)"); 1235 remote_host = xstrdup("unknown (remote did not supply name)");
1236 remote_len = 0;
1237 }
1159 1238
1160 debug("Received X11 open request."); 1239 debug("Received X11 open request.");
1161 packet_integrity_check(payload_len, 4 + 4 + remote_len, SSH_SMSG_X11_OPEN); 1240 packet_integrity_check(payload_len, 4 + remote_len, SSH_SMSG_X11_OPEN);
1162 1241
1163 /* Try to open a socket for the local X server. */ 1242 /* Try to open a socket for the local X server. */
1164 display = getenv("DISPLAY"); 1243 display = getenv("DISPLAY");
@@ -1166,11 +1245,15 @@ x11_input_open(int payload_len)
1166 error("DISPLAY not set."); 1245 error("DISPLAY not set.");
1167 goto fail; 1246 goto fail;
1168 } 1247 }
1169 /* Now we decode the value of the DISPLAY variable and make a 1248 /*
1170 connection to the real X server. */ 1249 * Now we decode the value of the DISPLAY variable and make a
1171 1250 * connection to the real X server.
1172 /* Check if it is a unix domain socket. Unix domain displays are 1251 */
1173 in one of the following formats: unix:d[.s], :d[.s], ::d[.s] */ 1252
1253 /*
1254 * Check if it is a unix domain socket. Unix domain displays are in
1255 * one of the following formats: unix:d[.s], :d[.s], ::d[.s]
1256 */
1174 if (strncmp(display, "unix:", 5) == 0 || 1257 if (strncmp(display, "unix:", 5) == 0 ||
1175 display[0] == ':') { 1258 display[0] == ':') {
1176 /* Connect to the unix domain socket. */ 1259 /* Connect to the unix domain socket. */
@@ -1187,8 +1270,10 @@ x11_input_open(int payload_len)
1187 /* OK, we now have a connection to the display. */ 1270 /* OK, we now have a connection to the display. */
1188 goto success; 1271 goto success;
1189 } 1272 }
1190 /* Connect to an inet socket. The DISPLAY value is supposedly 1273 /*
1191 hostname:d[.s], where hostname may also be numeric IP address. */ 1274 * Connect to an inet socket. The DISPLAY value is supposedly
1275 * hostname:d[.s], where hostname may also be numeric IP address.
1276 */
1192 strncpy(buf, display, sizeof(buf)); 1277 strncpy(buf, display, sizeof(buf));
1193 buf[sizeof(buf) - 1] = 0; 1278 buf[sizeof(buf) - 1] = 0;
1194 cp = strchr(buf, ':'); 1279 cp = strchr(buf, ':');
@@ -1197,8 +1282,7 @@ x11_input_open(int payload_len)
1197 goto fail; 1282 goto fail;
1198 } 1283 }
1199 *cp = 0; 1284 *cp = 0;
1200 /* buf now contains the host name. But first we parse the display 1285 /* buf now contains the host name. But first we parse the display number. */
1201 number. */
1202 if (sscanf(cp + 1, "%d", &display_number) != 1) { 1286 if (sscanf(cp + 1, "%d", &display_number) != 1) {
1203 error("Could not parse display number from DISPLAY: %.100s", 1287 error("Could not parse display number from DISPLAY: %.100s",
1204 display); 1288 display);
@@ -1267,8 +1351,10 @@ fail:
1267 packet_send(); 1351 packet_send();
1268} 1352}
1269 1353
1270/* Requests forwarding of X11 connections, generates fake authentication 1354/*
1271 data, and enables authentication spoofing. */ 1355 * Requests forwarding of X11 connections, generates fake authentication
1356 * data, and enables authentication spoofing.
1357 */
1272 1358
1273void 1359void
1274x11_request_forwarding_with_spoofing(const char *proto, const char *data) 1360x11_request_forwarding_with_spoofing(const char *proto, const char *data)
@@ -1293,8 +1379,10 @@ x11_request_forwarding_with_spoofing(const char *proto, const char *data)
1293 /* Save protocol name. */ 1379 /* Save protocol name. */
1294 x11_saved_proto = xstrdup(proto); 1380 x11_saved_proto = xstrdup(proto);
1295 1381
1296 /* Extract real authentication data and generate fake data of the 1382 /*
1297 same length. */ 1383 * Extract real authentication data and generate fake data of the
1384 * same length.
1385 */
1298 x11_saved_data = xmalloc(data_len); 1386 x11_saved_data = xmalloc(data_len);
1299 x11_fake_data = xmalloc(data_len); 1387 x11_fake_data = xmalloc(data_len);
1300 for (i = 0; i < data_len; i++) { 1388 for (i = 0; i < data_len; i++) {
@@ -1334,9 +1422,11 @@ auth_request_forwarding()
1334 packet_write_wait(); 1422 packet_write_wait();
1335} 1423}
1336 1424
1337/* Returns the name of the forwarded authentication socket. Returns NULL 1425/*
1338 if there is no forwarded authentication socket. The returned value 1426 * Returns the name of the forwarded authentication socket. Returns NULL if
1339 points to a static buffer. */ 1427 * there is no forwarded authentication socket. The returned value points to
1428 * a static buffer.
1429 */
1340 1430
1341char * 1431char *
1342auth_get_socket_name() 1432auth_get_socket_name()
@@ -1353,8 +1443,10 @@ cleanup_socket(void)
1353 rmdir(channel_forwarded_auth_socket_dir); 1443 rmdir(channel_forwarded_auth_socket_dir);
1354} 1444}
1355 1445
1356/* This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. 1446/*
1357 This starts forwarding authentication requests. */ 1447 * This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server.
1448 * This starts forwarding authentication requests.
1449 */
1358 1450
1359void 1451void
1360auth_input_request_forwarding(struct passwd * pw) 1452auth_input_request_forwarding(struct passwd * pw)
@@ -1422,14 +1514,18 @@ auth_input_open_request()
1422 /* Read the remote channel number from the message. */ 1514 /* Read the remote channel number from the message. */
1423 remch = packet_get_int(); 1515 remch = packet_get_int();
1424 1516
1425 /* Get a connection to the local authentication agent (this may 1517 /*
1426 again get forwarded). */ 1518 * Get a connection to the local authentication agent (this may again
1519 * get forwarded).
1520 */
1427 sock = ssh_get_authentication_socket(); 1521 sock = ssh_get_authentication_socket();
1428 1522
1429 /* If we could not connect the agent, send an error message back 1523 /*
1430 to the server. This should never happen unless the agent dies, 1524 * If we could not connect the agent, send an error message back to
1431 because authentication forwarding is only enabled if we have an 1525 * the server. This should never happen unless the agent dies,
1432 agent. */ 1526 * because authentication forwarding is only enabled if we have an
1527 * agent.
1528 */
1433 if (sock < 0) { 1529 if (sock < 0) {
1434 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); 1530 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1435 packet_put_int(remch); 1531 packet_put_int(remch);
@@ -1438,9 +1534,11 @@ auth_input_open_request()
1438 } 1534 }
1439 debug("Forwarding authentication connection."); 1535 debug("Forwarding authentication connection.");
1440 1536
1441 /* Dummy host name. This will be freed when the channel is freed; 1537 /*
1442 it will still be valid in the packet_put_string below since the 1538 * Dummy host name. This will be freed when the channel is freed; it
1443 channel cannot yet be freed at that point. */ 1539 * will still be valid in the packet_put_string below since the
1540 * channel cannot yet be freed at that point.
1541 */
1444 dummyname = xstrdup("authentication agent connection"); 1542 dummyname = xstrdup("authentication agent connection");
1445 1543
1446 newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname); 1544 newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname);
diff --git a/channels.h b/channels.h
index 5851257ca..f8bca5c9a 100644
--- a/channels.h
+++ b/channels.h
@@ -1,29 +1,26 @@
1/* RCSID("$Id: channels.h,v 1.3 1999/11/24 13:26:22 damien Exp $"); */ 1/* RCSID("$Id: channels.h,v 1.4 1999/11/25 00:54:58 damien Exp $"); */
2 2
3#ifndef CHANNELS_H 3#ifndef CHANNELS_H
4#define CHANNELS_H 4#define CHANNELS_H
5 5
6/* Definitions for channel types. */ 6/* Definitions for channel types. */
7#define SSH_CHANNEL_FREE 0 /* This channel is free 7#define SSH_CHANNEL_FREE 0 /* This channel is free (unused). */
8 * (unused). */ 8#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */
9#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11
10 * conn. */
11#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */ 9#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */
12#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */ 10#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */
13#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */ 11#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */
14#define SSH_CHANNEL_CLOSED 5 /* waiting for close 12#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */
15 * confirmation */ 13/* SSH_CHANNEL_AUTH_FD 6 authentication fd */
16/* SSH_CHANNEL_AUTH_FD 6 authentication fd */
17#define SSH_CHANNEL_AUTH_SOCKET 7 /* authentication socket */ 14#define SSH_CHANNEL_AUTH_SOCKET 7 /* authentication socket */
18/* SSH_CHANNEL_AUTH_SOCKET_FD 8 connection to auth socket */ 15/* SSH_CHANNEL_AUTH_SOCKET_FD 8 connection to auth socket */
19#define SSH_CHANNEL_X11_OPEN 9 /* reading first X11 packet */ 16#define SSH_CHANNEL_X11_OPEN 9 /* reading first X11 packet */
20#define SSH_CHANNEL_INPUT_DRAINING 10 /* sending remaining data to 17#define SSH_CHANNEL_INPUT_DRAINING 10 /* sending remaining data to conn */
21 * conn */ 18#define SSH_CHANNEL_OUTPUT_DRAINING 11 /* sending remaining data to app */
22#define SSH_CHANNEL_OUTPUT_DRAINING 11 /* sending remaining data to
23 * app */
24 19
25/* Data structure for channel data. This is iniailized in channel_allocate 20/*
26 and cleared in channel_free. */ 21 * Data structure for channel data. This is iniailized in channel_allocate
22 * and cleared in channel_free.
23 */
27 24
28typedef struct Channel { 25typedef struct Channel {
29 int type; /* channel type/state */ 26 int type; /* channel type/state */
diff --git a/cipher.c b/cipher.c
index 92fcd4740..e3bb05d13 100644
--- a/cipher.c
+++ b/cipher.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$Id: cipher.c,v 1.7 1999/11/24 13:26:22 damien Exp $"); 15RCSID("$Id: cipher.c,v 1.8 1999/11/25 00:54:58 damien Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "cipher.h" 18#include "cipher.h"
@@ -121,8 +121,10 @@ detect_cbc_attack(const unsigned char *src,
121 cipher_attack_detected("CRC-32 CBC insertion attack detected"); 121 cipher_attack_detected("CRC-32 CBC insertion attack detected");
122} 122}
123 123
124/* Names of all encryption algorithms. These must match the numbers defined 124/*
125 int cipher.h. */ 125 * Names of all encryption algorithms.
126 * These must match the numbers defined in cipher.h.
127 */
126static char *cipher_names[] = 128static char *cipher_names[] =
127{ 129{
128 "none", 130 "none",
@@ -134,9 +136,11 @@ static char *cipher_names[] =
134 "blowfish" 136 "blowfish"
135}; 137};
136 138
137/* Returns a bit mask indicating which ciphers are supported by this 139/*
138 implementation. The bit mask has the corresponding bit set of each 140 * Returns a bit mask indicating which ciphers are supported by this
139 supported cipher. */ 141 * implementation. The bit mask has the corresponding bit set of each
142 * supported cipher.
143 */
140 144
141unsigned int 145unsigned int
142cipher_mask() 146cipher_mask()
@@ -158,8 +162,10 @@ cipher_name(int cipher)
158 return cipher_names[cipher]; 162 return cipher_names[cipher];
159} 163}
160 164
161/* Parses the name of the cipher. Returns the number of the corresponding 165/*
162 cipher, or -1 on error. */ 166 * Parses the name of the cipher. Returns the number of the corresponding
167 * cipher, or -1 on error.
168 */
163 169
164int 170int
165cipher_number(const char *name) 171cipher_number(const char *name)
@@ -172,8 +178,10 @@ cipher_number(const char *name)
172 return -1; 178 return -1;
173} 179}
174 180
175/* Selects the cipher, and keys if by computing the MD5 checksum of the 181/*
176 passphrase and using the resulting 16 bytes as the key. */ 182 * Selects the cipher, and keys if by computing the MD5 checksum of the
183 * passphrase and using the resulting 16 bytes as the key.
184 */
177 185
178void 186void
179cipher_set_key_string(CipherContext *context, int cipher, 187cipher_set_key_string(CipherContext *context, int cipher,
@@ -211,15 +219,18 @@ cipher_set_key(CipherContext *context, int cipher,
211 /* Initialize the initialization vector. */ 219 /* Initialize the initialization vector. */
212 switch (cipher) { 220 switch (cipher) {
213 case SSH_CIPHER_NONE: 221 case SSH_CIPHER_NONE:
214 /* Has to stay for authfile saving of private key with 222 /*
215 no passphrase */ 223 * Has to stay for authfile saving of private key with no
224 * passphrase
225 */
216 break; 226 break;
217 227
218 case SSH_CIPHER_3DES: 228 case SSH_CIPHER_3DES:
219 /* Note: the least significant bit of each byte of key is 229 /*
220 parity, and must be ignored by the implementation. 16 230 * Note: the least significant bit of each byte of key is
221 bytes of key are used (first and last keys are the 231 * parity, and must be ignored by the implementation. 16
222 same). */ 232 * bytes of key are used (first and last keys are the same).
233 */
223 if (keylen < 16) 234 if (keylen < 16)
224 error("Key length %d is insufficient for 3DES.", keylen); 235 error("Key length %d is insufficient for 3DES.", keylen);
225 des_set_key((void *) padded, context->u.des3.key1); 236 des_set_key((void *) padded, context->u.des3.key1);
diff --git a/cipher.h b/cipher.h
index ae37b0bb8..79e8fb878 100644
--- a/cipher.h
+++ b/cipher.h
@@ -11,7 +11,7 @@
11 * 11 *
12 */ 12 */
13 13
14/* RCSID("$Id: cipher.h,v 1.4 1999/11/24 13:26:22 damien Exp $"); */ 14/* RCSID("$Id: cipher.h,v 1.5 1999/11/25 00:54:58 damien Exp $"); */
15 15
16#ifndef CIPHER_H 16#ifndef CIPHER_H
17#define CIPHER_H 17#define CIPHER_H
@@ -54,26 +54,34 @@ typedef struct {
54 } bf; 54 } bf;
55 } u; 55 } u;
56} CipherContext; 56} CipherContext;
57/* Returns a bit mask indicating which ciphers are supported by this 57/*
58 implementation. The bit mask has the corresponding bit set of each 58 * Returns a bit mask indicating which ciphers are supported by this
59 supported cipher. */ 59 * implementation. The bit mask has the corresponding bit set of each
60 * supported cipher.
61 */
60unsigned int cipher_mask(); 62unsigned int cipher_mask();
61 63
62/* Returns the name of the cipher. */ 64/* Returns the name of the cipher. */
63const char *cipher_name(int cipher); 65const char *cipher_name(int cipher);
64 66
65/* Parses the name of the cipher. Returns the number of the corresponding 67/*
66 cipher, or -1 on error. */ 68 * Parses the name of the cipher. Returns the number of the corresponding
69 * cipher, or -1 on error.
70 */
67int cipher_number(const char *name); 71int cipher_number(const char *name);
68 72
69/* Selects the cipher to use and sets the key. If for_encryption is true, 73/*
70 the key is setup for encryption; otherwise it is setup for decryption. */ 74 * Selects the cipher to use and sets the key. If for_encryption is true,
75 * the key is setup for encryption; otherwise it is setup for decryption.
76 */
71void 77void
72cipher_set_key(CipherContext * context, int cipher, 78cipher_set_key(CipherContext * context, int cipher,
73 const unsigned char *key, int keylen, int for_encryption); 79 const unsigned char *key, int keylen, int for_encryption);
74 80
75/* Sets key for the cipher by computing the MD5 checksum of the passphrase, 81/*
76 and using the resulting 16 bytes as the key. */ 82 * Sets key for the cipher by computing the MD5 checksum of the passphrase,
83 * and using the resulting 16 bytes as the key.
84 */
77void 85void
78cipher_set_key_string(CipherContext * context, int cipher, 86cipher_set_key_string(CipherContext * context, int cipher,
79 const char *passphrase, int for_encryption); 87 const char *passphrase, int for_encryption);
@@ -88,8 +96,10 @@ void
88cipher_decrypt(CipherContext * context, unsigned char *dest, 96cipher_decrypt(CipherContext * context, unsigned char *dest,
89 const unsigned char *src, unsigned int len); 97 const unsigned char *src, unsigned int len);
90 98
91/* If and CRC-32 attack is detected this function is called. Defaults 99/*
92 * to fatal, changed to packet_disconnect in sshd and ssh. */ 100 * If and CRC-32 attack is detected this function is called. Defaults to
93extern void (*cipher_attack_detected) (const char *fmt,...); 101 * fatal, changed to packet_disconnect in sshd and ssh.
102 */
103extern void (*cipher_attack_detected) (const char *fmt, ...);
94 104
95#endif /* CIPHER_H */ 105#endif /* CIPHER_H */
diff --git a/clientloop.c b/clientloop.c
index c49346c2c..679180f58 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: clientloop.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); 18RCSID("$Id: clientloop.c,v 1.6 1999/11/25 00:54:58 damien Exp $");
19 19
20#include "xmalloc.h" 20#include "xmalloc.h"
21#include "ssh.h" 21#include "ssh.h"
@@ -27,22 +27,28 @@ RCSID("$Id: clientloop.c,v 1.5 1999/11/24 13:26:22 damien Exp $");
27/* Flag indicating that stdin should be redirected from /dev/null. */ 27/* Flag indicating that stdin should be redirected from /dev/null. */
28extern int stdin_null_flag; 28extern int stdin_null_flag;
29 29
30/* Name of the host we are connecting to. This is the name given on the 30/*
31 command line, or the HostName specified for the user-supplied name 31 * Name of the host we are connecting to. This is the name given on the
32 in a configuration file. */ 32 * command line, or the HostName specified for the user-supplied name in a
33 * configuration file.
34 */
33extern char *host; 35extern char *host;
34 36
35/* Flag to indicate that we have received a window change signal which has 37/*
36 not yet been processed. This will cause a message indicating the new 38 * Flag to indicate that we have received a window change signal which has
37 window size to be sent to the server a little later. This is volatile 39 * not yet been processed. This will cause a message indicating the new
38 because this is updated in a signal handler. */ 40 * window size to be sent to the server a little later. This is volatile
41 * because this is updated in a signal handler.
42 */
39static volatile int received_window_change_signal = 0; 43static volatile int received_window_change_signal = 0;
40 44
41/* Terminal modes, as saved by enter_raw_mode. */ 45/* Terminal modes, as saved by enter_raw_mode. */
42static struct termios saved_tio; 46static struct termios saved_tio;
43 47
44/* Flag indicating whether we are in raw mode. This is used by enter_raw_mode 48/*
45 and leave_raw_mode. */ 49 * Flag indicating whether we are in raw mode. This is used by
50 * enter_raw_mode and leave_raw_mode.
51 */
46static int in_raw_mode = 0; 52static int in_raw_mode = 0;
47 53
48/* Flag indicating whether the user\'s terminal is in non-blocking mode. */ 54/* Flag indicating whether the user\'s terminal is in non-blocking mode. */
@@ -64,8 +70,7 @@ static unsigned long stdin_bytes, stdout_bytes, stderr_bytes;
64static int quit_pending; /* Set to non-zero to quit the client loop. */ 70static int quit_pending; /* Set to non-zero to quit the client loop. */
65static int escape_char; /* Escape character. */ 71static int escape_char; /* Escape character. */
66 72
67/* Returns the user\'s terminal to normal mode if it had been put in raw 73/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */
68 mode. */
69 74
70void 75void
71leave_raw_mode() 76leave_raw_mode()
@@ -127,8 +132,10 @@ enter_non_blocking()
127 fatal_add_cleanup((void (*) (void *)) leave_non_blocking, NULL); 132 fatal_add_cleanup((void (*) (void *)) leave_non_blocking, NULL);
128} 133}
129 134
130/* Signal handler for the window change signal (SIGWINCH). This just 135/*
131 sets a flag indicating that the window has changed. */ 136 * Signal handler for the window change signal (SIGWINCH). This just sets a
137 * flag indicating that the window has changed.
138 */
132 139
133void 140void
134window_change_handler(int sig) 141window_change_handler(int sig)
@@ -137,8 +144,10 @@ window_change_handler(int sig)
137 signal(SIGWINCH, window_change_handler); 144 signal(SIGWINCH, window_change_handler);
138} 145}
139 146
140/* Signal handler for signals that cause the program to terminate. These 147/*
141 signals must be trapped to restore terminal modes. */ 148 * Signal handler for signals that cause the program to terminate. These
149 * signals must be trapped to restore terminal modes.
150 */
142 151
143void 152void
144signal_handler(int sig) 153signal_handler(int sig)
@@ -152,8 +161,10 @@ signal_handler(int sig)
152 fatal("Killed by signal %d.", sig); 161 fatal("Killed by signal %d.", sig);
153} 162}
154 163
155/* Returns current time in seconds from Jan 1, 1970 with the maximum available 164/*
156 resolution. */ 165 * Returns current time in seconds from Jan 1, 1970 with the maximum
166 * available resolution.
167 */
157 168
158double 169double
159get_current_time() 170get_current_time()
@@ -163,9 +174,11 @@ get_current_time()
163 return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; 174 return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
164} 175}
165 176
166/* This is called when the interactive is entered. This checks if there 177/*
167 is an EOF coming on stdin. We must check this explicitly, as select() 178 * This is called when the interactive is entered. This checks if there is
168 does not appear to wake up when redirecting from /dev/null. */ 179 * an EOF coming on stdin. We must check this explicitly, as select() does
180 * not appear to wake up when redirecting from /dev/null.
181 */
169 182
170void 183void
171client_check_initial_eof_on_stdin() 184client_check_initial_eof_on_stdin()
@@ -173,13 +186,14 @@ client_check_initial_eof_on_stdin()
173 int len; 186 int len;
174 char buf[1]; 187 char buf[1];
175 188
176 /* If standard input is to be "redirected from /dev/null", we 189 /*
177 simply mark that we have seen an EOF and send an EOF message to 190 * If standard input is to be "redirected from /dev/null", we simply
178 the server. Otherwise, we try to read a single character; it 191 * mark that we have seen an EOF and send an EOF message to the
179 appears that for some files, such /dev/null, select() never 192 * server. Otherwise, we try to read a single character; it appears
180 wakes up for read for this descriptor, which means that we 193 * that for some files, such /dev/null, select() never wakes up for
181 never get EOF. This way we will get the EOF if stdin comes 194 * read for this descriptor, which means that we never get EOF. This
182 from /dev/null or similar. */ 195 * way we will get the EOF if stdin comes from /dev/null or similar.
196 */
183 if (stdin_null_flag) { 197 if (stdin_null_flag) {
184 /* Fake EOF on stdin. */ 198 /* Fake EOF on stdin. */
185 debug("Sending eof."); 199 debug("Sending eof.");
@@ -187,22 +201,22 @@ client_check_initial_eof_on_stdin()
187 packet_start(SSH_CMSG_EOF); 201 packet_start(SSH_CMSG_EOF);
188 packet_send(); 202 packet_send();
189 } else { 203 } else {
190 /* Enter non-blocking mode for stdin. */
191 enter_non_blocking(); 204 enter_non_blocking();
192 205
193 /* Check for immediate EOF on stdin. */ 206 /* Check for immediate EOF on stdin. */
194 len = read(fileno(stdin), buf, 1); 207 len = read(fileno(stdin), buf, 1);
195 if (len == 0) { 208 if (len == 0) {
196 /* EOF. Record that we have seen it and send EOF 209 /* EOF. Record that we have seen it and send EOF to server. */
197 to server. */
198 debug("Sending eof."); 210 debug("Sending eof.");
199 stdin_eof = 1; 211 stdin_eof = 1;
200 packet_start(SSH_CMSG_EOF); 212 packet_start(SSH_CMSG_EOF);
201 packet_send(); 213 packet_send();
202 } else if (len > 0) { 214 } else if (len > 0) {
203 /* Got data. We must store the data in the 215 /*
204 buffer, and also process it as an escape 216 * Got data. We must store the data in the buffer,
205 character if appropriate. */ 217 * and also process it as an escape character if
218 * appropriate.
219 */
206 if ((unsigned char) buf[0] == escape_char) 220 if ((unsigned char) buf[0] == escape_char)
207 escape_pending = 1; 221 escape_pending = 1;
208 else { 222 else {
@@ -210,13 +224,14 @@ client_check_initial_eof_on_stdin()
210 stdin_bytes += 1; 224 stdin_bytes += 1;
211 } 225 }
212 } 226 }
213 /* Leave non-blocking mode. */
214 leave_non_blocking(); 227 leave_non_blocking();
215 } 228 }
216} 229}
217 230
218/* Get packets from the connection input buffer, and process them as long 231/*
219 as there are packets available. */ 232 * Get packets from the connection input buffer, and process them as long as
233 * there are packets available.
234 */
220 235
221void 236void
222client_process_buffered_input_packets() 237client_process_buffered_input_packets()
@@ -255,8 +270,10 @@ client_process_buffered_input_packets()
255 /* Acknowledge the exit. */ 270 /* Acknowledge the exit. */
256 packet_start(SSH_CMSG_EXIT_CONFIRMATION); 271 packet_start(SSH_CMSG_EXIT_CONFIRMATION);
257 packet_send(); 272 packet_send();
258 /* Must wait for packet to be sent since we are 273 /*
259 exiting the loop. */ 274 * Must wait for packet to be sent since we are
275 * exiting the loop.
276 */
260 packet_write_wait(); 277 packet_write_wait();
261 /* Flag that we want to exit. */ 278 /* Flag that we want to exit. */
262 quit_pending = 1; 279 quit_pending = 1;
@@ -300,20 +317,24 @@ client_process_buffered_input_packets()
300 break; 317 break;
301 318
302 default: 319 default:
303 /* Any unknown packets received during the actual 320 /*
304 session cause the session to terminate. This 321 * Any unknown packets received during the actual
305 is intended to make debugging easier since no 322 * session cause the session to terminate. This is
306 confirmations are sent. Any compatible 323 * intended to make debugging easier since no
307 protocol extensions must be negotiated during 324 * confirmations are sent. Any compatible protocol
308 the preparatory phase. */ 325 * extensions must be negotiated during the
326 * preparatory phase.
327 */
309 packet_disconnect("Protocol error during session: type %d", 328 packet_disconnect("Protocol error during session: type %d",
310 type); 329 type);
311 } 330 }
312 } 331 }
313} 332}
314 333
315/* Make packets from buffered stdin data, and buffer them for sending to 334/*
316 the connection. */ 335 * Make packets from buffered stdin data, and buffer them for sending to the
336 * connection.
337 */
317 338
318void 339void
319client_make_packets_from_stdin_data() 340client_make_packets_from_stdin_data()
@@ -339,10 +360,12 @@ client_make_packets_from_stdin_data()
339 } 360 }
340} 361}
341 362
342/* Checks if the client window has changed, and sends a packet about it to 363/*
343 the server if so. The actual change is detected elsewhere (by a software 364 * Checks if the client window has changed, and sends a packet about it to
344 interrupt on Unix); this just checks the flag and sends a message if 365 * the server if so. The actual change is detected elsewhere (by a software
345 appropriate. */ 366 * interrupt on Unix); this just checks the flag and sends a message if
367 * appropriate.
368 */
346 369
347void 370void
348client_check_window_change() 371client_check_window_change()
@@ -367,8 +390,10 @@ client_check_window_change()
367 } 390 }
368} 391}
369 392
370/* Waits until the client can do something (some data becomes available on 393/*
371 one of the file descriptors). */ 394 * Waits until the client can do something (some data becomes available on
395 * one of the file descriptors).
396 */
372 397
373void 398void
374client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) 399client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
@@ -382,8 +407,10 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
382 channel_not_very_much_buffered_data()) 407 channel_not_very_much_buffered_data())
383 FD_SET(connection_in, readset); 408 FD_SET(connection_in, readset);
384 409
385 /* Read from stdin, unless we have seen EOF or have very much 410 /*
386 buffered data to send to the server. */ 411 * Read from stdin, unless we have seen EOF or have very much
412 * buffered data to send to the server.
413 */
387 if (!stdin_eof && packet_not_very_much_data_to_write()) 414 if (!stdin_eof && packet_not_very_much_data_to_write())
388 FD_SET(fileno(stdin), readset); 415 FD_SET(fileno(stdin), readset);
389 416
@@ -408,13 +435,14 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
408 if (channel_max_fd() > max_fd) 435 if (channel_max_fd() > max_fd)
409 max_fd = channel_max_fd(); 436 max_fd = channel_max_fd();
410 437
411 /* Wait for something to happen. This will suspend the process 438 /*
412 until some selected descriptor can be read, written, or has 439 * Wait for something to happen. This will suspend the process until
413 some other event pending. 440 * some selected descriptor can be read, written, or has some other
414 Note: if you want to implement SSH_MSG_IGNORE messages to fool 441 * event pending. Note: if you want to implement SSH_MSG_IGNORE
415 traffic analysis, this might be the place to do it: 442 * messages to fool traffic analysis, this might be the place to do
416 just have a random timeout for the select, and send a random 443 * it: just have a random timeout for the select, and send a random
417 SSH_MSG_IGNORE packet when the timeout expires. */ 444 * SSH_MSG_IGNORE packet when the timeout expires.
445 */
418 446
419 if (select(max_fd + 1, readset, writeset, NULL, NULL) < 0) { 447 if (select(max_fd + 1, readset, writeset, NULL, NULL) < 0) {
420 char buf[100]; 448 char buf[100];
@@ -446,11 +474,12 @@ client_suspend_self()
446 buffer_ptr(&stderr_buffer), 474 buffer_ptr(&stderr_buffer),
447 buffer_len(&stderr_buffer)); 475 buffer_len(&stderr_buffer));
448 476
449 /* Leave raw mode. */
450 leave_raw_mode(); 477 leave_raw_mode();
451 478
452 /* Free (and clear) the buffer to reduce the amount of data that 479 /*
453 gets written to swap. */ 480 * Free (and clear) the buffer to reduce the amount of data that gets
481 * written to swap.
482 */
454 buffer_free(&stdin_buffer); 483 buffer_free(&stdin_buffer);
455 buffer_free(&stdout_buffer); 484 buffer_free(&stdout_buffer);
456 buffer_free(&stderr_buffer); 485 buffer_free(&stderr_buffer);
@@ -474,7 +503,6 @@ client_suspend_self()
474 buffer_init(&stdout_buffer); 503 buffer_init(&stdout_buffer);
475 buffer_init(&stderr_buffer); 504 buffer_init(&stderr_buffer);
476 505
477 /* Re-enter raw mode. */
478 enter_raw_mode(); 506 enter_raw_mode();
479} 507}
480 508
@@ -484,8 +512,10 @@ client_process_input(fd_set * readset)
484 int len, pid; 512 int len, pid;
485 char buf[8192], *s; 513 char buf[8192], *s;
486 514
487 /* Read input from the server, and add any such data to the buffer 515 /*
488 of the packet subsystem. */ 516 * Read input from the server, and add any such data to the buffer of
517 * the packet subsystem.
518 */
489 if (FD_ISSET(connection_in, readset)) { 519 if (FD_ISSET(connection_in, readset)) {
490 /* Read as much as possible. */ 520 /* Read as much as possible. */
491 len = read(connection_in, buf, sizeof(buf)); 521 len = read(connection_in, buf, sizeof(buf));
@@ -498,9 +528,10 @@ client_process_input(fd_set * readset)
498 quit_pending = 1; 528 quit_pending = 1;
499 return; 529 return;
500 } 530 }
501 /* There is a kernel bug on Solaris that causes select to 531 /*
502 sometimes wake up even though there is no data 532 * There is a kernel bug on Solaris that causes select to
503 available. */ 533 * sometimes wake up even though there is no data available.
534 */
504 if (len < 0 && errno == EAGAIN) 535 if (len < 0 && errno == EAGAIN)
505 len = 0; 536 len = 0;
506 537
@@ -520,9 +551,11 @@ client_process_input(fd_set * readset)
520 /* Read as much as possible. */ 551 /* Read as much as possible. */
521 len = read(fileno(stdin), buf, sizeof(buf)); 552 len = read(fileno(stdin), buf, sizeof(buf));
522 if (len <= 0) { 553 if (len <= 0) {
523 /* Received EOF or error. They are treated 554 /*
524 similarly, except that an error message is 555 * Received EOF or error. They are treated
525 printed if it was an error condition. */ 556 * similarly, except that an error message is printed
557 * if it was an error condition.
558 */
526 if (len < 0) { 559 if (len < 0) {
527 snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); 560 snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno));
528 buffer_append(&stderr_buffer, buf, strlen(buf)); 561 buffer_append(&stderr_buffer, buf, strlen(buf));
@@ -530,32 +563,35 @@ client_process_input(fd_set * readset)
530 } 563 }
531 /* Mark that we have seen EOF. */ 564 /* Mark that we have seen EOF. */
532 stdin_eof = 1; 565 stdin_eof = 1;
533 /* Send an EOF message to the server unless there 566 /*
534 is data in the buffer. If there is data in the 567 * Send an EOF message to the server unless there is
535 buffer, no message will be sent now. Code 568 * data in the buffer. If there is data in the
536 elsewhere will send the EOF when the buffer 569 * buffer, no message will be sent now. Code
537 becomes empty if stdin_eof is set. */ 570 * elsewhere will send the EOF when the buffer
571 * becomes empty if stdin_eof is set.
572 */
538 if (buffer_len(&stdin_buffer) == 0) { 573 if (buffer_len(&stdin_buffer) == 0) {
539 packet_start(SSH_CMSG_EOF); 574 packet_start(SSH_CMSG_EOF);
540 packet_send(); 575 packet_send();
541 } 576 }
542 } else if (escape_char == -1) { 577 } else if (escape_char == -1) {
543 /* Normal successful read, and no escape 578 /*
544 character. Just append the data to buffer. */ 579 * Normal successful read, and no escape character.
580 * Just append the data to buffer.
581 */
545 buffer_append(&stdin_buffer, buf, len); 582 buffer_append(&stdin_buffer, buf, len);
546 stdin_bytes += len; 583 stdin_bytes += len;
547 } else { 584 } else {
548 /* Normal, successful read. But we have an escape 585 /*
549 character and have to process the characters 586 * Normal, successful read. But we have an escape character
550 one by one. */ 587 * and have to process the characters one by one.
588 */
551 unsigned int i; 589 unsigned int i;
552 for (i = 0; i < len; i++) { 590 for (i = 0; i < len; i++) {
553 unsigned char ch; 591 unsigned char ch;
554 /* Get one character at a time. */ 592 /* Get one character at a time. */
555 ch = buf[i]; 593 ch = buf[i];
556 594
557 /* Check if we have a pending escape
558 character. */
559 if (escape_pending) { 595 if (escape_pending) {
560 /* We have previously seen an escape character. */ 596 /* We have previously seen an escape character. */
561 /* Clear the flag now. */ 597 /* Clear the flag now. */
@@ -584,12 +620,16 @@ client_process_input(fd_set * readset)
584 continue; 620 continue;
585 621
586 case '&': 622 case '&':
587 /* Detach the program (continue to serve connections, 623 /*
588 but put in background and no more new connections). */ 624 * Detach the program (continue to serve connections,
625 * but put in background and no more new connections).
626 */
589 if (!stdin_eof) { 627 if (!stdin_eof) {
590 /* Sending SSH_CMSG_EOF alone does not always appear 628 /*
591 to be enough. So we try to send an EOF character 629 * Sending SSH_CMSG_EOF alone does not always appear
592 first. */ 630 * to be enough. So we try to send an EOF character
631 * first.
632 */
593 packet_start(SSH_CMSG_STDIN_DATA); 633 packet_start(SSH_CMSG_STDIN_DATA);
594 packet_put_string("\004", 1); 634 packet_put_string("\004", 1);
595 packet_send(); 635 packet_send();
@@ -646,22 +686,28 @@ Supported escape sequences:\r\n\
646 686
647 default: 687 default:
648 if (ch != escape_char) { 688 if (ch != escape_char) {
649 /* Escape character followed by non-special character. 689 /*
650 Append both to the input buffer. */ 690 * Escape character followed by non-special character.
691 * Append both to the input buffer.
692 */
651 buf[0] = escape_char; 693 buf[0] = escape_char;
652 buf[1] = ch; 694 buf[1] = ch;
653 buffer_append(&stdin_buffer, buf, 2); 695 buffer_append(&stdin_buffer, buf, 2);
654 stdin_bytes += 2; 696 stdin_bytes += 2;
655 continue; 697 continue;
656 } 698 }
657 /* Note that escape character typed twice 699 /*
658 falls through here; the latter gets processed 700 * Note that escape character typed twice
659 as a normal character below. */ 701 * falls through here; the latter gets processed
702 * as a normal character below.
703 */
660 break; 704 break;
661 } 705 }
662 } else { 706 } else {
663 /* The previous character was not an escape char. Check if this 707 /*
664 is an escape. */ 708 * The previous character was not an escape char. Check if this
709 * is an escape.
710 */
665 if (last_was_cr && ch == escape_char) { 711 if (last_was_cr && ch == escape_char) {
666 /* It is. Set the flag and continue to next character. */ 712 /* It is. Set the flag and continue to next character. */
667 escape_pending = 1; 713 escape_pending = 1;
@@ -669,8 +715,10 @@ Supported escape sequences:\r\n\
669 } 715 }
670 } 716 }
671 717
672 /* Normal character. Record whether it was a newline, and append it to the 718 /*
673 buffer. */ 719 * Normal character. Record whether it was a newline,
720 * and append it to the buffer.
721 */
674 last_was_cr = (ch == '\r' || ch == '\n'); 722 last_was_cr = (ch == '\r' || ch == '\n');
675 buf[0] = ch; 723 buf[0] = ch;
676 buffer_append(&stdin_buffer, buf, 1); 724 buffer_append(&stdin_buffer, buf, 1);
@@ -696,8 +744,10 @@ client_process_output(fd_set * writeset)
696 if (errno == EAGAIN) 744 if (errno == EAGAIN)
697 len = 0; 745 len = 0;
698 else { 746 else {
699 /* An error or EOF was encountered. Put 747 /*
700 an error message to stderr buffer. */ 748 * An error or EOF was encountered. Put an
749 * error message to stderr buffer.
750 */
701 snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); 751 snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno));
702 buffer_append(&stderr_buffer, buf, strlen(buf)); 752 buffer_append(&stderr_buffer, buf, strlen(buf));
703 stderr_bytes += strlen(buf); 753 stderr_bytes += strlen(buf);
@@ -717,8 +767,7 @@ client_process_output(fd_set * writeset)
717 if (errno == EAGAIN) 767 if (errno == EAGAIN)
718 len = 0; 768 len = 0;
719 else { 769 else {
720 /* EOF or error, but can't even print 770 /* EOF or error, but can't even print error message. */
721 error message. */
722 quit_pending = 1; 771 quit_pending = 1;
723 return; 772 return;
724 } 773 }
@@ -728,11 +777,12 @@ client_process_output(fd_set * writeset)
728 } 777 }
729} 778}
730 779
731/* Implements the interactive session with the server. This is called 780/*
732 after the user has been authenticated, and a command has been 781 * Implements the interactive session with the server. This is called after
733 started on the remote host. If escape_char != -1, it is the character 782 * the user has been authenticated, and a command has been started on the
734 used as an escape character for terminating or suspending the 783 * remote host. If escape_char != -1, it is the character used as an escape
735 session. */ 784 * character for terminating or suspending the session.
785 */
736 786
737int 787int
738client_loop(int have_pty, int escape_char_arg) 788client_loop(int have_pty, int escape_char_arg)
@@ -776,7 +826,6 @@ client_loop(int have_pty, int escape_char_arg)
776 if (have_pty) 826 if (have_pty)
777 signal(SIGWINCH, window_change_handler); 827 signal(SIGWINCH, window_change_handler);
778 828
779 /* Enter raw mode if have a pseudo terminal. */
780 if (have_pty) 829 if (have_pty)
781 enter_raw_mode(); 830 enter_raw_mode();
782 831
@@ -787,27 +836,35 @@ client_loop(int have_pty, int escape_char_arg)
787 while (!quit_pending) { 836 while (!quit_pending) {
788 fd_set readset, writeset; 837 fd_set readset, writeset;
789 838
790 /* Precess buffered packets sent by the server. */ 839 /* Process buffered packets sent by the server. */
791 client_process_buffered_input_packets(); 840 client_process_buffered_input_packets();
792 841
793 /* Make packets of buffered stdin data, and buffer them 842 /*
794 for sending to the server. */ 843 * Make packets of buffered stdin data, and buffer them for
844 * sending to the server.
845 */
795 client_make_packets_from_stdin_data(); 846 client_make_packets_from_stdin_data();
796 847
797 /* Make packets from buffered channel data, and buffer 848 /*
798 them for sending to the server. */ 849 * Make packets from buffered channel data, and buffer them
850 * for sending to the server.
851 */
799 if (packet_not_very_much_data_to_write()) 852 if (packet_not_very_much_data_to_write())
800 channel_output_poll(); 853 channel_output_poll();
801 854
802 /* Check if the window size has changed, and buffer a 855 /*
803 message about it to the server if so. */ 856 * Check if the window size has changed, and buffer a message
857 * about it to the server if so.
858 */
804 client_check_window_change(); 859 client_check_window_change();
805 860
806 if (quit_pending) 861 if (quit_pending)
807 break; 862 break;
808 863
809 /* Wait until we have something to do (something becomes 864 /*
810 available on one of the descriptors). */ 865 * Wait until we have something to do (something becomes
866 * available on one of the descriptors).
867 */
811 client_wait_until_can_do_something(&readset, &writeset); 868 client_wait_until_can_do_something(&readset, &writeset);
812 869
813 if (quit_pending) 870 if (quit_pending)
@@ -816,16 +873,19 @@ client_loop(int have_pty, int escape_char_arg)
816 /* Do channel operations. */ 873 /* Do channel operations. */
817 channel_after_select(&readset, &writeset); 874 channel_after_select(&readset, &writeset);
818 875
819 /* Process input from the connection and from stdin. 876 /*
820 Buffer any data that is available. */ 877 * Process input from the connection and from stdin. Buffer
878 * any data that is available.
879 */
821 client_process_input(&readset); 880 client_process_input(&readset);
822 881
823 /* Process output to stdout and stderr. Output to the 882 /*
824 connection is processed elsewhere (above). */ 883 * Process output to stdout and stderr. Output to the
884 * connection is processed elsewhere (above).
885 */
825 client_process_output(&writeset); 886 client_process_output(&writeset);
826 887
827 /* Send as much buffered packet data as possible to the 888 /* Send as much buffered packet data as possible to the sender. */
828 sender. */
829 if (FD_ISSET(connection_out, &writeset)) 889 if (FD_ISSET(connection_out, &writeset))
830 packet_write_poll(); 890 packet_write_poll();
831 } 891 }
@@ -839,8 +899,10 @@ client_loop(int have_pty, int escape_char_arg)
839 /* Stop listening for connections. */ 899 /* Stop listening for connections. */
840 channel_stop_listening(); 900 channel_stop_listening();
841 901
842 /* In interactive mode (with pseudo tty) display a message 902 /*
843 indicating that the connection has been closed. */ 903 * In interactive mode (with pseudo tty) display a message indicating
904 * that the connection has been closed.
905 */
844 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { 906 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
845 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); 907 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
846 buffer_append(&stderr_buffer, buf, strlen(buf)); 908 buffer_append(&stderr_buffer, buf, strlen(buf));
@@ -868,7 +930,6 @@ client_loop(int have_pty, int escape_char_arg)
868 buffer_consume(&stderr_buffer, len); 930 buffer_consume(&stderr_buffer, len);
869 } 931 }
870 932
871 /* Leave raw mode. */
872 if (have_pty) 933 if (have_pty)
873 leave_raw_mode(); 934 leave_raw_mode();
874 935
diff --git a/compat.c b/compat.c
index 0935154c7..d39a3d6f7 100644
--- a/compat.c
+++ b/compat.c
@@ -1,5 +1,34 @@
1/*
2 * Copyright (c) 1999 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
1#include "includes.h" 30#include "includes.h"
2RCSID("$Id: compat.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); 31RCSID("$Id: compat.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
3 32
4#include "ssh.h" 33#include "ssh.h"
5 34
diff --git a/compat.h b/compat.h
index 4f6c10ff6..4f53607f3 100644
--- a/compat.h
+++ b/compat.h
@@ -1,4 +1,32 @@
1/* RCSID("$Id: compat.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ 1/*
2 * Copyright (c) 1999 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29/* RCSID("$Id: compat.h,v 1.3 1999/11/25 00:54:59 damien Exp $"); */
2 30
3#ifndef COMPAT_H 31#ifndef COMPAT_H
4#define COMPAT_H 32#define COMPAT_H
diff --git a/compress.c b/compress.c
index 463e7374e..544811c19 100644
--- a/compress.c
+++ b/compress.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: compress.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); 17RCSID("$Id: compress.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "buffer.h" 20#include "buffer.h"
@@ -23,8 +23,10 @@ RCSID("$Id: compress.c,v 1.2 1999/11/24 13:26:22 damien Exp $");
23static z_stream incoming_stream; 23static z_stream incoming_stream;
24static z_stream outgoing_stream; 24static z_stream outgoing_stream;
25 25
26/* Initializes compression; level is compression level from 1 to 9 26/*
27 (as in gzip). */ 27 * Initializes compression; level is compression level from 1 to 9
28 * (as in gzip).
29 */
28 30
29void 31void
30buffer_compress_init(int level) 32buffer_compress_init(int level)
@@ -53,13 +55,14 @@ buffer_compress_uninit()
53 deflateEnd(&outgoing_stream); 55 deflateEnd(&outgoing_stream);
54} 56}
55 57
56/* Compresses the contents of input_buffer into output_buffer. All 58/*
57 packets compressed using this function will form a single 59 * Compresses the contents of input_buffer into output_buffer. All packets
58 compressed data stream; however, data will be flushed at the end of 60 * compressed using this function will form a single compressed data stream;
59 every call so that each output_buffer can be decompressed 61 * however, data will be flushed at the end of every call so that each
60 independently (but in the appropriate order since they together 62 * output_buffer can be decompressed independently (but in the appropriate
61 form a single compression stream) by the receiver. This appends 63 * order since they together form a single compression stream) by the
62 the compressed data to the output buffer. */ 64 * receiver. This appends the compressed data to the output buffer.
65 */
63 66
64void 67void
65buffer_compress(Buffer * input_buffer, Buffer * output_buffer) 68buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
@@ -106,13 +109,14 @@ buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
106 while (outgoing_stream.avail_out == 0); 109 while (outgoing_stream.avail_out == 0);
107} 110}
108 111
109/* Uncompresses the contents of input_buffer into output_buffer. All 112/*
110 packets uncompressed using this function will form a single 113 * Uncompresses the contents of input_buffer into output_buffer. All packets
111 compressed data stream; however, data will be flushed at the end of 114 * uncompressed using this function will form a single compressed data
112 every call so that each output_buffer. This must be called for the 115 * stream; however, data will be flushed at the end of every call so that
113 same size units that the buffer_compress was called, and in the 116 * each output_buffer. This must be called for the same size units that the
114 same order that buffers compressed with that. This appends the 117 * buffer_compress was called, and in the same order that buffers compressed
115 uncompressed data to the output buffer. */ 118 * with that. This appends the uncompressed data to the output buffer.
119 */
116 120
117void 121void
118buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer) 122buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
@@ -145,9 +149,11 @@ buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
145 fatal("buffer_uncompress: inflate returned Z_STREAM_ERROR"); 149 fatal("buffer_uncompress: inflate returned Z_STREAM_ERROR");
146 /* NOTREACHED */ 150 /* NOTREACHED */
147 case Z_BUF_ERROR: 151 case Z_BUF_ERROR:
148 /* Comments in zlib.h say that we should keep 152 /*
149 calling inflate() until we get an error. This 153 * Comments in zlib.h say that we should keep calling
150 appears to be the error that we get. */ 154 * inflate() until we get an error. This appears to
155 * be the error that we get.
156 */
151 return; 157 return;
152 case Z_MEM_ERROR: 158 case Z_MEM_ERROR:
153 fatal("buffer_uncompress: inflate returned Z_MEM_ERROR"); 159 fatal("buffer_uncompress: inflate returned Z_MEM_ERROR");
diff --git a/compress.h b/compress.h
index e028f71a5..41279a0bd 100644
--- a/compress.h
+++ b/compress.h
@@ -13,34 +13,38 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: compress.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: compress.h,v 1.3 1999/11/25 00:54:59 damien Exp $"); */
17 17
18#ifndef COMPRESS_H 18#ifndef COMPRESS_H
19#define COMPRESS_H 19#define COMPRESS_H
20 20
21/* Initializes compression; level is compression level from 1 to 9 (as in 21/*
22 gzip). */ 22 * Initializes compression; level is compression level from 1 to 9 (as in
23 * gzip).
24 */
23void buffer_compress_init(int level); 25void buffer_compress_init(int level);
24 26
25/* Frees any data structures allocated by buffer_compress_init. */ 27/* Frees any data structures allocated by buffer_compress_init. */
26void buffer_compress_uninit(); 28void buffer_compress_uninit();
27 29
28/* Compresses the contents of input_buffer into output_buffer. All 30/*
29 packets compressed using this function will form a single 31 * Compresses the contents of input_buffer into output_buffer. All packets
30 compressed data stream; however, data will be flushed at the end of 32 * compressed using this function will form a single compressed data stream;
31 every call so that each output_buffer can be decompressed 33 * however, data will be flushed at the end of every call so that each
32 independently (but in the appropriate order since they together 34 * output_buffer can be decompressed independently (but in the appropriate
33 form a single compression stream) by the receiver. This appends 35 * order since they together form a single compression stream) by the
34 the compressed data to the output buffer. */ 36 * receiver. This appends the compressed data to the output buffer.
37 */
35void buffer_compress(Buffer * input_buffer, Buffer * output_buffer); 38void buffer_compress(Buffer * input_buffer, Buffer * output_buffer);
36 39
37/* Uncompresses the contents of input_buffer into output_buffer. All 40/*
38 packets uncompressed using this function will form a single 41 * Uncompresses the contents of input_buffer into output_buffer. All packets
39 compressed data stream; however, data will be flushed at the end of 42 * uncompressed using this function will form a single compressed data
40 every call so that each output_buffer. This must be called for the 43 * stream; however, data will be flushed at the end of every call so that
41 same size units that the buffer_compress was called, and in the 44 * each output_buffer. This must be called for the same size units that the
42 same order that buffers compressed with that. This appends the 45 * buffer_compress was called, and in the same order that buffers compressed
43 uncompressed data to the output buffer. */ 46 * with that. This appends the uncompressed data to the output buffer.
47 */
44void buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer); 48void buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer);
45 49
46#endif /* COMPRESS_H */ 50#endif /* COMPRESS_H */
diff --git a/crc32.h b/crc32.h
index 6aa3aa620..d20a8ab15 100644
--- a/crc32.h
+++ b/crc32.h
@@ -13,13 +13,15 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: crc32.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: crc32.h,v 1.3 1999/11/25 00:54:59 damien Exp $"); */
17 17
18#ifndef CRC32_H 18#ifndef CRC32_H
19#define CRC32_H 19#define CRC32_H
20 20
21/* This computes a 32 bit CRC of the data in the buffer, and returns the 21/*
22 CRC. The polynomial used is 0xedb88320. */ 22 * This computes a 32 bit CRC of the data in the buffer, and returns the CRC.
23 * The polynomial used is 0xedb88320.
24 */
23unsigned int crc32(const unsigned char *buf, unsigned int len); 25unsigned int crc32(const unsigned char *buf, unsigned int len);
24 26
25#endif /* CRC32_H */ 27#endif /* CRC32_H */
diff --git a/fingerprint.c b/fingerprint.c
index 54fc7e9b0..f032a5144 100644
--- a/fingerprint.c
+++ b/fingerprint.c
@@ -1,5 +1,34 @@
1/*
2 * Copyright (c) 1999 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
1#include "includes.h" 30#include "includes.h"
2RCSID("$Id: fingerprint.c,v 1.3 1999/11/24 00:26:01 deraadt Exp $"); 31RCSID("$Id: fingerprint.c,v 1.4 1999/11/24 16:15:25 markus Exp $");
3 32
4#include "ssh.h" 33#include "ssh.h"
5#include "xmalloc.h" 34#include "xmalloc.h"
diff --git a/fingerprint.h b/fingerprint.h
index 8c603aa16..fbb0d4c46 100644
--- a/fingerprint.h
+++ b/fingerprint.h
@@ -1,4 +1,32 @@
1/* RCSID("$Id: fingerprint.h,v 1.2 1999/11/24 00:26:02 deraadt Exp $"); */ 1/*
2 * Copyright (c) 1999 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29/* RCSID("$Id: fingerprint.h,v 1.3 1999/11/24 16:15:25 markus Exp $"); */
2 30
3#ifndef FINGERPRINT_H 31#ifndef FINGERPRINT_H
4#define FINGERPRINT_H 32#define FINGERPRINT_H
diff --git a/hostfile.c b/hostfile.c
index 61046f071..cdfb48f3e 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -14,16 +14,18 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: hostfile.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); 17RCSID("$Id: hostfile.c,v 1.6 1999/11/25 00:54:59 damien Exp $");
18 18
19#include "packet.h" 19#include "packet.h"
20#include "ssh.h" 20#include "ssh.h"
21 21
22/* Reads a multiple-precision integer in hex from the buffer, and advances the 22/*
23 pointer. The integer must already be initialized. This function is 23 * Reads a multiple-precision integer in hex from the buffer, and advances
24 permitted to modify the buffer. This leaves *cpp to point just beyond 24 * the pointer. The integer must already be initialized. This function is
25 the last processed (and maybe modified) character. Note that this may 25 * permitted to modify the buffer. This leaves *cpp to point just beyond the
26 modify the buffer containing the number. */ 26 * last processed (and maybe modified) character. Note that this may modify
27 * the buffer containing the number.
28 */
27 29
28int 30int
29auth_rsa_read_bignum(char **cpp, BIGNUM * value) 31auth_rsa_read_bignum(char **cpp, BIGNUM * value)
@@ -32,7 +34,8 @@ auth_rsa_read_bignum(char **cpp, BIGNUM * value)
32 int len, old; 34 int len, old;
33 35
34 /* Skip any leading whitespace. */ 36 /* Skip any leading whitespace. */
35 for (; *cp == ' ' || *cp == '\t'; cp++); 37 for (; *cp == ' ' || *cp == '\t'; cp++)
38 ;
36 39
37 /* Check that it begins with a hex digit. */ 40 /* Check that it begins with a hex digit. */
38 if (*cp < '0' || *cp > '9') 41 if (*cp < '0' || *cp > '9')
@@ -42,7 +45,8 @@ auth_rsa_read_bignum(char **cpp, BIGNUM * value)
42 *cpp = cp; 45 *cpp = cp;
43 46
44 /* Move forward until all hex digits skipped. */ 47 /* Move forward until all hex digits skipped. */
45 for (; *cp >= '0' && *cp <= '9'; cp++); 48 for (; *cp >= '0' && *cp <= '9'; cp++)
49 ;
46 50
47 /* Compute the length of the hex number. */ 51 /* Compute the length of the hex number. */
48 len = cp - *cpp; 52 len = cp - *cpp;
@@ -51,7 +55,6 @@ auth_rsa_read_bignum(char **cpp, BIGNUM * value)
51 old = *cp; 55 old = *cp;
52 *cp = 0; 56 *cp = 0;
53 57
54
55 /* Parse the number. */ 58 /* Parse the number. */
56 if (BN_dec2bn(&value, *cpp) == 0) 59 if (BN_dec2bn(&value, *cpp) == 0)
57 return 0; 60 return 0;
@@ -64,8 +67,10 @@ auth_rsa_read_bignum(char **cpp, BIGNUM * value)
64 return 1; 67 return 1;
65} 68}
66 69
67/* Parses an RSA key (number of bits, e, n) from a string. Moves the pointer 70/*
68 over the key. Skips any whitespace at the beginning and at end. */ 71 * Parses an RSA key (number of bits, e, n) from a string. Moves the pointer
72 * over the key. Skips any whitespace at the beginning and at end.
73 */
69 74
70int 75int
71auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n) 76auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
@@ -74,7 +79,8 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
74 char *cp; 79 char *cp;
75 80
76 /* Skip leading whitespace. */ 81 /* Skip leading whitespace. */
77 for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++); 82 for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
83 ;
78 84
79 /* Get number of bits. */ 85 /* Get number of bits. */
80 if (*cp < '0' || *cp > '9') 86 if (*cp < '0' || *cp > '9')
@@ -91,7 +97,8 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
91 return 0; 97 return 0;
92 98
93 /* Skip trailing whitespace. */ 99 /* Skip trailing whitespace. */
94 for (; *cp == ' ' || *cp == '\t'; cp++); 100 for (; *cp == ' ' || *cp == '\t'; cp++)
101 ;
95 102
96 /* Return results. */ 103 /* Return results. */
97 *cpp = cp; 104 *cpp = cp;
@@ -99,10 +106,12 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
99 return 1; 106 return 1;
100} 107}
101 108
102/* Tries to match the host name (which must be in all lowercase) against the 109/*
103 comma-separated sequence of subpatterns (each possibly preceded by ! to 110 * Tries to match the host name (which must be in all lowercase) against the
104 indicate negation). Returns true if there is a positive match; zero 111 * comma-separated sequence of subpatterns (each possibly preceded by ! to
105 otherwise. */ 112 * indicate negation). Returns true if there is a positive match; zero
113 * otherwise.
114 */
106 115
107int 116int
108match_hostname(const char *host, const char *pattern, unsigned int len) 117match_hostname(const char *host, const char *pattern, unsigned int len)
@@ -121,18 +130,19 @@ match_hostname(const char *host, const char *pattern, unsigned int len)
121 } else 130 } else
122 negated = 0; 131 negated = 0;
123 132
124 /* Extract the subpattern up to a comma or end. Convert 133 /*
125 the subpattern to lowercase. */ 134 * Extract the subpattern up to a comma or end. Convert the
135 * subpattern to lowercase.
136 */
126 for (subi = 0; 137 for (subi = 0;
127 i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; 138 i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
128 subi++, i++) 139 subi++, i++)
129 sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i]; 140 sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i];
130 /* If subpattern too long, return failure (no match). */ 141 /* If subpattern too long, return failure (no match). */
131 if (subi >= sizeof(sub) - 1) 142 if (subi >= sizeof(sub) - 1)
132 return 0; 143 return 0;
133 144
134 /* If the subpattern was terminated by a comma, skip the 145 /* If the subpattern was terminated by a comma, skip the comma. */
135 comma. */
136 if (i < len && pattern[i] == ',') 146 if (i < len && pattern[i] == ',')
137 i++; 147 i++;
138 148
@@ -142,24 +152,25 @@ match_hostname(const char *host, const char *pattern, unsigned int len)
142 /* Try to match the subpattern against the host name. */ 152 /* Try to match the subpattern against the host name. */
143 if (match_pattern(host, sub)) { 153 if (match_pattern(host, sub)) {
144 if (negated) 154 if (negated)
145 return 0; /* Fail if host matches 155 return 0; /* Fail */
146 any negated subpattern. */
147 else 156 else
148 got_positive = 1; 157 got_positive = 1;
149 } 158 }
150 } 159 }
151 160
152 /* Return success if got a positive match. If there was a 161 /*
153 negative match, we have already returned zero and never get 162 * Return success if got a positive match. If there was a negative
154 here. */ 163 * match, we have already returned zero and never get here.
164 */
155 return got_positive; 165 return got_positive;
156} 166}
157 167
158/* Checks whether the given host (which must be in all lowercase) is 168/*
159 already in the list of our known hosts. 169 * Checks whether the given host (which must be in all lowercase) is already
160 Returns HOST_OK if the host is known and has the specified key, 170 * in the list of our known hosts. Returns HOST_OK if the host is known and
161 HOST_NEW if the host is not known, and HOST_CHANGED if the host is known 171 * has the specified key, HOST_NEW if the host is not known, and HOST_CHANGED
162 but used to have a different host key. */ 172 * if the host is known but used to have a different host key.
173 */
163 174
164HostStatus 175HostStatus
165check_host_in_hostfile(const char *filename, const char *host, 176check_host_in_hostfile(const char *filename, const char *host,
@@ -180,9 +191,11 @@ check_host_in_hostfile(const char *filename, const char *host,
180 /* Cache the length of the host name. */ 191 /* Cache the length of the host name. */
181 hostlen = strlen(host); 192 hostlen = strlen(host);
182 193
183 /* Return value when the loop terminates. This is set to 194 /*
184 HOST_CHANGED if we have seen a different key for the host and 195 * Return value when the loop terminates. This is set to
185 have not found the proper one. */ 196 * HOST_CHANGED if we have seen a different key for the host and have
197 * not found the proper one.
198 */
186 end_return = HOST_NEW; 199 end_return = HOST_NEW;
187 200
188 /* size of modulus 'n' */ 201 /* size of modulus 'n' */
@@ -193,15 +206,15 @@ check_host_in_hostfile(const char *filename, const char *host,
193 cp = line; 206 cp = line;
194 linenum++; 207 linenum++;
195 208
196 /* Skip any leading whitespace. */ 209 /* Skip any leading whitespace, comments and empty lines. */
197 for (; *cp == ' ' || *cp == '\t'; cp++); 210 for (; *cp == ' ' || *cp == '\t'; cp++)
198 211 ;
199 /* Ignore comment lines and empty lines. */
200 if (!*cp || *cp == '#' || *cp == '\n') 212 if (!*cp || *cp == '#' || *cp == '\n')
201 continue; 213 continue;
202 214
203 /* Find the end of the host name portion. */ 215 /* Find the end of the host name portion. */
204 for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++); 216 for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
217 ;
205 218
206 /* Check if the host name matches. */ 219 /* Check if the host name matches. */
207 if (!match_hostname(host, cp, (unsigned int) (cp2 - cp))) 220 if (!match_hostname(host, cp, (unsigned int) (cp2 - cp)))
@@ -210,8 +223,10 @@ check_host_in_hostfile(const char *filename, const char *host,
210 /* Got a match. Skip host name. */ 223 /* Got a match. Skip host name. */
211 cp = cp2; 224 cp = cp2;
212 225
213 /* Extract the key from the line. This will skip any 226 /*
214 leading whitespace. Ignore badly formatted lines. */ 227 * Extract the key from the line. This will skip any leading
228 * whitespace. Ignore badly formatted lines.
229 */
215 if (!auth_rsa_read_key(&cp, &kbits, ke, kn)) 230 if (!auth_rsa_read_key(&cp, &kbits, ke, kn))
216 continue; 231 continue;
217 232
@@ -228,21 +243,27 @@ check_host_in_hostfile(const char *filename, const char *host,
228 fclose(f); 243 fclose(f);
229 return HOST_OK; 244 return HOST_OK;
230 } 245 }
231 /* They do not match. We will continue to go through the 246 /*
232 file; however, we note that we will not return that it 247 * They do not match. We will continue to go through the
233 is new. */ 248 * file; however, we note that we will not return that it is
249 * new.
250 */
234 end_return = HOST_CHANGED; 251 end_return = HOST_CHANGED;
235 } 252 }
236 /* Clear variables and close the file. */ 253 /* Clear variables and close the file. */
237 fclose(f); 254 fclose(f);
238 255
239 /* Return either HOST_NEW or HOST_CHANGED, depending on whether we 256 /*
240 saw a different key for the host. */ 257 * Return either HOST_NEW or HOST_CHANGED, depending on whether we
258 * saw a different key for the host.
259 */
241 return end_return; 260 return end_return;
242} 261}
243 262
244/* Appends an entry to the host file. Returns false if the entry 263/*
245 could not be appended. */ 264 * Appends an entry to the host file. Returns false if the entry could not
265 * be appended.
266 */
246 267
247int 268int
248add_host_to_hostfile(const char *filename, const char *host, 269add_host_to_hostfile(const char *filename, const char *host,
diff --git a/includes.h b/includes.h
index 4a2539696..a198597bc 100644
--- a/includes.h
+++ b/includes.h
@@ -87,8 +87,10 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
87#define _PATH_RSH "/usr/bin/rsh" 87#define _PATH_RSH "/usr/bin/rsh"
88#endif /* _PATH_RSH */ 88#endif /* _PATH_RSH */
89 89
90/* Define this to use pipes instead of socketpairs for communicating with the 90/*
91 client program. Socketpairs do not seem to work on all systems. */ 91 * Define this to use pipes instead of socketpairs for communicating with the
92 * client program. Socketpairs do not seem to work on all systems.
93 */
92#define USE_PIPES 1 94#define USE_PIPES 1
93 95
94#endif /* INCLUDES_H */ 96#endif /* INCLUDES_H */
diff --git a/log.c b/log.c
index e7052115e..837a670de 100644
--- a/log.c
+++ b/log.c
@@ -1,11 +1,9 @@
1/* 1/*
2 *
3 * Shared versions of debug(), log(), etc. 2 * Shared versions of debug(), log(), etc.
4 * 3 */
5*/
6 4
7#include "includes.h" 5#include "includes.h"
8RCSID("$OpenBSD: log.c,v 1.5 1999/11/24 00:26:02 deraadt Exp $"); 6RCSID("$OpenBSD: log.c,v 1.6 1999/11/24 19:53:47 markus Exp $");
9 7
10#include "ssh.h" 8#include "ssh.h"
11#include "xmalloc.h" 9#include "xmalloc.h"
diff --git a/login.c b/login.c
index aa01aac45..ddd58ff67 100644
--- a/login.c
+++ b/login.c
@@ -18,7 +18,7 @@
18 */ 18 */
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: login.c,v 1.3 1999/11/24 13:26:22 damien Exp $"); 21RCSID("$Id: login.c,v 1.4 1999/11/25 00:54:59 damien Exp $");
22 22
23#include <utmp.h> 23#include <utmp.h>
24#include "ssh.h" 24#include "ssh.h"
@@ -30,12 +30,16 @@ RCSID("$Id: login.c,v 1.3 1999/11/24 13:26:22 damien Exp $");
30# include <lastlog.h> 30# include <lastlog.h>
31#endif 31#endif
32 32
33/* Returns the time when the user last logged in. Returns 0 if the 33/*
34 information is not available. This must be called before record_login. 34 * Returns the time when the user last logged in. Returns 0 if the
35 The host the user logged in from will be returned in buf. */ 35 * information is not available. This must be called before record_login.
36 * The host the user logged in from will be returned in buf.
37 */
36 38
37/* Returns the time when the user last logged in (or 0 if no previous login 39/*
38 is found). The name of the host used last time is returned in buf. */ 40 * Returns the time when the user last logged in (or 0 if no previous login
41 * is found). The name of the host used last time is returned in buf.
42 */
39 43
40unsigned long 44unsigned long
41get_last_login_time(uid_t uid, const char *logname, 45get_last_login_time(uid_t uid, const char *logname,
@@ -64,8 +68,10 @@ get_last_login_time(uid_t uid, const char *logname,
64 return ll.ll_time; 68 return ll.ll_time;
65} 69}
66 70
67/* Records that the user has logged in. I these parts of operating systems 71/*
68 were more standardized. */ 72 * Records that the user has logged in. I these parts of operating systems
73 * were more standardized.
74 */
69 75
70void 76void
71record_login(int pid, const char *ttyname, const char *user, uid_t uid, 77record_login(int pid, const char *ttyname, const char *user, uid_t uid,
@@ -95,9 +101,10 @@ record_login(int pid, const char *ttyname, const char *user, uid_t uid,
95 101
96 /* Update lastlog unless actually recording a logout. */ 102 /* Update lastlog unless actually recording a logout. */
97 if (strcmp(user, "") != 0) { 103 if (strcmp(user, "") != 0) {
98 /* It is safer to bzero the lastlog structure first 104 /*
99 because some systems might have some extra fields in it 105 * It is safer to bzero the lastlog structure first because
100 (e.g. SGI) */ 106 * some systems might have some extra fields in it (e.g. SGI)
107 */
101 memset(&ll, 0, sizeof(ll)); 108 memset(&ll, 0, sizeof(ll));
102 109
103 /* Update lastlog. */ 110 /* Update lastlog. */
diff --git a/match.c b/match.c
index c0729dd8d..5386df6c4 100644
--- a/match.c
+++ b/match.c
@@ -14,12 +14,14 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: match.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); 17RCSID("$Id: match.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20 20
21/* Returns true if the given string matches the pattern (which may contain 21/*
22 ? and * as wildcards), and zero if it does not match. */ 22 * Returns true if the given string matches the pattern (which may contain ?
23 * and * as wildcards), and zero if it does not match.
24 */
23 25
24int 26int
25match_pattern(const char *s, const char *pattern) 27match_pattern(const char *s, const char *pattern)
@@ -29,7 +31,6 @@ match_pattern(const char *s, const char *pattern)
29 if (!*pattern) 31 if (!*pattern)
30 return !*s; 32 return !*s;
31 33
32 /* Process '*'. */
33 if (*pattern == '*') { 34 if (*pattern == '*') {
34 /* Skip the asterisk. */ 35 /* Skip the asterisk. */
35 pattern++; 36 pattern++;
@@ -40,9 +41,11 @@ match_pattern(const char *s, const char *pattern)
40 41
41 /* If next character in pattern is known, optimize. */ 42 /* If next character in pattern is known, optimize. */
42 if (*pattern != '?' && *pattern != '*') { 43 if (*pattern != '?' && *pattern != '*') {
43 /* Look instances of the next character in 44 /*
44 pattern, and try to match starting from 45 * Look instances of the next character in
45 those. */ 46 * pattern, and try to match starting from
47 * those.
48 */
46 for (; *s; s++) 49 for (; *s; s++)
47 if (*s == *pattern && 50 if (*s == *pattern &&
48 match_pattern(s + 1, pattern + 1)) 51 match_pattern(s + 1, pattern + 1))
@@ -50,26 +53,28 @@ match_pattern(const char *s, const char *pattern)
50 /* Failed. */ 53 /* Failed. */
51 return 0; 54 return 0;
52 } 55 }
53 /* Move ahead one character at a time and try to 56 /*
54 match at each position. */ 57 * Move ahead one character at a time and try to
58 * match at each position.
59 */
55 for (; *s; s++) 60 for (; *s; s++)
56 if (match_pattern(s, pattern)) 61 if (match_pattern(s, pattern))
57 return 1; 62 return 1;
58 /* Failed. */ 63 /* Failed. */
59 return 0; 64 return 0;
60 } 65 }
61 /* There must be at least one more character in the 66 /*
62 string. If we are at the end, fail. */ 67 * There must be at least one more character in the string.
68 * If we are at the end, fail.
69 */
63 if (!*s) 70 if (!*s)
64 return 0; 71 return 0;
65 72
66 /* Check if the next character of the string is 73 /* Check if the next character of the string is acceptable. */
67 acceptable. */
68 if (*pattern != '?' && *pattern != *s) 74 if (*pattern != '?' && *pattern != *s)
69 return 0; 75 return 0;
70 76
71 /* Move to the next character, both in string and in 77 /* Move to the next character, both in string and in pattern. */
72 pattern. */
73 s++; 78 s++;
74 pattern++; 79 pattern++;
75 } 80 }
diff --git a/mpaux.h b/mpaux.h
index b13f07e3a..105bc3148 100644
--- a/mpaux.h
+++ b/mpaux.h
@@ -13,14 +13,16 @@
13 * precision integers. 13 * precision integers.
14 */ 14 */
15 15
16/* RCSID("$Id: mpaux.h,v 1.3 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: mpaux.h,v 1.4 1999/11/25 00:54:59 damien Exp $"); */
17 17
18#ifndef MPAUX_H 18#ifndef MPAUX_H
19#define MPAUX_H 19#define MPAUX_H
20 20
21/* Computes a 16-byte session id in the global variable session_id. 21/*
22 The session id is computed by concatenating the linearized, msb 22 * Computes a 16-byte session id in the global variable session_id. The
23 first representations of host_key_n, session_key_n, and the cookie. */ 23 * session id is computed by concatenating the linearized, msb first
24 * representations of host_key_n, session_key_n, and the cookie.
25 */
24void 26void
25compute_session_id(unsigned char session_id[16], 27compute_session_id(unsigned char session_id[16],
26 unsigned char cookie[8], 28 unsigned char cookie[8],
diff --git a/nchan.c b/nchan.c
index b9a8ba49c..065b69baf 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,5 +1,34 @@
1/*
2 * Copyright (c) 1999 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
1#include "includes.h" 30#include "includes.h"
2RCSID("$Id: nchan.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); 31RCSID("$Id: nchan.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
3 32
4#include "ssh.h" 33#include "ssh.h"
5 34
@@ -173,9 +202,10 @@ chan_send_oclose(Channel *c)
173static void 202static void
174chan_shutdown_write(Channel *c) 203chan_shutdown_write(Channel *c)
175{ 204{
205 /* shutdown failure is allowed if write failed already */
176 debug("channel %d: shutdown_write", c->self); 206 debug("channel %d: shutdown_write", c->self);
177 if (shutdown(c->sock, SHUT_WR) < 0) 207 if (shutdown(c->sock, SHUT_WR) < 0)
178 error("chan_shutdown_write failed for #%d/fd%d: %.100s", 208 debug("chan_shutdown_write failed for #%d/fd%d: %.100s",
179 c->self, c->sock, strerror(errno)); 209 c->self, c->sock, strerror(errno));
180} 210}
181static void 211static void
diff --git a/nchan.h b/nchan.h
index 323dac349..49f2d0609 100644
--- a/nchan.h
+++ b/nchan.h
@@ -1,4 +1,33 @@
1/* RCSID("$Id: nchan.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ 1/*
2 * Copyright (c) 1999 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/* RCSID("$Id: nchan.h,v 1.3 1999/11/25 00:54:59 damien Exp $"); */
2 31
3#ifndef NCHAN_H 32#ifndef NCHAN_H
4#define NCHAN_H 33#define NCHAN_H
diff --git a/nchan.ms b/nchan.ms
index 18e7e9a9a..7b6c1617e 100644
--- a/nchan.ms
+++ b/nchan.ms
@@ -1,3 +1,31 @@
1.\"
2.\" Copyright (c) 1999 Markus Friedl. All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by Markus Friedl.
15.\" 4. The name of the author may not be used to endorse or promote products
16.\" derived from this software without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28.\"
1.TL 29.TL
2OpenSSH Channel Close Protocol 1.5 Implementation 30OpenSSH Channel Close Protocol 1.5 Implementation
3.SH 31.SH
diff --git a/packet.c b/packet.c
index 0e60dd5ec..f4b44f5e0 100644
--- a/packet.c
+++ b/packet.c
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: packet.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); 18RCSID("$Id: packet.c,v 1.6 1999/11/25 00:54:59 damien Exp $");
19 19
20#include "xmalloc.h" 20#include "xmalloc.h"
21#include "buffer.h" 21#include "buffer.h"
@@ -29,15 +29,19 @@ RCSID("$Id: packet.c,v 1.5 1999/11/24 13:26:22 damien Exp $");
29#include "compress.h" 29#include "compress.h"
30#include "deattack.h" 30#include "deattack.h"
31 31
32/* This variable contains the file descriptors used for communicating with 32/*
33 the other side. connection_in is used for reading; connection_out 33 * This variable contains the file descriptors used for communicating with
34 for writing. These can be the same descriptor, in which case it is 34 * the other side. connection_in is used for reading; connection_out for
35 assumed to be a socket. */ 35 * writing. These can be the same descriptor, in which case it is assumed to
36 * be a socket.
37 */
36static int connection_in = -1; 38static int connection_in = -1;
37static int connection_out = -1; 39static int connection_out = -1;
38 40
39/* Cipher type. This value is only used to determine whether to pad the 41/*
40 packets with zeroes or random data. */ 42 * Cipher type. This value is only used to determine whether to pad the
43 * packets with zeroes or random data.
44 */
41static int cipher_type = SSH_CIPHER_NONE; 45static int cipher_type = SSH_CIPHER_NONE;
42 46
43/* Protocol flags for the remote side. */ 47/* Protocol flags for the remote side. */
@@ -76,8 +80,10 @@ static int initialized = 0;
76/* Set to true if the connection is interactive. */ 80/* Set to true if the connection is interactive. */
77static int interactive_mode = 0; 81static int interactive_mode = 0;
78 82
79/* Sets the descriptors used for communication. Disables encryption until 83/*
80 packet_set_encryption_key is called. */ 84 * Sets the descriptors used for communication. Disables encryption until
85 * packet_set_encryption_key is called.
86 */
81 87
82void 88void
83packet_set_connection(int fd_in, int fd_out) 89packet_set_connection(int fd_in, int fd_out)
@@ -171,8 +177,10 @@ packet_get_protocol_flags()
171 return remote_protocol_flags; 177 return remote_protocol_flags;
172} 178}
173 179
174/* Starts packet compression from the next packet on in both directions. 180/*
175 Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. */ 181 * Starts packet compression from the next packet on in both directions.
182 * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip.
183 */
176 184
177void 185void
178packet_start_compression(int level) 186packet_start_compression(int level)
@@ -184,8 +192,10 @@ packet_start_compression(int level)
184 buffer_compress_init(level); 192 buffer_compress_init(level);
185} 193}
186 194
187/* Encrypts the given number of bytes, copying from src to dest. 195/*
188 bytes is known to be a multiple of 8. */ 196 * Encrypts the given number of bytes, copying from src to dest. bytes is
197 * known to be a multiple of 8.
198 */
189 199
190void 200void
191packet_encrypt(CipherContext * cc, void *dest, void *src, 201packet_encrypt(CipherContext * cc, void *dest, void *src,
@@ -194,8 +204,10 @@ packet_encrypt(CipherContext * cc, void *dest, void *src,
194 cipher_encrypt(cc, dest, src, bytes); 204 cipher_encrypt(cc, dest, src, bytes);
195} 205}
196 206
197/* Decrypts the given number of bytes, copying from src to dest. 207/*
198 bytes is known to be a multiple of 8. */ 208 * Decrypts the given number of bytes, copying from src to dest. bytes is
209 * known to be a multiple of 8.
210 */
199 211
200void 212void
201packet_decrypt(CipherContext * cc, void *dest, void *src, 213packet_decrypt(CipherContext * cc, void *dest, void *src,
@@ -206,8 +218,10 @@ packet_decrypt(CipherContext * cc, void *dest, void *src,
206 if ((bytes % 8) != 0) 218 if ((bytes % 8) != 0)
207 fatal("packet_decrypt: bad ciphertext length %d", bytes); 219 fatal("packet_decrypt: bad ciphertext length %d", bytes);
208 220
209 /* Cryptographic attack detector for ssh - Modifications for packet.c 221 /*
210 (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com) */ 222 * Cryptographic attack detector for ssh - Modifications for packet.c
223 * (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com)
224 */
211 225
212 switch (cc->type) { 226 switch (cc->type) {
213 case SSH_CIPHER_NONE: 227 case SSH_CIPHER_NONE:
@@ -224,9 +238,11 @@ packet_decrypt(CipherContext * cc, void *dest, void *src,
224 cipher_decrypt(cc, dest, src, bytes); 238 cipher_decrypt(cc, dest, src, bytes);
225} 239}
226 240
227/* Causes any further packets to be encrypted using the given key. The same 241/*
228 key is used for both sending and reception. However, both directions 242 * Causes any further packets to be encrypted using the given key. The same
229 are encrypted independently of each other. */ 243 * key is used for both sending and reception. However, both directions are
244 * encrypted independently of each other.
245 */
230 246
231void 247void
232packet_set_encryption_key(const unsigned char *key, unsigned int keylen, 248packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
@@ -283,8 +299,10 @@ packet_put_bignum(BIGNUM * value)
283 buffer_put_bignum(&outgoing_packet, value); 299 buffer_put_bignum(&outgoing_packet, value);
284} 300}
285 301
286/* Finalizes and sends the packet. If the encryption key has been set, 302/*
287 encrypts the packet before sending. */ 303 * Finalizes and sends the packet. If the encryption key has been set,
304 * encrypts the packet before sending.
305 */
288 306
289void 307void
290packet_send() 308packet_send()
@@ -294,8 +312,10 @@ packet_send()
294 unsigned int checksum; 312 unsigned int checksum;
295 u_int32_t rand = 0; 313 u_int32_t rand = 0;
296 314
297 /* If using packet compression, compress the payload of the 315 /*
298 outgoing packet. */ 316 * If using packet compression, compress the payload of the outgoing
317 * packet.
318 */
299 if (packet_compression) { 319 if (packet_compression) {
300 buffer_clear(&compression_buffer); 320 buffer_clear(&compression_buffer);
301 /* Skip padding. */ 321 /* Skip padding. */
@@ -348,14 +368,18 @@ packet_send()
348 368
349 buffer_clear(&outgoing_packet); 369 buffer_clear(&outgoing_packet);
350 370
351 /* Note that the packet is now only buffered in output. It won\'t 371 /*
352 be actually sent until packet_write_wait or packet_write_poll 372 * Note that the packet is now only buffered in output. It won\'t be
353 is called. */ 373 * actually sent until packet_write_wait or packet_write_poll is
374 * called.
375 */
354} 376}
355 377
356/* Waits until a packet has been received, and returns its type. Note that 378/*
357 no other data is processed until this returns, so this function should 379 * Waits until a packet has been received, and returns its type. Note that
358 not be used during the interactive session. */ 380 * no other data is processed until this returns, so this function should not
381 * be used during the interactive session.
382 */
359 383
360int 384int
361packet_read(int *payload_len_ptr) 385packet_read(int *payload_len_ptr)
@@ -379,12 +403,16 @@ packet_read(int *payload_len_ptr)
379 /* If we got a packet, return it. */ 403 /* If we got a packet, return it. */
380 if (type != SSH_MSG_NONE) 404 if (type != SSH_MSG_NONE)
381 return type; 405 return type;
382 /* Otherwise, wait for some data to arrive, add it to the 406 /*
383 buffer, and try again. */ 407 * Otherwise, wait for some data to arrive, add it to the
408 * buffer, and try again.
409 */
384 FD_ZERO(&set); 410 FD_ZERO(&set);
385 FD_SET(connection_in, &set); 411 FD_SET(connection_in, &set);
412
386 /* Wait for some data to arrive. */ 413 /* Wait for some data to arrive. */
387 select(connection_in + 1, &set, NULL, NULL, NULL); 414 select(connection_in + 1, &set, NULL, NULL, NULL);
415
388 /* Read data from the socket. */ 416 /* Read data from the socket. */
389 len = read(connection_in, buf, sizeof(buf)); 417 len = read(connection_in, buf, sizeof(buf));
390 if (len == 0) 418 if (len == 0)
@@ -397,8 +425,10 @@ packet_read(int *payload_len_ptr)
397 /* NOTREACHED */ 425 /* NOTREACHED */
398} 426}
399 427
400/* Waits until a packet has been received, verifies that its type matches 428/*
401 that given, and gives a fatal error and exits if there is a mismatch. */ 429 * Waits until a packet has been received, verifies that its type matches
430 * that given, and gives a fatal error and exits if there is a mismatch.
431 */
402 432
403void 433void
404packet_read_expect(int *payload_len_ptr, int expected_type) 434packet_read_expect(int *payload_len_ptr, int expected_type)
@@ -516,8 +546,10 @@ restart:
516 return (unsigned char) buf[0]; 546 return (unsigned char) buf[0];
517} 547}
518 548
519/* Buffers the given amount of input characters. This is intended to be 549/*
520 used together with packet_read_poll. */ 550 * Buffers the given amount of input characters. This is intended to be used
551 * together with packet_read_poll.
552 */
521 553
522void 554void
523packet_process_incoming(const char *buf, unsigned int len) 555packet_process_incoming(const char *buf, unsigned int len)
@@ -543,8 +575,10 @@ packet_get_int()
543 return buffer_get_int(&incoming_packet); 575 return buffer_get_int(&incoming_packet);
544} 576}
545 577
546/* Returns an arbitrary precision integer from the packet data. The integer 578/*
547 must have been initialized before this call. */ 579 * Returns an arbitrary precision integer from the packet data. The integer
580 * must have been initialized before this call.
581 */
548 582
549void 583void
550packet_get_bignum(BIGNUM * value, int *length_ptr) 584packet_get_bignum(BIGNUM * value, int *length_ptr)
@@ -552,25 +586,27 @@ packet_get_bignum(BIGNUM * value, int *length_ptr)
552 *length_ptr = buffer_get_bignum(&incoming_packet, value); 586 *length_ptr = buffer_get_bignum(&incoming_packet, value);
553} 587}
554 588
555/* Returns a string from the packet data. The string is allocated using 589/*
556 xmalloc; it is the responsibility of the calling program to free it when 590 * Returns a string from the packet data. The string is allocated using
557 no longer needed. The length_ptr argument may be NULL, or point to an 591 * xmalloc; it is the responsibility of the calling program to free it when
558 integer into which the length of the string is stored. */ 592 * no longer needed. The length_ptr argument may be NULL, or point to an
593 * integer into which the length of the string is stored.
594 */
559 595
560char 596char *
561*
562packet_get_string(unsigned int *length_ptr) 597packet_get_string(unsigned int *length_ptr)
563{ 598{
564 return buffer_get_string(&incoming_packet, length_ptr); 599 return buffer_get_string(&incoming_packet, length_ptr);
565} 600}
566 601
567/* Sends a diagnostic message from the server to the client. This message 602/*
568 can be sent at any time (but not while constructing another message). 603 * Sends a diagnostic message from the server to the client. This message
569 The message is printed immediately, but only if the client is being 604 * can be sent at any time (but not while constructing another message). The
570 executed in verbose mode. These messages are primarily intended to 605 * message is printed immediately, but only if the client is being executed
571 ease debugging authentication problems. The length of the formatted 606 * in verbose mode. These messages are primarily intended to ease debugging
572 message must not exceed 1024 bytes. This will automatically call 607 * authentication problems. The length of the formatted message must not
573 packet_write_wait. */ 608 * exceed 1024 bytes. This will automatically call packet_write_wait.
609 */
574 610
575void 611void
576packet_send_debug(const char *fmt,...) 612packet_send_debug(const char *fmt,...)
@@ -588,10 +624,12 @@ packet_send_debug(const char *fmt,...)
588 packet_write_wait(); 624 packet_write_wait();
589} 625}
590 626
591/* Logs the error plus constructs and sends a disconnect 627/*
592 packet, closes the connection, and exits. This function never returns. 628 * Logs the error plus constructs and sends a disconnect packet, closes the
593 The error message should not contain a newline. The length of the 629 * connection, and exits. This function never returns. The error message
594 formatted message must not exceed 1024 bytes. */ 630 * should not contain a newline. The length of the formatted message must
631 * not exceed 1024 bytes.
632 */
595 633
596void 634void
597packet_disconnect(const char *fmt,...) 635packet_disconnect(const char *fmt,...)
@@ -603,8 +641,10 @@ packet_disconnect(const char *fmt,...)
603 fatal("packet_disconnect called recursively."); 641 fatal("packet_disconnect called recursively.");
604 disconnecting = 1; 642 disconnecting = 1;
605 643
606 /* Format the message. Note that the caller must make sure the 644 /*
607 message is of limited size. */ 645 * Format the message. Note that the caller must make sure the
646 * message is of limited size.
647 */
608 va_start(args, fmt); 648 va_start(args, fmt);
609 vsnprintf(buf, sizeof(buf), fmt, args); 649 vsnprintf(buf, sizeof(buf), fmt, args);
610 va_end(args); 650 va_end(args);
@@ -625,8 +665,7 @@ packet_disconnect(const char *fmt,...)
625 fatal("Disconnecting: %.100s", buf); 665 fatal("Disconnecting: %.100s", buf);
626} 666}
627 667
628/* Checks if there is any buffered output, and tries to write some of the 668/* Checks if there is any buffered output, and tries to write some of the output. */
629 output. */
630 669
631void 670void
632packet_write_poll() 671packet_write_poll()
@@ -644,8 +683,10 @@ packet_write_poll()
644 } 683 }
645} 684}
646 685
647/* Calls packet_write_poll repeatedly until all pending output data has 686/*
648 been written. */ 687 * Calls packet_write_poll repeatedly until all pending output data has been
688 * written.
689 */
649 690
650void 691void
651packet_write_wait() 692packet_write_wait()
@@ -689,8 +730,10 @@ packet_set_interactive(int interactive, int keepalives)
689 /* Record that we are in interactive mode. */ 730 /* Record that we are in interactive mode. */
690 interactive_mode = interactive; 731 interactive_mode = interactive;
691 732
692 /* Only set socket options if using a socket (as indicated by the 733 /*
693 descriptors being the same). */ 734 * Only set socket options if using a socket (as indicated by the
735 * descriptors being the same).
736 */
694 if (connection_in != connection_out) 737 if (connection_in != connection_out)
695 return; 738 return;
696 739
@@ -701,8 +744,10 @@ packet_set_interactive(int interactive, int keepalives)
701 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 744 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
702 } 745 }
703 if (interactive) { 746 if (interactive) {
704 /* Set IP options for an interactive connection. Use 747 /*
705 IPTOS_LOWDELAY and TCP_NODELAY. */ 748 * Set IP options for an interactive connection. Use
749 * IPTOS_LOWDELAY and TCP_NODELAY.
750 */
706 int lowdelay = IPTOS_LOWDELAY; 751 int lowdelay = IPTOS_LOWDELAY;
707 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay, 752 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay,
708 sizeof(lowdelay)) < 0) 753 sizeof(lowdelay)) < 0)
@@ -711,8 +756,10 @@ packet_set_interactive(int interactive, int keepalives)
711 sizeof(on)) < 0) 756 sizeof(on)) < 0)
712 error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); 757 error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
713 } else { 758 } else {
714 /* Set IP options for a non-interactive connection. Use 759 /*
715 IPTOS_THROUGHPUT. */ 760 * Set IP options for a non-interactive connection. Use
761 * IPTOS_THROUGHPUT.
762 */
716 int throughput = IPTOS_THROUGHPUT; 763 int throughput = IPTOS_THROUGHPUT;
717 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput, 764 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput,
718 sizeof(throughput)) < 0) 765 sizeof(throughput)) < 0)
diff --git a/packet.h b/packet.h
index ad1a5b089..e6ae671a4 100644
--- a/packet.h
+++ b/packet.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: packet.h,v 1.6 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: packet.h,v 1.7 1999/11/25 00:54:59 damien Exp $"); */
17 17
18#ifndef PACKET_H 18#ifndef PACKET_H
19#define PACKET_H 19#define PACKET_H
@@ -27,10 +27,11 @@
27#include <ssl/bn.h> 27#include <ssl/bn.h>
28#endif 28#endif
29 29
30/* Sets the socket used for communication. Disables encryption until 30/*
31 packet_set_encryption_key is called. It is permissible that fd_in 31 * Sets the socket used for communication. Disables encryption until
32 and fd_out are the same descriptor; in that case it is assumed to 32 * packet_set_encryption_key is called. It is permissible that fd_in and
33 be a socket. */ 33 * fd_out are the same descriptor; in that case it is assumed to be a socket.
34 */
34void packet_set_connection(int fd_in, int fd_out); 35void packet_set_connection(int fd_in, int fd_out);
35 36
36/* Puts the connection file descriptors into non-blocking mode. */ 37/* Puts the connection file descriptors into non-blocking mode. */
@@ -42,20 +43,25 @@ int packet_get_connection_in(void);
42/* Returns the file descriptor used for output. */ 43/* Returns the file descriptor used for output. */
43int packet_get_connection_out(void); 44int packet_get_connection_out(void);
44 45
45/* Closes the connection (both descriptors) and clears and frees 46/*
46 internal data structures. */ 47 * Closes the connection (both descriptors) and clears and frees internal
48 * data structures.
49 */
47void packet_close(void); 50void packet_close(void);
48 51
49/* Causes any further packets to be encrypted using the given key. The same 52/*
50 key is used for both sending and reception. However, both directions 53 * Causes any further packets to be encrypted using the given key. The same
51 are encrypted independently of each other. Cipher types are 54 * key is used for both sending and reception. However, both directions are
52 defined in ssh.h. */ 55 * encrypted independently of each other. Cipher types are defined in ssh.h.
56 */
53void 57void
54packet_set_encryption_key(const unsigned char *key, unsigned int keylen, 58packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
55 int cipher_type); 59 int cipher_type);
56 60
57/* Sets remote side protocol flags for the current connection. This can 61/*
58 be called at any time. */ 62 * Sets remote side protocol flags for the current connection. This can be
63 * called at any time.
64 */
59void packet_set_protocol_flags(unsigned int flags); 65void packet_set_protocol_flags(unsigned int flags);
60 66
61/* Returns the remote protocol flags set earlier by the above function. */ 67/* Returns the remote protocol flags set earlier by the above function. */
@@ -64,8 +70,10 @@ unsigned int packet_get_protocol_flags(void);
64/* Enables compression in both directions starting from the next packet. */ 70/* Enables compression in both directions starting from the next packet. */
65void packet_start_compression(int level); 71void packet_start_compression(int level);
66 72
67/* Informs that the current session is interactive. Sets IP flags for optimal 73/*
68 performance in interactive use. */ 74 * Informs that the current session is interactive. Sets IP flags for
75 * optimal performance in interactive use.
76 */
69void packet_set_interactive(int interactive, int keepalives); 77void packet_set_interactive(int interactive, int keepalives);
70 78
71/* Returns true if the current connection is interactive. */ 79/* Returns true if the current connection is interactive. */
@@ -86,28 +94,35 @@ void packet_put_bignum(BIGNUM * value);
86/* Appends a string to packet data. */ 94/* Appends a string to packet data. */
87void packet_put_string(const char *buf, unsigned int len); 95void packet_put_string(const char *buf, unsigned int len);
88 96
89/* Finalizes and sends the packet. If the encryption key has been set, 97/*
90 encrypts the packet before sending. */ 98 * Finalizes and sends the packet. If the encryption key has been set,
99 * encrypts the packet before sending.
100 */
91void packet_send(void); 101void packet_send(void);
92 102
93/* Waits until a packet has been received, and returns its type. */ 103/* Waits until a packet has been received, and returns its type. */
94int packet_read(int *payload_len_ptr); 104int packet_read(int *payload_len_ptr);
95 105
96/* Waits until a packet has been received, verifies that its type matches 106/*
97 that given, and gives a fatal error and exits if there is a mismatch. */ 107 * Waits until a packet has been received, verifies that its type matches
108 * that given, and gives a fatal error and exits if there is a mismatch.
109 */
98void packet_read_expect(int *payload_len_ptr, int type); 110void packet_read_expect(int *payload_len_ptr, int type);
99 111
100/* Checks if a full packet is available in the data received so far via 112/*
101 packet_process_incoming. If so, reads the packet; otherwise returns 113 * Checks if a full packet is available in the data received so far via
102 SSH_MSG_NONE. This does not wait for data from the connection. 114 * packet_process_incoming. If so, reads the packet; otherwise returns
103 115 * SSH_MSG_NONE. This does not wait for data from the connection.
104 SSH_MSG_DISCONNECT is handled specially here. Also, 116 * SSH_MSG_DISCONNECT is handled specially here. Also, SSH_MSG_IGNORE
105 SSH_MSG_IGNORE messages are skipped by this function and are never returned 117 * messages are skipped by this function and are never returned to higher
106 to higher levels. */ 118 * levels.
119 */
107int packet_read_poll(int *packet_len_ptr); 120int packet_read_poll(int *packet_len_ptr);
108 121
109/* Buffers the given amount of input characters. This is intended to be 122/*
110 used together with packet_read_poll. */ 123 * Buffers the given amount of input characters. This is intended to be used
124 * together with packet_read_poll.
125 */
111void packet_process_incoming(const char *buf, unsigned int len); 126void packet_process_incoming(const char *buf, unsigned int len);
112 127
113/* Returns a character (0-255) from the packet data. */ 128/* Returns a character (0-255) from the packet data. */
@@ -116,34 +131,41 @@ unsigned int packet_get_char(void);
116/* Returns an integer from the packet data. */ 131/* Returns an integer from the packet data. */
117unsigned int packet_get_int(void); 132unsigned int packet_get_int(void);
118 133
119/* Returns an arbitrary precision integer from the packet data. The integer 134/*
120 must have been initialized before this call. */ 135 * Returns an arbitrary precision integer from the packet data. The integer
136 * must have been initialized before this call.
137 */
121void packet_get_bignum(BIGNUM * value, int *length_ptr); 138void packet_get_bignum(BIGNUM * value, int *length_ptr);
122 139
123/* Returns a string from the packet data. The string is allocated using 140/*
124 xmalloc; it is the responsibility of the calling program to free it when 141 * Returns a string from the packet data. The string is allocated using
125 no longer needed. The length_ptr argument may be NULL, or point to an 142 * xmalloc; it is the responsibility of the calling program to free it when
126 integer into which the length of the string is stored. */ 143 * no longer needed. The length_ptr argument may be NULL, or point to an
144 * integer into which the length of the string is stored.
145 */
127char *packet_get_string(unsigned int *length_ptr); 146char *packet_get_string(unsigned int *length_ptr);
128 147
129/* Logs the error in syslog using LOG_INFO, constructs and sends a disconnect 148/*
130 packet, closes the connection, and exits. This function never returns. 149 * Logs the error in syslog using LOG_INFO, constructs and sends a disconnect
131 The error message should not contain a newline. The total length of the 150 * packet, closes the connection, and exits. This function never returns.
132 message must not exceed 1024 bytes. */ 151 * The error message should not contain a newline. The total length of the
152 * message must not exceed 1024 bytes.
153 */
133void packet_disconnect(const char *fmt,...); 154void packet_disconnect(const char *fmt,...);
134 155
135/* Sends a diagnostic message to the other side. This message 156/*
136 can be sent at any time (but not while constructing another message). 157 * Sends a diagnostic message to the other side. This message can be sent at
137 The message is printed immediately, but only if the client is being 158 * any time (but not while constructing another message). The message is
138 executed in verbose mode. These messages are primarily intended to 159 * printed immediately, but only if the client is being executed in verbose
139 ease debugging authentication problems. The total length of the message 160 * mode. These messages are primarily intended to ease debugging
140 must not exceed 1024 bytes. This will automatically call 161 * authentication problems. The total length of the message must not exceed
141 packet_write_wait. If the remote side protocol flags do not indicate 162 * 1024 bytes. This will automatically call packet_write_wait. If the
142 that it supports SSH_MSG_DEBUG, this will do nothing. */ 163 * remote side protocol flags do not indicate that it supports SSH_MSG_DEBUG,
164 * this will do nothing.
165 */
143void packet_send_debug(const char *fmt,...); 166void packet_send_debug(const char *fmt,...);
144 167
145/* Checks if there is any buffered output, and tries to write some of the 168/* Checks if there is any buffered output, and tries to write some of the output. */
146 output. */
147void packet_write_poll(void); 169void packet_write_poll(void);
148 170
149/* Waits until all pending output data has been written. */ 171/* Waits until all pending output data has been written. */
diff --git a/pty.c b/pty.c
index 34ed48d61..e46842138 100644
--- a/pty.c
+++ b/pty.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: pty.c,v 1.4 1999/11/24 13:26:22 damien Exp $"); 17RCSID("$Id: pty.c,v 1.5 1999/11/25 00:54:59 damien Exp $");
18 18
19#include "pty.h" 19#include "pty.h"
20#include "ssh.h" 20#include "ssh.h"
@@ -32,10 +32,12 @@ RCSID("$Id: pty.c,v 1.4 1999/11/24 13:26:22 damien Exp $");
32#define O_NOCTTY 0 32#define O_NOCTTY 0
33#endif 33#endif
34 34
35/* Allocates and opens a pty. Returns 0 if no pty could be allocated, 35/*
36 or nonzero if a pty was successfully allocated. On success, open file 36 * Allocates and opens a pty. Returns 0 if no pty could be allocated, or
37 descriptors for the pty and tty sides and the name of the tty side are 37 * nonzero if a pty was successfully allocated. On success, open file
38 returned (the buffer must be able to hold at least 64 characters). */ 38 * descriptors for the pty and tty sides and the name of the tty side are
39 * returned (the buffer must be able to hold at least 64 characters).
40 */
39 41
40int 42int
41pty_allocate(int *ptyfd, int *ttyfd, char *namebuf) 43pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
@@ -52,8 +54,10 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
52 return 1; 54 return 1;
53#else /* HAVE_OPENPTY */ 55#else /* HAVE_OPENPTY */
54#ifdef HAVE__GETPTY 56#ifdef HAVE__GETPTY
55 /* _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates 57 /*
56 more pty's automagically when needed */ 58 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
59 * pty's automagically when needed
60 */
57 char *slave; 61 char *slave;
58 62
59 slave = _getpty(ptyfd, O_RDWR, 0622, 0); 63 slave = _getpty(ptyfd, O_RDWR, 0622, 0);
@@ -72,8 +76,10 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
72 return 1; 76 return 1;
73#else /* HAVE__GETPTY */ 77#else /* HAVE__GETPTY */
74#ifdef HAVE_DEV_PTMX 78#ifdef HAVE_DEV_PTMX
75 /* This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 79 /*
76 also has bsd-style ptys, but they simply do not work.) */ 80 * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3
81 * also has bsd-style ptys, but they simply do not work.)
82 */
77 int ptm; 83 int ptm;
78 char *pts; 84 char *pts;
79 85
@@ -103,8 +109,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
103 close(*ptyfd); 109 close(*ptyfd);
104 return 0; 110 return 0;
105 } 111 }
106 /* Push the appropriate streams modules, as described in Solaris 112 /* Push the appropriate streams modules, as described in Solaris pts(7). */
107 pts(7). */
108 if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) 113 if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
109 error("ioctl I_PUSH ptem: %.100s", strerror(errno)); 114 error("ioctl I_PUSH ptem: %.100s", strerror(errno));
110 if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) 115 if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
@@ -138,8 +143,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
138 /* BSD-style pty code. */ 143 /* BSD-style pty code. */
139 char buf[64]; 144 char buf[64];
140 int i; 145 int i;
141 const char *ptymajors = 146 const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
142 "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
143 const char *ptyminors = "0123456789abcdef"; 147 const char *ptyminors = "0123456789abcdef";
144 int num_minors = strlen(ptyminors); 148 int num_minors = strlen(ptyminors);
145 int num_ptys = strlen(ptymajors) * num_minors; 149 int num_ptys = strlen(ptymajors) * num_minors;
@@ -198,8 +202,10 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
198 if (setsid() < 0) 202 if (setsid() < 0)
199 error("setsid: %.100s", strerror(errno)); 203 error("setsid: %.100s", strerror(errno));
200 204
201 /* Verify that we are successfully disconnected from the 205 /*
202 controlling tty. */ 206 * Verify that we are successfully disconnected from the controlling
207 * tty.
208 */
203 fd = open("/dev/tty", O_RDWR | O_NOCTTY); 209 fd = open("/dev/tty", O_RDWR | O_NOCTTY);
204 if (fd >= 0) { 210 if (fd >= 0) {
205 error("Failed to disconnect from controlling tty."); 211 error("Failed to disconnect from controlling tty.");
@@ -208,9 +214,11 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
208 /* Make it our controlling tty. */ 214 /* Make it our controlling tty. */
209#ifdef TIOCSCTTY 215#ifdef TIOCSCTTY
210 debug("Setting controlling tty using TIOCSCTTY."); 216 debug("Setting controlling tty using TIOCSCTTY.");
211 /* We ignore errors from this, because HPSUX defines TIOCSCTTY, 217 /*
212 but returns EINVAL with these arguments, and there is 218 * We ignore errors from this, because HPSUX defines TIOCSCTTY, but
213 absolutely no documentation. */ 219 * returns EINVAL with these arguments, and there is absolutely no
220 * documentation.
221 */
214 ioctl(*ttyfd, TIOCSCTTY, NULL); 222 ioctl(*ttyfd, TIOCSCTTY, NULL);
215#endif /* TIOCSCTTY */ 223#endif /* TIOCSCTTY */
216 fd = open(ttyname, O_RDWR); 224 fd = open(ttyname, O_RDWR);
diff --git a/pty.h b/pty.h
index 215f4343e..0601e69fc 100644
--- a/pty.h
+++ b/pty.h
@@ -13,23 +13,29 @@
13 * tty. 13 * tty.
14 */ 14 */
15 15
16/* RCSID("$Id: pty.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: pty.h,v 1.3 1999/11/25 00:54:59 damien Exp $"); */
17 17
18#ifndef PTY_H 18#ifndef PTY_H
19#define PTY_H 19#define PTY_H
20 20
21/* Allocates and opens a pty. Returns 0 if no pty could be allocated, 21/*
22 or nonzero if a pty was successfully allocated. On success, open file 22 * Allocates and opens a pty. Returns 0 if no pty could be allocated, or
23 descriptors for the pty and tty sides and the name of the tty side are 23 * nonzero if a pty was successfully allocated. On success, open file
24 returned (the buffer must be able to hold at least 64 characters). */ 24 * descriptors for the pty and tty sides and the name of the tty side are
25 * returned (the buffer must be able to hold at least 64 characters).
26 */
25int pty_allocate(int *ptyfd, int *ttyfd, char *ttyname); 27int pty_allocate(int *ptyfd, int *ttyfd, char *ttyname);
26 28
27/* Releases the tty. Its ownership is returned to root, and permissions to 29/*
28 0666. */ 30 * Releases the tty. Its ownership is returned to root, and permissions to
31 * 0666.
32 */
29void pty_release(const char *ttyname); 33void pty_release(const char *ttyname);
30 34
31/* Makes the tty the processes controlling tty and sets it to sane modes. 35/*
32 This may need to reopen the tty to get rid of possible eavesdroppers. */ 36 * Makes the tty the processes controlling tty and sets it to sane modes.
37 * This may need to reopen the tty to get rid of possible eavesdroppers.
38 */
33void pty_make_controlling_tty(int *ttyfd, const char *ttyname); 39void pty_make_controlling_tty(int *ttyfd, const char *ttyname);
34 40
35/* Changes the window size associated with the pty. */ 41/* Changes the window size associated with the pty. */
diff --git a/radix.c b/radix.c
index 6637b2fb1..c87dd2d35 100644
--- a/radix.c
+++ b/radix.c
@@ -74,9 +74,11 @@ uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize)
74 while (*bufcoded == ' ' || *bufcoded == '\t') 74 while (*bufcoded == ' ' || *bufcoded == '\t')
75 bufcoded++; 75 bufcoded++;
76 76
77 /* Figure out how many characters are in the input buffer. If this 77 /*
78 would decode into more bytes than would fit into the output 78 * Figure out how many characters are in the input buffer. If this
79 buffer, adjust the number of input bytes downwards. */ 79 * would decode into more bytes than would fit into the output
80 * buffer, adjust the number of input bytes downwards.
81 */
80 bufin = bufcoded; 82 bufin = bufcoded;
81 while (DEC(*(bufin++)) <= MAXVAL); 83 while (DEC(*(bufin++)) <= MAXVAL);
82 nprbytes = bufin - bufcoded - 1; 84 nprbytes = bufin - bufcoded - 1;
diff --git a/readconf.c b/readconf.c
index 063bd467d..2c2705067 100644
--- a/readconf.c
+++ b/readconf.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: readconf.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); 17RCSID("$Id: readconf.c,v 1.6 1999/11/25 00:54:59 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "cipher.h" 20#include "cipher.h"
@@ -158,8 +158,10 @@ static struct {
158#define WHITESPACE " \t\r\n" 158#define WHITESPACE " \t\r\n"
159 159
160 160
161/* Adds a local TCP/IP port forward to options. Never returns if there 161/*
162 is an error. */ 162 * Adds a local TCP/IP port forward to options. Never returns if there is an
163 * error.
164 */
163 165
164void 166void
165add_local_forward(Options *options, int port, const char *host, 167add_local_forward(Options *options, int port, const char *host,
@@ -179,8 +181,10 @@ add_local_forward(Options *options, int port, const char *host,
179 fwd->host_port = host_port; 181 fwd->host_port = host_port;
180} 182}
181 183
182/* Adds a remote TCP/IP port forward to options. Never returns if there 184/*
183 is an error. */ 185 * Adds a remote TCP/IP port forward to options. Never returns if there is
186 * an error.
187 */
184 188
185void 189void
186add_remote_forward(Options *options, int port, const char *host, 190add_remote_forward(Options *options, int port, const char *host,
@@ -196,8 +200,10 @@ add_remote_forward(Options *options, int port, const char *host,
196 fwd->host_port = host_port; 200 fwd->host_port = host_port;
197} 201}
198 202
199/* Returns the number of the token pointed to by cp of length len. 203/*
200 Never returns if the token is not known. */ 204 * Returns the number of the token pointed to by cp of length len. Never
205 * returns if the token is not known.
206 */
201 207
202static OpCodes 208static OpCodes
203parse_token(const char *cp, const char *filename, int linenum) 209parse_token(const char *cp, const char *filename, int linenum)
@@ -205,7 +211,7 @@ parse_token(const char *cp, const char *filename, int linenum)
205 unsigned int i; 211 unsigned int i;
206 212
207 for (i = 0; keywords[i].name; i++) 213 for (i = 0; keywords[i].name; i++)
208 if (strcmp(cp, keywords[i].name) == 0) 214 if (strcasecmp(cp, keywords[i].name) == 0)
209 return keywords[i].opcode; 215 return keywords[i].opcode;
210 216
211 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", 217 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
@@ -213,15 +219,17 @@ parse_token(const char *cp, const char *filename, int linenum)
213 return oBadOption; 219 return oBadOption;
214} 220}
215 221
216/* Processes a single option line as used in the configuration files. 222/*
217 This only sets those values that have not already been set. */ 223 * Processes a single option line as used in the configuration files. This
224 * only sets those values that have not already been set.
225 */
218 226
219int 227int
220process_config_line(Options *options, const char *host, 228process_config_line(Options *options, const char *host,
221 char *line, const char *filename, int linenum, 229 char *line, const char *filename, int linenum,
222 int *activep) 230 int *activep)
223{ 231{
224 char buf[256], *cp, *string, **charptr; 232 char buf[256], *cp, *string, **charptr, *cp2;
225 int opcode, *intptr, value, fwd_port, fwd_host_port; 233 int opcode, *intptr, value, fwd_port, fwd_host_port;
226 234
227 /* Skip leading whitespace. */ 235 /* Skip leading whitespace. */
@@ -229,21 +237,14 @@ process_config_line(Options *options, const char *host,
229 if (!*cp || *cp == '\n' || *cp == '#') 237 if (!*cp || *cp == '\n' || *cp == '#')
230 return 0; 238 return 0;
231 239
232 /* Get the keyword. (Each line is supposed to begin with a 240 /* Get the keyword. (Each line is supposed to begin with a keyword). */
233 keyword). */
234 cp = strtok(cp, WHITESPACE); 241 cp = strtok(cp, WHITESPACE);
235 {
236 char *t = cp;
237 for (; *t != 0; t++)
238 if ('A' <= *t && *t <= 'Z')
239 *t = *t - 'A' + 'a'; /* tolower */
240
241 }
242 opcode = parse_token(cp, filename, linenum); 242 opcode = parse_token(cp, filename, linenum);
243 243
244 switch (opcode) { 244 switch (opcode) {
245 case oBadOption: 245 case oBadOption:
246 return -1; /* don't panic, but count bad options */ 246 /* don't panic, but count bad options */
247 return -1;
247 /* NOTREACHED */ 248 /* NOTREACHED */
248 case oForwardAgent: 249 case oForwardAgent:
249 intptr = &options->forward_agent; 250 intptr = &options->forward_agent;
@@ -419,17 +420,11 @@ parse_int:
419 fatal("%.200s line %d: Missing argument.", filename, linenum); 420 fatal("%.200s line %d: Missing argument.", filename, linenum);
420 if (cp[0] < '0' || cp[0] > '9') 421 if (cp[0] < '0' || cp[0] > '9')
421 fatal("%.200s line %d: Bad number.", filename, linenum); 422 fatal("%.200s line %d: Bad number.", filename, linenum);
422#if 0 423
423 value = atoi(cp); 424 /* Octal, decimal, or hex format? */
424#else 425 value = strtol(cp, &cp2, 0);
425 { 426 if (cp == cp2)
426 char *ptr; 427 fatal("%.200s line %d: Bad number.", filename, linenum);
427 value = strtol(cp, &ptr, 0); /* Octal, decimal, or
428 hex format? */
429 if (cp == ptr)
430 fatal("%.200s line %d: Bad number.", filename, linenum);
431 }
432#endif
433 if (*activep && *intptr == -1) 428 if (*activep && *intptr == -1)
434 *intptr = value; 429 *intptr = value;
435 break; 430 break;
@@ -506,8 +501,7 @@ parse_int:
506 *activep = 1; 501 *activep = 1;
507 break; 502 break;
508 } 503 }
509 /* Avoid garbage check below, as strtok already returned 504 /* Avoid garbage check below, as strtok already returned NULL. */
510 NULL. */
511 return 0; 505 return 0;
512 506
513 case oEscapeChar: 507 case oEscapeChar:
@@ -544,9 +538,11 @@ parse_int:
544} 538}
545 539
546 540
547/* Reads the config file and modifies the options accordingly. Options should 541/*
548 already be initialized before this call. This never returns if there 542 * Reads the config file and modifies the options accordingly. Options
549 is an error. If the file does not exist, this returns immediately. */ 543 * should already be initialized before this call. This never returns if
544 * there is an error. If the file does not exist, this returns immediately.
545 */
550 546
551void 547void
552read_config_file(const char *filename, const char *host, Options *options) 548read_config_file(const char *filename, const char *host, Options *options)
@@ -563,8 +559,10 @@ read_config_file(const char *filename, const char *host, Options *options)
563 559
564 debug("Reading configuration data %.200s", filename); 560 debug("Reading configuration data %.200s", filename);
565 561
566 /* Mark that we are now processing the options. This flag is 562 /*
567 turned on/off by Host specifications. */ 563 * Mark that we are now processing the options. This flag is turned
564 * on/off by Host specifications.
565 */
568 active = 1; 566 active = 1;
569 linenum = 0; 567 linenum = 0;
570 while (fgets(line, sizeof(line), f)) { 568 while (fgets(line, sizeof(line), f)) {
@@ -579,10 +577,12 @@ read_config_file(const char *filename, const char *host, Options *options)
579 filename, bad_options); 577 filename, bad_options);
580} 578}
581 579
582/* Initializes options to special values that indicate that they have not 580/*
583 yet been set. Read_config_file will only set options with this value. 581 * Initializes options to special values that indicate that they have not yet
584 Options are processed in the following order: command line, user config 582 * been set. Read_config_file will only set options with this value. Options
585 file, system config file. Last, fill_default_options is called. */ 583 * are processed in the following order: command line, user config file,
584 * system config file. Last, fill_default_options is called.
585 */
586 586
587void 587void
588initialize_options(Options * options) 588initialize_options(Options * options)
@@ -628,8 +628,10 @@ initialize_options(Options * options)
628 options->log_level = (LogLevel) - 1; 628 options->log_level = (LogLevel) - 1;
629} 629}
630 630
631/* Called after processing other sources of option data, this fills those 631/*
632 options for which no value has been specified with their default values. */ 632 * Called after processing other sources of option data, this fills those
633 * options for which no value has been specified with their default values.
634 */
633 635
634void 636void
635fill_default_options(Options * options) 637fill_default_options(Options * options)
diff --git a/readconf.h b/readconf.h
index aeec53a75..d594a46d7 100644
--- a/readconf.h
+++ b/readconf.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: readconf.h,v 1.4 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: readconf.h,v 1.5 1999/11/25 00:54:59 damien Exp $"); */
17 17
18#ifndef READCONF_H 18#ifndef READCONF_H
19#define READCONF_H 19#define READCONF_H
@@ -85,42 +85,53 @@ typedef struct {
85} Options; 85} Options;
86 86
87 87
88/* Initializes options to special values that indicate that they have not 88/*
89 yet been set. Read_config_file will only set options with this value. 89 * Initializes options to special values that indicate that they have not yet
90 Options are processed in the following order: command line, user config 90 * been set. Read_config_file will only set options with this value. Options
91 file, system config file. Last, fill_default_options is called. */ 91 * are processed in the following order: command line, user config file,
92 * system config file. Last, fill_default_options is called.
93 */
92void initialize_options(Options * options); 94void initialize_options(Options * options);
93 95
94/* Called after processing other sources of option data, this fills those 96/*
95 options for which no value has been specified with their default values. */ 97 * Called after processing other sources of option data, this fills those
98 * options for which no value has been specified with their default values.
99 */
96void fill_default_options(Options * options); 100void fill_default_options(Options * options);
97 101
98/* Processes a single option line as used in the configuration files. 102/*
99 This only sets those values that have not already been set. 103 * Processes a single option line as used in the configuration files. This
100 Returns 0 for legal options */ 104 * only sets those values that have not already been set. Returns 0 for legal
105 * options
106 */
101int 107int
102process_config_line(Options * options, const char *host, 108process_config_line(Options * options, const char *host,
103 char *line, const char *filename, int linenum, 109 char *line, const char *filename, int linenum,
104 int *activep); 110 int *activep);
105 111
106/* Reads the config file and modifies the options accordingly. Options should 112/*
107 already be initialized before this call. This never returns if there 113 * Reads the config file and modifies the options accordingly. Options
108 is an error. If the file does not exist, this returns immediately. */ 114 * should already be initialized before this call. This never returns if
115 * there is an error. If the file does not exist, this returns immediately.
116 */
109void 117void
110read_config_file(const char *filename, const char *host, 118read_config_file(const char *filename, const char *host,
111 Options * options); 119 Options * options);
112 120
113/* Adds a local TCP/IP port forward to options. Never returns if there 121/*
114 is an error. */ 122 * Adds a local TCP/IP port forward to options. Never returns if there is an
123 * error.
124 */
115void 125void
116add_local_forward(Options * options, int port, const char *host, 126add_local_forward(Options * options, int port, const char *host,
117 int host_port); 127 int host_port);
118 128
119/* Adds a remote TCP/IP port forward to options. Never returns if there 129/*
120 is an error. */ 130 * Adds a remote TCP/IP port forward to options. Never returns if there is
131 * an error.
132 */
121void 133void
122add_remote_forward(Options * options, int port, const char *host, 134add_remote_forward(Options * options, int port, const char *host,
123 int host_port); 135 int host_port);
124 136
125
126#endif /* READCONF_H */ 137#endif /* READCONF_H */
diff --git a/readpass.c b/readpass.c
index 66ce33c97..5b7119fd7 100644
--- a/readpass.c
+++ b/readpass.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: readpass.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); 17RCSID("$Id: readpass.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
18 18
19#include "xmalloc.h" 19#include "xmalloc.h"
20#include "ssh.h" 20#include "ssh.h"
@@ -38,10 +38,12 @@ intr_handler(int sig)
38 kill(getpid(), sig); 38 kill(getpid(), sig);
39} 39}
40 40
41/* Reads a passphrase from /dev/tty with echo turned off. Returns the 41/*
42 passphrase (allocated with xmalloc). Exits if EOF is encountered. 42 * Reads a passphrase from /dev/tty with echo turned off. Returns the
43 The passphrase if read from stdin if from_stdin is true (as is the 43 * passphrase (allocated with xmalloc). Exits if EOF is encountered. The
44 case with ssh-keygen). */ 44 * passphrase if read from stdin if from_stdin is true (as is the case with
45 * ssh-keygen).
46 */
45 47
46char * 48char *
47read_passphrase(const char *prompt, int from_stdin) 49read_passphrase(const char *prompt, int from_stdin)
@@ -53,8 +55,10 @@ read_passphrase(const char *prompt, int from_stdin)
53 if (from_stdin) 55 if (from_stdin)
54 f = stdin; 56 f = stdin;
55 else { 57 else {
56 /* Read the passphrase from /dev/tty to make it possible 58 /*
57 to ask it even when stdin has been redirected. */ 59 * Read the passphrase from /dev/tty to make it possible to
60 * ask it even when stdin has been redirected.
61 */
58 f = fopen("/dev/tty", "r"); 62 f = fopen("/dev/tty", "r");
59 if (!f) { 63 if (!f) {
60 /* No controlling terminal and no DISPLAY. Nowhere to read. */ 64 /* No controlling terminal and no DISPLAY. Nowhere to read. */
@@ -101,8 +105,10 @@ read_passphrase(const char *prompt, int from_stdin)
101 *strchr(buf, '\n') = 0; 105 *strchr(buf, '\n') = 0;
102 /* Allocate a copy of the passphrase. */ 106 /* Allocate a copy of the passphrase. */
103 cp = xstrdup(buf); 107 cp = xstrdup(buf);
104 /* Clear the buffer so we don\'t leave copies of the passphrase 108 /*
105 laying around. */ 109 * Clear the buffer so we don\'t leave copies of the passphrase
110 * laying around.
111 */
106 memset(buf, 0, sizeof(buf)); 112 memset(buf, 0, sizeof(buf));
107 /* Print a newline since the prompt probably didn\'t have one. */ 113 /* Print a newline since the prompt probably didn\'t have one. */
108 fprintf(stderr, "\n"); 114 fprintf(stderr, "\n");
diff --git a/rsa.c b/rsa.c
index 5228fd398..ab4859563 100644
--- a/rsa.c
+++ b/rsa.c
@@ -35,7 +35,7 @@
35*/ 35*/
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$Id: rsa.c,v 1.4 1999/11/24 13:26:22 damien Exp $"); 38RCSID("$Id: rsa.c,v 1.5 1999/11/25 00:54:59 damien Exp $");
39 39
40#include "rsa.h" 40#include "rsa.h"
41#include "ssh.h" 41#include "ssh.h"
@@ -55,9 +55,11 @@ rsa_alive()
55 return (1); 55 return (1);
56} 56}
57 57
58/* Generates RSA public and private keys. This initializes the data 58/*
59 structures; they should be freed with rsa_clear_private_key and 59 * Generates RSA public and private keys. This initializes the data
60 rsa_clear_public_key. */ 60 * structures; they should be freed with rsa_clear_private_key and
61 * rsa_clear_public_key.
62 */
61 63
62void 64void
63rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits) 65rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits)
diff --git a/rsa.h b/rsa.h
index 31acb2dac..485a94dcd 100644
--- a/rsa.h
+++ b/rsa.h
@@ -13,7 +13,7 @@
13 * 13 *
14*/ 14*/
15 15
16/* RCSID("$Id: rsa.h,v 1.4 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: rsa.h,v 1.5 1999/11/25 00:54:59 damien Exp $"); */
17 17
18#ifndef RSA_H 18#ifndef RSA_H
19#define RSA_H 19#define RSA_H
@@ -33,8 +33,10 @@
33/* Calls SSL RSA_generate_key, only copies to prv and pub */ 33/* Calls SSL RSA_generate_key, only copies to prv and pub */
34void rsa_generate_key(RSA * prv, RSA * pub, unsigned int bits); 34void rsa_generate_key(RSA * prv, RSA * pub, unsigned int bits);
35 35
36/* Indicates whether the rsa module is permitted to show messages on 36/*
37 the terminal. */ 37 * Indicates whether the rsa module is permitted to show messages on the
38 * terminal.
39 */
38void rsa_set_verbose __P((int verbose)); 40void rsa_set_verbose __P((int verbose));
39 41
40int rsa_alive __P((void)); 42int rsa_alive __P((void));
diff --git a/scp.c b/scp.c
index 977c38984..faa18277e 100644
--- a/scp.c
+++ b/scp.c
@@ -45,7 +45,7 @@
45 */ 45 */
46 46
47#include "includes.h" 47#include "includes.h"
48RCSID("$Id: scp.c,v 1.9 1999/11/24 13:26:22 damien Exp $"); 48RCSID("$Id: scp.c,v 1.10 1999/11/25 00:54:59 damien Exp $");
49 49
50#include "ssh.h" 50#include "ssh.h"
51#include "xmalloc.h" 51#include "xmalloc.h"
@@ -97,9 +97,11 @@ char *identity = NULL;
97/* This is the port to use in contacting the remote site (is non-NULL). */ 97/* This is the port to use in contacting the remote site (is non-NULL). */
98char *port = NULL; 98char *port = NULL;
99 99
100/* This function executes the given command as the specified user on the given 100/*
101 host. This returns < 0 if execution fails, and >= 0 otherwise. 101 * This function executes the given command as the specified user on the
102 This assigns the input and output file descriptors on success. */ 102 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This
103 * assigns the input and output file descriptors on success.
104 */
103 105
104int 106int
105do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) 107do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
@@ -110,8 +112,10 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
110 fprintf(stderr, "Executing: host %s, user %s, command %s\n", 112 fprintf(stderr, "Executing: host %s, user %s, command %s\n",
111 host, remuser ? remuser : "(unspecified)", cmd); 113 host, remuser ? remuser : "(unspecified)", cmd);
112 114
113 /* Reserve two descriptors so that the real pipes won't get 115 /*
114 descriptors 0 and 1 because that will screw up dup2 below. */ 116 * Reserve two descriptors so that the real pipes won't get
117 * descriptors 0 and 1 because that will screw up dup2 below.
118 */
115 pipe(reserved); 119 pipe(reserved);
116 120
117 /* Create a socket pair for communicating with ssh. */ 121 /* Create a socket pair for communicating with ssh. */
@@ -970,7 +974,7 @@ run_err(const char *fmt,...)
970 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 974 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
971 * SUCH DAMAGE. 975 * SUCH DAMAGE.
972 * 976 *
973 * $Id: scp.c,v 1.9 1999/11/24 13:26:22 damien Exp $ 977 * $Id: scp.c,v 1.10 1999/11/25 00:54:59 damien Exp $
974 */ 978 */
975 979
976char * 980char *
@@ -1142,7 +1146,7 @@ progressmeter(int flag)
1142 (void) gettimeofday(&now, (struct timezone *) 0); 1146 (void) gettimeofday(&now, (struct timezone *) 0);
1143 cursize = statbytes; 1147 cursize = statbytes;
1144 if (totalbytes != 0) { 1148 if (totalbytes != 0) {
1145 ratio = cursize * 100.0 / totalbytes; 1149 ratio = 100.0 * cursize / totalbytes;
1146 ratio = MAX(ratio, 0); 1150 ratio = MAX(ratio, 0);
1147 ratio = MIN(ratio, 100); 1151 ratio = MIN(ratio, 100);
1148 } else 1152 } else
diff --git a/servconf.c b/servconf.c
index aa7d5b781..99cccbf21 100644
--- a/servconf.c
+++ b/servconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$Id: servconf.c,v 1.6 1999/11/24 13:26:22 damien Exp $"); 15RCSID("$Id: servconf.c,v 1.7 1999/11/25 00:54:59 damien Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "servconf.h" 18#include "servconf.h"
@@ -212,8 +212,10 @@ static struct {
212 { NULL, 0 } 212 { NULL, 0 }
213}; 213};
214 214
215/* Returns the number of the token pointed to by cp of length len. 215/*
216 Never returns if the token is not known. */ 216 * Returns the number of the token pointed to by cp of length len. Never
217 * returns if the token is not known.
218 */
217 219
218static ServerOpCodes 220static ServerOpCodes
219parse_token(const char *cp, const char *filename, 221parse_token(const char *cp, const char *filename,
@@ -222,7 +224,7 @@ parse_token(const char *cp, const char *filename,
222 unsigned int i; 224 unsigned int i;
223 225
224 for (i = 0; keywords[i].name; i++) 226 for (i = 0; keywords[i].name; i++)
225 if (strcmp(cp, keywords[i].name) == 0) 227 if (strcasecmp(cp, keywords[i].name) == 0)
226 return keywords[i].opcode; 228 return keywords[i].opcode;
227 229
228 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", 230 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
@@ -254,13 +256,6 @@ read_server_config(ServerOptions *options, const char *filename)
254 if (!*cp || *cp == '#') 256 if (!*cp || *cp == '#')
255 continue; 257 continue;
256 cp = strtok(cp, WHITESPACE); 258 cp = strtok(cp, WHITESPACE);
257 {
258 char *t = cp;
259 for (; *t != 0; t++)
260 if ('A' <= *t && *t <= 'Z')
261 *t = *t - 'A' + 'a'; /* tolower */
262
263 }
264 opcode = parse_token(cp, filename, linenum); 259 opcode = parse_token(cp, filename, linenum);
265 switch (opcode) { 260 switch (opcode) {
266 case sBadOption: 261 case sBadOption:
diff --git a/servconf.h b/servconf.h
index 4f3238e0c..e3ac5bdee 100644
--- a/servconf.h
+++ b/servconf.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: servconf.h,v 1.4 1999/11/24 13:26:22 damien Exp $"); */ 16/* RCSID("$Id: servconf.h,v 1.5 1999/11/25 00:54:59 damien Exp $"); */
17 17
18#ifndef SERVCONF_H 18#ifndef SERVCONF_H
19#define SERVCONF_H 19#define SERVCONF_H
@@ -84,12 +84,16 @@ typedef struct {
84 unsigned int num_deny_groups; 84 unsigned int num_deny_groups;
85 char *deny_groups[MAX_DENY_GROUPS]; 85 char *deny_groups[MAX_DENY_GROUPS];
86} ServerOptions; 86} ServerOptions;
87/* Initializes the server options to special values that indicate that they 87/*
88 have not yet been set. */ 88 * Initializes the server options to special values that indicate that they
89 * have not yet been set.
90 */
89void initialize_server_options(ServerOptions * options); 91void initialize_server_options(ServerOptions * options);
90 92
91/* Reads the server configuration file. This only sets the values for those 93/*
92 options that have the special value indicating they have not been set. */ 94 * Reads the server configuration file. This only sets the values for those
95 * options that have the special value indicating they have not been set.
96 */
93void read_server_config(ServerOptions * options, const char *filename); 97void read_server_config(ServerOptions * options, const char *filename);
94 98
95/* Sets values for those values that have not yet been set. */ 99/* Sets values for those values that have not yet been set. */
diff --git a/serverloop.c b/serverloop.c
index fc959baef..683598ef8 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -33,8 +33,10 @@ static int connection_out; /* Connection to client (output). */
33static unsigned int buffer_high;/* "Soft" max buffer size. */ 33static unsigned int buffer_high;/* "Soft" max buffer size. */
34static int max_fd; /* Max file descriptor number for select(). */ 34static int max_fd; /* Max file descriptor number for select(). */
35 35
36/* This SIGCHLD kludge is used to detect when the child exits. The server 36/*
37 will exit after that, as soon as forwarded connections have terminated. */ 37 * This SIGCHLD kludge is used to detect when the child exits. The server
38 * will exit after that, as soon as forwarded connections have terminated.
39 */
38 40
39static int child_pid; /* Pid of the child. */ 41static int child_pid; /* Pid of the child. */
40static volatile int child_terminated; /* The child has terminated. */ 42static volatile int child_terminated; /* The child has terminated. */
@@ -87,9 +89,11 @@ process_buffered_input_packets()
87 break; 89 break;
88 90
89 case SSH_CMSG_EOF: 91 case SSH_CMSG_EOF:
90 /* Eof from the client. The stdin descriptor to 92 /*
91 the program will be closed when all buffered 93 * Eof from the client. The stdin descriptor to the
92 data has drained. */ 94 * program will be closed when all buffered data has
95 * drained.
96 */
93 debug("EOF received for stdin."); 97 debug("EOF received for stdin.");
94 packet_integrity_check(payload_len, 0, type); 98 packet_integrity_check(payload_len, 0, type);
95 stdin_eof = 1; 99 stdin_eof = 1;
@@ -140,13 +144,15 @@ process_buffered_input_packets()
140 break; 144 break;
141 145
142 default: 146 default:
143 /* In this phase, any unexpected messages cause a 147 /*
144 protocol error. This is to ease debugging; 148 * In this phase, any unexpected messages cause a
145 also, since no confirmations are sent messages, 149 * protocol error. This is to ease debugging; also,
146 unprocessed unknown messages could cause 150 * since no confirmations are sent messages,
147 strange problems. Any compatible protocol 151 * unprocessed unknown messages could cause strange
148 extensions must be negotiated before entering 152 * problems. Any compatible protocol extensions must
149 the interactive session. */ 153 * be negotiated before entering the interactive
154 * session.
155 */
150 packet_disconnect("Protocol error during session: type %d", 156 packet_disconnect("Protocol error during session: type %d",
151 type); 157 type);
152 } 158 }
@@ -230,14 +236,18 @@ retry_select:
230 /* Initialize select() masks. */ 236 /* Initialize select() masks. */
231 FD_ZERO(readset); 237 FD_ZERO(readset);
232 238
233 /* Read packets from the client unless we have too much buffered 239 /*
234 stdin or channel data. */ 240 * Read packets from the client unless we have too much buffered
241 * stdin or channel data.
242 */
235 if (buffer_len(&stdin_buffer) < 4096 && 243 if (buffer_len(&stdin_buffer) < 4096 &&
236 channel_not_very_much_buffered_data()) 244 channel_not_very_much_buffered_data())
237 FD_SET(connection_in, readset); 245 FD_SET(connection_in, readset);
238 246
239 /* If there is not too much data already buffered going to the 247 /*
240 client, try to get some more data from the program. */ 248 * If there is not too much data already buffered going to the
249 * client, try to get some more data from the program.
250 */
241 if (packet_not_very_much_data_to_write()) { 251 if (packet_not_very_much_data_to_write()) {
242 if (!fdout_eof) 252 if (!fdout_eof)
243 FD_SET(fdout, readset); 253 FD_SET(fdout, readset);
@@ -249,8 +259,10 @@ retry_select:
249 /* Set masks for channel descriptors. */ 259 /* Set masks for channel descriptors. */
250 channel_prepare_select(readset, writeset); 260 channel_prepare_select(readset, writeset);
251 261
252 /* If we have buffered packet data going to the client, mark that 262 /*
253 descriptor. */ 263 * If we have buffered packet data going to the client, mark that
264 * descriptor.
265 */
254 if (packet_have_data_to_write()) 266 if (packet_have_data_to_write())
255 FD_SET(connection_out, writeset); 267 FD_SET(connection_out, writeset);
256 268
@@ -263,8 +275,10 @@ retry_select:
263 if (channel_max_fd() > max_fd) 275 if (channel_max_fd() > max_fd)
264 max_fd = channel_max_fd(); 276 max_fd = channel_max_fd();
265 277
266 /* If child has terminated and there is enough buffer space to 278 /*
267 read from it, then read as much as is available and exit. */ 279 * If child has terminated and there is enough buffer space to read
280 * from it, then read as much as is available and exit.
281 */
268 if (child_terminated && packet_not_very_much_data_to_write()) 282 if (child_terminated && packet_not_very_much_data_to_write())
269 if (max_time_milliseconds == 0) 283 if (max_time_milliseconds == 0)
270 max_time_milliseconds = 100; 284 max_time_milliseconds = 100;
@@ -305,9 +319,10 @@ process_input(fd_set * readset)
305 verbose("Connection closed by remote host."); 319 verbose("Connection closed by remote host.");
306 fatal_cleanup(); 320 fatal_cleanup();
307 } 321 }
308 /* There is a kernel bug on Solaris that causes select to 322 /*
309 sometimes wake up even though there is no data 323 * There is a kernel bug on Solaris that causes select to
310 available. */ 324 * sometimes wake up even though there is no data available.
325 */
311 if (len < 0 && errno == EAGAIN) 326 if (len < 0 && errno == EAGAIN)
312 len = 0; 327 len = 0;
313 328
@@ -456,11 +471,12 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
456 buffer_init(&stdout_buffer); 471 buffer_init(&stdout_buffer);
457 buffer_init(&stderr_buffer); 472 buffer_init(&stderr_buffer);
458 473
459 /* If we have no separate fderr (which is the case when we have a 474 /*
460 pty - there we cannot make difference between data sent to 475 * If we have no separate fderr (which is the case when we have a pty
461 stdout and stderr), indicate that we have seen an EOF from 476 * - there we cannot make difference between data sent to stdout and
462 stderr. This way we don\'t need to check the descriptor 477 * stderr), indicate that we have seen an EOF from stderr. This way
463 everywhere. */ 478 * we don\'t need to check the descriptor everywhere.
479 */
464 if (fderr == -1) 480 if (fderr == -1)
465 fderr_eof = 1; 481 fderr_eof = 1;
466 482
@@ -471,8 +487,10 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
471 /* Process buffered packets from the client. */ 487 /* Process buffered packets from the client. */
472 process_buffered_input_packets(); 488 process_buffered_input_packets();
473 489
474 /* If we have received eof, and there is no more pending 490 /*
475 input data, cause a real eof by closing fdin. */ 491 * If we have received eof, and there is no more pending
492 * input data, cause a real eof by closing fdin.
493 */
476 if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { 494 if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
477#ifdef USE_PIPES 495#ifdef USE_PIPES
478 close(fdin); 496 close(fdin);
@@ -484,16 +502,16 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
484#endif 502#endif
485 fdin = -1; 503 fdin = -1;
486 } 504 }
487 /* Make packets from buffered stderr data to send to the 505 /* Make packets from buffered stderr data to send to the client. */
488 client. */
489 make_packets_from_stderr_data(); 506 make_packets_from_stderr_data();
490 507
491 /* Make packets from buffered stdout data to send to the 508 /*
492 client. If there is very little to send, this arranges 509 * Make packets from buffered stdout data to send to the
493 to not send them now, but to wait a short while to see 510 * client. If there is very little to send, this arranges to
494 if we are getting more data. This is necessary, as some 511 * not send them now, but to wait a short while to see if we
495 systems wake up readers from a pty after each separate 512 * are getting more data. This is necessary, as some systems
496 character. */ 513 * wake up readers from a pty after each separate character.
514 */
497 max_time_milliseconds = 0; 515 max_time_milliseconds = 0;
498 stdout_buffer_bytes = buffer_len(&stdout_buffer); 516 stdout_buffer_bytes = buffer_len(&stdout_buffer);
499 if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 && 517 if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
@@ -510,9 +528,11 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
510 if (packet_not_very_much_data_to_write()) 528 if (packet_not_very_much_data_to_write())
511 channel_output_poll(); 529 channel_output_poll();
512 530
513 /* Bail out of the loop if the program has closed its 531 /*
514 output descriptors, and we have no more data to send to 532 * Bail out of the loop if the program has closed its output
515 the client, and there is no pending buffered data. */ 533 * descriptors, and we have no more data to send to the
534 * client, and there is no pending buffered data.
535 */
516 if (fdout_eof && fderr_eof && !packet_have_data_to_write() && 536 if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
517 buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) { 537 buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
518 if (!channel_still_open()) 538 if (!channel_still_open())
@@ -604,11 +624,13 @@ quit:
604 packet_send(); 624 packet_send();
605 packet_write_wait(); 625 packet_write_wait();
606 626
607 /* Wait for exit confirmation. Note that there might be 627 /*
608 other packets coming before it; however, the program 628 * Wait for exit confirmation. Note that there might be
609 has already died so we just ignore them. The client is 629 * other packets coming before it; however, the program has
610 supposed to respond with the confirmation when it 630 * already died so we just ignore them. The client is
611 receives the exit status. */ 631 * supposed to respond with the confirmation when it receives
632 * the exit status.
633 */
612 do { 634 do {
613 int plen; 635 int plen;
614 type = packet_read(&plen); 636 type = packet_read(&plen);
diff --git a/ssh-add.1 b/ssh-add.1
index cbcca4718..67e09b467 100644
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 23:55:14 1995 ylo 10.\" Created: Sat Apr 22 23:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: ssh-add.1,v 1.4 1999/11/17 06:29:08 damien Exp $ 12.\" $Id: ssh-add.1,v 1.5 1999/11/25 00:54:59 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH-ADD 1 15.Dt SSH-ADD 1
@@ -71,8 +71,11 @@ terminal if it was run from a terminal. If
71.Nm 71.Nm
72does not have a terminal associated with it but 72does not have a terminal associated with it but
73.Ev DISPLAY 73.Ev DISPLAY
74is set, it 74and
75will open an X11 window to read the passphrase. This is particularly 75.Ev SSH_ASKPASS
76are set, it will execute the program specified by
77.Ev SSH_ASKPASS
78and open an X11 window to read the passphrase. This is particularly
76useful when calling 79useful when calling
77.Nm 80.Nm
78from a 81from a
diff --git a/ssh-add.c b/ssh-add.c
index f94dcdabb..711ae126e 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -7,7 +7,7 @@
7 */ 7 */
8 8
9#include "includes.h" 9#include "includes.h"
10RCSID("$Id: ssh-add.c,v 1.13 1999/11/24 13:26:22 damien Exp $"); 10RCSID("$Id: ssh-add.c,v 1.14 1999/11/25 00:54:59 damien Exp $");
11 11
12#include "rsa.h" 12#include "rsa.h"
13#include "ssh.h" 13#include "ssh.h"
@@ -15,10 +15,6 @@ RCSID("$Id: ssh-add.c,v 1.13 1999/11/24 13:26:22 damien Exp $");
15#include "authfd.h" 15#include "authfd.h"
16#include "fingerprint.h" 16#include "fingerprint.h"
17 17
18#ifdef USE_EXTERNAL_ASKPASS
19int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment);
20#endif /* USE_EXTERNAL_ASKPASS */
21
22#ifdef HAVE___PROGNAME 18#ifdef HAVE___PROGNAME
23extern char *__progname; 19extern char *__progname;
24#else /* HAVE___PROGNAME */ 20#else /* HAVE___PROGNAME */
@@ -54,13 +50,53 @@ delete_all(AuthenticationConnection *ac)
54 fprintf(stderr, "Failed to remove all identitities.\n"); 50 fprintf(stderr, "Failed to remove all identitities.\n");
55} 51}
56 52
53char *
54ssh_askpass(char *askpass, char *msg)
55{
56 pid_t pid;
57 size_t len;
58 char *nl, *pass;
59 int p[2], status;
60 char buf[1024];
61
62 if (askpass == NULL)
63 fatal("internal error: askpass undefined");
64 if (pipe(p) < 0)
65 fatal("ssh_askpass: pipe: %s", strerror(errno));
66 if ((pid = fork()) < 0)
67 fatal("ssh_askpass: fork: %s", strerror(errno));
68 if (pid == 0) {
69 close(p[0]);
70 if (dup2(p[1], STDOUT_FILENO) < 0)
71 fatal("ssh_askpass: dup2: %s", strerror(errno));
72 execlp(askpass, askpass, msg, (char *) 0);
73 fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
74 }
75 close(p[1]);
76 len = read(p[0], buf, sizeof buf);
77 close(p[0]);
78 while (waitpid(pid, &status, 0) < 0)
79 if (errno != EINTR)
80 break;
81 if (len <= 1)
82 return xstrdup("");
83 nl = strchr(buf, '\n');
84 if (nl)
85 *nl = '\0';
86 pass = xstrdup(buf);
87 memset(buf, 0, sizeof(buf));
88 return pass;
89}
90
57void 91void
58add_file(AuthenticationConnection *ac, const char *filename) 92add_file(AuthenticationConnection *ac, const char *filename)
59{ 93{
60 RSA *key; 94 RSA *key;
61 RSA *public_key; 95 RSA *public_key;
62 char *saved_comment, *comment; 96 char *saved_comment, *comment, *askpass = NULL;
97 char buf[1024], msg[1024];
63 int success; 98 int success;
99 int interactive = isatty(STDIN_FILENO);
64 100
65 key = RSA_new(); 101 key = RSA_new();
66 public_key = RSA_new(); 102 public_key = RSA_new();
@@ -70,29 +106,26 @@ add_file(AuthenticationConnection *ac, const char *filename)
70 } 106 }
71 RSA_free(public_key); 107 RSA_free(public_key);
72 108
109 if (!interactive && getenv("DISPLAY"))
110 askpass = getenv("SSH_ASKPASS");
111
73 /* At first, try empty passphrase */ 112 /* At first, try empty passphrase */
74 success = load_private_key(filename, "", key, &comment); 113 success = load_private_key(filename, "", key, &comment);
75 if (!success) { 114 if (!success) {
76 printf("Need passphrase for %s (%s).\n", filename, saved_comment); 115 printf("Need passphrase for %.200s\n", filename);
77 if (!isatty(STDIN_FILENO)) { 116 if (!interactive && askpass == NULL) {
78#ifdef USE_EXTERNAL_ASKPASS 117 xfree(saved_comment);
79 int prompts = 3; 118 return;
80 while (prompts && !success) {
81 success = askpass(filename, key, saved_comment, &comment);
82 prompts--;
83 }
84 if (!success) {
85 xfree(saved_comment);
86 return;
87 }
88#else /* !USE_EXTERNAL_ASKPASS */
89 xfree(saved_comment);
90 return;
91#endif /* USE_EXTERNAL_ASKPASS */
92 } 119 }
93 120 snprintf(msg, sizeof msg, "Enter passphrase for %.200s", saved_comment);
94 while (!success) { 121 for (;;) {
95 char *pass = read_passphrase("Enter passphrase: ", 1); 122 char *pass;
123 if (interactive) {
124 snprintf(buf, sizeof buf, "%s: ", msg);
125 pass = read_passphrase(buf, 1);
126 } else {
127 pass = ssh_askpass(askpass, msg);
128 }
96 if (strcmp(pass, "") == 0) { 129 if (strcmp(pass, "") == 0) {
97 xfree(pass); 130 xfree(pass);
98 xfree(saved_comment); 131 xfree(saved_comment);
@@ -103,7 +136,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
103 xfree(pass); 136 xfree(pass);
104 if (success) 137 if (success)
105 break; 138 break;
106 printf("Bad passphrase.\n"); 139 strlcpy(msg, "Bad passphrase, try again", sizeof msg);
107 } 140 }
108 } 141 }
109 xfree(saved_comment); 142 xfree(saved_comment);
@@ -222,85 +255,3 @@ main(int argc, char **argv)
222 ssh_close_authentication_connection(ac); 255 ssh_close_authentication_connection(ac);
223 exit(0); 256 exit(0);
224} 257}
225
226#ifdef USE_EXTERNAL_ASKPASS
227int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment)
228{
229 int pipes[2];
230 char buf[1024];
231 int tmp;
232 pid_t child;
233 FILE *pipef;
234
235 /* Check that we are X11-capable */
236 if (getenv("DISPLAY") == NULL)
237 exit(1);
238
239 if (pipe(pipes) == -1) {
240 fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno));
241 exit(1);
242 }
243
244 if (fflush(NULL) == EOF) {
245 fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno));
246 exit(1);
247 }
248
249 child = fork();
250 if (child == -1) {
251 fprintf(stderr, "Cannot fork: %s\n", strerror(errno));
252 exit(1);
253 }
254
255 if (child == 0) {
256 /* In child */
257
258 close(pipes[0]);
259 if (dup2(pipes[1], 1) ==-1) {
260 fprintf(stderr, "dup2 failed: %s\n", strerror(errno));
261 exit(1);
262 }
263
264 tmp = snprintf(buf, sizeof(buf), "Need passphrase for %s", saved_comment);
265 /* skip the prompt if it won't fit */
266 if ((tmp < 0) || (tmp >= sizeof(buf)))
267 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", 0);
268 else
269 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0);
270
271 /* Shouldn't get this far */
272 fprintf(stderr, "Executing ssh-askpass failed: %s\n", strerror(errno));
273 exit(1);
274 }
275
276 /* In parent */
277 close(pipes[1]);
278
279 if ((pipef = fdopen(pipes[0], "r")) == NULL) {
280 fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
281 exit(1);
282 }
283
284 /* Read passphrase back from child, abort if none presented */
285 if(fgets(buf, sizeof(buf), pipef) == NULL)
286 exit(1);
287
288 fclose(pipef);
289
290 if (strchr(buf, '\n'))
291 *strchr(buf, '\n') = 0;
292
293 if (waitpid(child, NULL, 0) == -1) {
294 fprintf(stderr, "Waiting for child failed: %s\n",
295 strerror(errno));
296 exit(1);
297 }
298
299 /* Try password as it was presented */
300 tmp = load_private_key(filename, buf, key, comment);
301
302 memset(buf, 0, sizeof(buf));
303
304 return(tmp);
305}
306#endif /* USE_EXTERNAL_ASKPASS */
diff --git a/ssh-agent.c b/ssh-agent.c
index 70c2a7f65..90c64ea8a 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.22 1999/11/24 00:26:03 deraadt Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.23 1999/11/24 19:53:51 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -9,7 +9,7 @@
9 */ 9 */
10 10
11#include "includes.h" 11#include "includes.h"
12RCSID("$OpenBSD: ssh-agent.c,v 1.22 1999/11/24 00:26:03 deraadt Exp $"); 12RCSID("$OpenBSD: ssh-agent.c,v 1.23 1999/11/24 19:53:51 markus Exp $");
13 13
14#include "ssh.h" 14#include "ssh.h"
15#include "rsa.h" 15#include "rsa.h"
@@ -189,10 +189,12 @@ process_remove_identity(SocketEntry *e)
189 /* Check if we have the key. */ 189 /* Check if we have the key. */
190 for (i = 0; i < num_identities; i++) 190 for (i = 0; i < num_identities; i++)
191 if (BN_cmp(identities[i].key->n, n) == 0) { 191 if (BN_cmp(identities[i].key->n, n) == 0) {
192 /* We have this key. Free the old key. Since we 192 /*
193 don\'t want to leave empty slots in the middle 193 * We have this key. Free the old key. Since we
194 of the array, we actually free the key there 194 * don\'t want to leave empty slots in the middle of
195 and copy data from the last entry. */ 195 * the array, we actually free the key there and copy
196 * data from the last entry.
197 */
196 RSA_free(identities[i].key); 198 RSA_free(identities[i].key);
197 xfree(identities[i].comment); 199 xfree(identities[i].comment);
198 if (i < num_identities - 1) 200 if (i < num_identities - 1)
@@ -291,8 +293,10 @@ process_add_identity(SocketEntry *e)
291 /* Check if we already have the key. */ 293 /* Check if we already have the key. */
292 for (i = 0; i < num_identities; i++) 294 for (i = 0; i < num_identities; i++)
293 if (BN_cmp(identities[i].key->n, k->n) == 0) { 295 if (BN_cmp(identities[i].key->n, k->n) == 0) {
294 /* We already have this key. Clear and free the 296 /*
295 new data and return success. */ 297 * We already have this key. Clear and free the new
298 * data and return success.
299 */
296 RSA_free(k); 300 RSA_free(k);
297 xfree(identities[num_identities].comment); 301 xfree(identities[num_identities].comment);
298 302
@@ -511,11 +515,7 @@ main(int ac, char **av)
511 __progname); 515 __progname);
512 exit(1); 516 exit(1);
513 } 517 }
514#if defined(__GNU_LIBRARY__)
515 while ((ch = getopt(ac, av, "+cks")) != -1) {
516#else
517 while ((ch = getopt(ac, av, "cks")) != -1) { 518 while ((ch = getopt(ac, av, "cks")) != -1) {
518#endif /* defined(__GNU_LIBRARY__) */
519 switch (ch) { 519 switch (ch) {
520 case 'c': 520 case 'c':
521 if (s_flag) 521 if (s_flag)
@@ -579,8 +579,10 @@ main(int ac, char **av)
579 snprintf(socket_name, sizeof socket_name, "%s/agent.%d", socket_dir, 579 snprintf(socket_name, sizeof socket_name, "%s/agent.%d", socket_dir,
580 parent_pid); 580 parent_pid);
581 581
582 /* Create socket early so it will exist before command gets run 582 /*
583 from the parent. */ 583 * Create socket early so it will exist before command gets run from
584 * the parent.
585 */
584 sock = socket(AF_UNIX, SOCK_STREAM, 0); 586 sock = socket(AF_UNIX, SOCK_STREAM, 0);
585 if (sock < 0) { 587 if (sock < 0) {
586 perror("socket"); 588 perror("socket");
@@ -597,9 +599,10 @@ main(int ac, char **av)
597 perror("listen"); 599 perror("listen");
598 cleanup_exit(1); 600 cleanup_exit(1);
599 } 601 }
600 /* Fork, and have the parent execute the command, if any, or 602 /*
601 present the socket data. The child continues as the 603 * Fork, and have the parent execute the command, if any, or present
602 authentication agent. */ 604 * the socket data. The child continues as the authentication agent.
605 */
603 pid = fork(); 606 pid = fork();
604 if (pid == -1) { 607 if (pid == -1) {
605 perror("fork"); 608 perror("fork");
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 6f2d426b8..2b674676d 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -7,7 +7,7 @@
7 */ 7 */
8 8
9#include "includes.h" 9#include "includes.h"
10RCSID("$Id: ssh-keygen.c,v 1.9 1999/11/24 13:26:23 damien Exp $"); 10RCSID("$Id: ssh-keygen.c,v 1.10 1999/11/25 00:54:59 damien Exp $");
11 11
12#include "rsa.h" 12#include "rsa.h"
13#include "ssh.h" 13#include "ssh.h"
@@ -20,16 +20,19 @@ RSA *private_key;
20/* Generated public key. */ 20/* Generated public key. */
21RSA *public_key; 21RSA *public_key;
22 22
23/* Number of bits in the RSA key. This value can be changed on the command 23/* Number of bits in the RSA key. This value can be changed on the command line. */
24 line. */
25int bits = 1024; 24int bits = 1024;
26 25
27/* Flag indicating that we just want to change the passphrase. This can be 26/*
28 set on the command line. */ 27 * Flag indicating that we just want to change the passphrase. This can be
28 * set on the command line.
29 */
29int change_passphrase = 0; 30int change_passphrase = 0;
30 31
31/* Flag indicating that we just want to change the comment. This can be set 32/*
32 on the command line. */ 33 * Flag indicating that we just want to change the comment. This can be set
34 * on the command line.
35 */
33int change_comment = 0; 36int change_comment = 0;
34 37
35int quiet = 0; 38int quiet = 0;
@@ -136,13 +139,10 @@ do_change_passphrase(struct passwd *pw)
136 139
137 if (!have_identity) 140 if (!have_identity)
138 ask_filename(pw, "Enter file in which the key is"); 141 ask_filename(pw, "Enter file in which the key is");
139 /* Check if the file exists. */
140 if (stat(identity_file, &st) < 0) { 142 if (stat(identity_file, &st) < 0) {
141 perror(identity_file); 143 perror(identity_file);
142 exit(1); 144 exit(1);
143 } 145 }
144 /* Try to load the public key from the file the verify that it is
145 readable and of the proper format. */
146 public_key = RSA_new(); 146 public_key = RSA_new();
147 if (!load_public_key(identity_file, public_key, NULL)) { 147 if (!load_public_key(identity_file, public_key, NULL)) {
148 printf("%s is not a valid key file.\n", identity_file); 148 printf("%s is not a valid key file.\n", identity_file);
@@ -154,19 +154,16 @@ do_change_passphrase(struct passwd *pw)
154 /* Try to load the file with empty passphrase. */ 154 /* Try to load the file with empty passphrase. */
155 private_key = RSA_new(); 155 private_key = RSA_new();
156 if (!load_private_key(identity_file, "", private_key, &comment)) { 156 if (!load_private_key(identity_file, "", private_key, &comment)) {
157 /* Read passphrase from the user. */
158 if (identity_passphrase) 157 if (identity_passphrase)
159 old_passphrase = xstrdup(identity_passphrase); 158 old_passphrase = xstrdup(identity_passphrase);
160 else 159 else
161 old_passphrase = read_passphrase("Enter old passphrase: ", 1); 160 old_passphrase = read_passphrase("Enter old passphrase: ", 1);
162 /* Try to load using the passphrase. */
163 if (!load_private_key(identity_file, old_passphrase, private_key, &comment)) { 161 if (!load_private_key(identity_file, old_passphrase, private_key, &comment)) {
164 memset(old_passphrase, 0, strlen(old_passphrase)); 162 memset(old_passphrase, 0, strlen(old_passphrase));
165 xfree(old_passphrase); 163 xfree(old_passphrase);
166 printf("Bad passphrase.\n"); 164 printf("Bad passphrase.\n");
167 exit(1); 165 exit(1);
168 } 166 }
169 /* Destroy the passphrase. */
170 memset(old_passphrase, 0, strlen(old_passphrase)); 167 memset(old_passphrase, 0, strlen(old_passphrase));
171 xfree(old_passphrase); 168 xfree(old_passphrase);
172 } 169 }
@@ -230,24 +227,24 @@ do_change_comment(struct passwd *pw)
230 227
231 if (!have_identity) 228 if (!have_identity)
232 ask_filename(pw, "Enter file in which the key is"); 229 ask_filename(pw, "Enter file in which the key is");
233 /* Check if the file exists. */
234 if (stat(identity_file, &st) < 0) { 230 if (stat(identity_file, &st) < 0) {
235 perror(identity_file); 231 perror(identity_file);
236 exit(1); 232 exit(1);
237 } 233 }
238 /* Try to load the public key from the file the verify that it is 234 /*
239 readable and of the proper format. */ 235 * Try to load the public key from the file the verify that it is
236 * readable and of the proper format.
237 */
240 public_key = RSA_new(); 238 public_key = RSA_new();
241 if (!load_public_key(identity_file, public_key, NULL)) { 239 if (!load_public_key(identity_file, public_key, NULL)) {
242 printf("%s is not a valid key file.\n", identity_file); 240 printf("%s is not a valid key file.\n", identity_file);
243 exit(1); 241 exit(1);
244 } 242 }
245 private_key = RSA_new(); 243 private_key = RSA_new();
246 /* Try to load the file with empty passphrase. */ 244
247 if (load_private_key(identity_file, "", private_key, &comment)) 245 if (load_private_key(identity_file, "", private_key, &comment))
248 passphrase = xstrdup(""); 246 passphrase = xstrdup("");
249 else { 247 else {
250 /* Read passphrase from the user. */
251 if (identity_passphrase) 248 if (identity_passphrase)
252 passphrase = xstrdup(identity_passphrase); 249 passphrase = xstrdup(identity_passphrase);
253 else if (identity_new_passphrase) 250 else if (identity_new_passphrase)
@@ -274,7 +271,6 @@ do_change_comment(struct passwd *pw)
274 RSA_free(private_key); 271 RSA_free(private_key);
275 exit(1); 272 exit(1);
276 } 273 }
277 /* Remove terminating newline from comment. */
278 if (strchr(new_comment, '\n')) 274 if (strchr(new_comment, '\n'))
279 *strchr(new_comment, '\n') = 0; 275 *strchr(new_comment, '\n') = 0;
280 } 276 }
@@ -289,13 +285,10 @@ do_change_comment(struct passwd *pw)
289 xfree(comment); 285 xfree(comment);
290 exit(1); 286 exit(1);
291 } 287 }
292 /* Destroy the passphrase and the private key in memory. */
293 memset(passphrase, 0, strlen(passphrase)); 288 memset(passphrase, 0, strlen(passphrase));
294 xfree(passphrase); 289 xfree(passphrase);
295 RSA_free(private_key); 290 RSA_free(private_key);
296 291
297 /* Save the public key in text format in a file with the same name
298 but .pub appended. */
299 strlcat(identity_file, ".pub", sizeof(identity_file)); 292 strlcat(identity_file, ".pub", sizeof(identity_file));
300 f = fopen(identity_file, "w"); 293 f = fopen(identity_file, "w");
301 if (!f) { 294 if (!f) {
@@ -343,21 +336,18 @@ main(int ac, char **av)
343 336
344 /* check if RSA support exists */ 337 /* check if RSA support exists */
345 if (rsa_alive() == 0) { 338 if (rsa_alive() == 0) {
346 extern char *__progname;
347
348 fprintf(stderr, 339 fprintf(stderr,
349 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", 340 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
350 __progname); 341 __progname);
351 exit(1); 342 exit(1);
352 } 343 }
353 /* Get user\'s passwd structure. We need this for the home 344 /* we need this for the home * directory. */
354 directory. */
355 pw = getpwuid(getuid()); 345 pw = getpwuid(getuid());
356 if (!pw) { 346 if (!pw) {
357 printf("You don't exist, go away!\n"); 347 printf("You don't exist, go away!\n");
358 exit(1); 348 exit(1);
359 } 349 }
360 /* Parse command line arguments. */ 350
361 while ((opt = getopt(ac, av, "qpclb:f:P:N:C:")) != EOF) { 351 while ((opt = getopt(ac, av, "qpclb:f:P:N:C:")) != EOF) {
362 switch (opt) { 352 switch (opt) {
363 case 'b': 353 case 'b':
@@ -416,14 +406,8 @@ main(int ac, char **av)
416 } 406 }
417 if (print_fingerprint) 407 if (print_fingerprint)
418 do_fingerprint(pw); 408 do_fingerprint(pw);
419
420 /* If the user requested to change the passphrase, do it now.
421 This function never returns. */
422 if (change_passphrase) 409 if (change_passphrase)
423 do_change_passphrase(pw); 410 do_change_passphrase(pw);
424
425 /* If the user requested to change the comment, do it now. This
426 function never returns. */
427 if (change_comment) 411 if (change_comment)
428 do_change_comment(pw); 412 do_change_comment(pw);
429 413
@@ -484,11 +468,10 @@ passphrase_again:
484 xfree(passphrase2); 468 xfree(passphrase2);
485 } 469 }
486 470
487 /* Create default commend field for the passphrase. The user can
488 later edit this field. */
489 if (identity_comment) { 471 if (identity_comment) {
490 strlcpy(comment, identity_comment, sizeof(comment)); 472 strlcpy(comment, identity_comment, sizeof(comment));
491 } else { 473 } else {
474 /* Create default commend field for the passphrase. */
492 if (gethostname(hostname, sizeof(hostname)) < 0) { 475 if (gethostname(hostname, sizeof(hostname)) < 0) {
493 perror("gethostname"); 476 perror("gethostname");
494 exit(1); 477 exit(1);
@@ -515,8 +498,6 @@ passphrase_again:
515 if (!quiet) 498 if (!quiet)
516 printf("Your identification has been saved in %s.\n", identity_file); 499 printf("Your identification has been saved in %s.\n", identity_file);
517 500
518 /* Save the public key in text format in a file with the same name
519 but .pub appended. */
520 strlcat(identity_file, ".pub", sizeof(identity_file)); 501 strlcat(identity_file, ".pub", sizeof(identity_file));
521 f = fopen(identity_file, "w"); 502 f = fopen(identity_file, "w");
522 if (!f) { 503 if (!f) {
diff --git a/ssh.1 b/ssh.1
index df7c0b455..537a6e08f 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.9 1999/11/24 13:26:23 damien Exp $ 12.\" $Id: ssh.1,v 1.10 1999/11/25 00:54:59 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH 1 15.Dt SSH 1
@@ -293,7 +293,7 @@ disables any escapes and makes the session fully transparent.
293.It Fl f 293.It Fl f
294Requests 294Requests
295.Nm 295.Nm
296to go to background after authentication. This is useful 296to go to background just before command execution. This is useful
297if 297if
298.Nm 298.Nm
299is going to ask for passwords or passphrases, but the user 299is going to ask for passwords or passphrases, but the user
diff --git a/ssh.c b/ssh.c
index 8d73e61e3..21147f7e8 100644
--- a/ssh.c
+++ b/ssh.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include "includes.h" 13#include "includes.h"
14RCSID("$Id: ssh.c,v 1.11 1999/11/24 13:26:23 damien Exp $"); 14RCSID("$Id: ssh.c,v 1.12 1999/11/25 00:54:59 damien Exp $");
15 15
16#include "xmalloc.h" 16#include "xmalloc.h"
17#include "ssh.h" 17#include "ssh.h"
@@ -30,35 +30,43 @@ const char *__progname = "ssh";
30/* Flag indicating whether debug mode is on. This can be set on the command line. */ 30/* Flag indicating whether debug mode is on. This can be set on the command line. */
31int debug_flag = 0; 31int debug_flag = 0;
32 32
33/* Flag indicating whether to allocate a pseudo tty. This can be set on the command
34 line, and is automatically set if no command is given on the command line. */
35int tty_flag = 0; 33int tty_flag = 0;
36 34
37/* Flag indicating that nothing should be read from stdin. This can be set 35/*
38 on the command line. */ 36 * Flag indicating that nothing should be read from stdin. This can be set
37 * on the command line.
38 */
39int stdin_null_flag = 0; 39int stdin_null_flag = 0;
40 40
41/* Flag indicating that ssh should fork after authentication. This is useful 41/*
42 so that the pasphrase can be entered manually, and then ssh goes to the 42 * Flag indicating that ssh should fork after authentication. This is useful
43 background. */ 43 * so that the pasphrase can be entered manually, and then ssh goes to the
44 * background.
45 */
44int fork_after_authentication_flag = 0; 46int fork_after_authentication_flag = 0;
45 47
46/* General data structure for command line options and options configurable 48/*
47 in configuration files. See readconf.h. */ 49 * General data structure for command line options and options configurable
50 * in configuration files. See readconf.h.
51 */
48Options options; 52Options options;
49 53
50/* Name of the host we are connecting to. This is the name given on the 54/*
51 command line, or the HostName specified for the user-supplied name 55 * Name of the host we are connecting to. This is the name given on the
52 in a configuration file. */ 56 * command line, or the HostName specified for the user-supplied name in a
57 * configuration file.
58 */
53char *host; 59char *host;
54 60
55/* socket address the host resolves to */ 61/* socket address the host resolves to */
56struct sockaddr_in hostaddr; 62struct sockaddr_in hostaddr;
57 63
58/* Flag to indicate that we have received a window change signal which has 64/*
59 not yet been processed. This will cause a message indicating the new 65 * Flag to indicate that we have received a window change signal which has
60 window size to be sent to the server a little later. This is volatile 66 * not yet been processed. This will cause a message indicating the new
61 because this is updated in a signal handler. */ 67 * window size to be sent to the server a little later. This is volatile
68 * because this is updated in a signal handler.
69 */
62volatile int received_window_change_signal = 0; 70volatile int received_window_change_signal = 0;
63 71
64/* Value of argv[0] (set in the main program). */ 72/* Value of argv[0] (set in the main program). */
@@ -165,8 +173,10 @@ main(int ac, char **av)
165 uid_t original_effective_uid; 173 uid_t original_effective_uid;
166 int plen; 174 int plen;
167 175
168 /* Save the original real uid. It will be needed later 176 /*
169 (uid-swapping may clobber the real uid). */ 177 * Save the original real uid. It will be needed later (uid-swapping
178 * may clobber the real uid).
179 */
170 original_real_uid = getuid(); 180 original_real_uid = getuid();
171 original_effective_uid = geteuid(); 181 original_effective_uid = geteuid();
172 182
@@ -177,18 +187,21 @@ main(int ac, char **av)
177 if (setrlimit(RLIMIT_CORE, &rlim) < 0) 187 if (setrlimit(RLIMIT_CORE, &rlim) < 0)
178 fatal("setrlimit failed: %.100s", strerror(errno)); 188 fatal("setrlimit failed: %.100s", strerror(errno));
179 } 189 }
180 /* Use uid-swapping to give up root privileges for the duration of 190 /*
181 option processing. We will re-instantiate the rights when we 191 * Use uid-swapping to give up root privileges for the duration of
182 are ready to create the privileged port, and will permanently 192 * option processing. We will re-instantiate the rights when we are
183 drop them when the port has been created (actually, when the 193 * ready to create the privileged port, and will permanently drop
184 connection has been made, as we may need to create the port 194 * them when the port has been created (actually, when the connection
185 several times). */ 195 * has been made, as we may need to create the port several times).
196 */
186 temporarily_use_uid(original_real_uid); 197 temporarily_use_uid(original_real_uid);
187 198
188 /* Set our umask to something reasonable, as some files are 199 /*
189 created with the default umask. This will make them 200 * Set our umask to something reasonable, as some files are created
190 world-readable but writable only by the owner, which is ok for 201 * with the default umask. This will make them world-readable but
191 all files for which we don't set the modes explicitly. */ 202 * writable only by the owner, which is ok for all files for which we
203 * don't set the modes explicitly.
204 */
192 umask(022); 205 umask(022);
193 206
194 /* Save our own name. */ 207 /* Save our own name. */
@@ -387,10 +400,11 @@ main(int ac, char **av)
387 /* Initialize the command to execute on remote host. */ 400 /* Initialize the command to execute on remote host. */
388 buffer_init(&command); 401 buffer_init(&command);
389 402
390 /* Save the command to execute on the remote host in a buffer. 403 /*
391 There is no limit on the length of the command, except by the 404 * Save the command to execute on the remote host in a buffer. There
392 maximum packet size. Also sets the tty flag if there is no 405 * is no limit on the length of the command, except by the maximum
393 command. */ 406 * packet size. Also sets the tty flag if there is no command.
407 */
394 if (optind == ac) { 408 if (optind == ac) {
395 /* No command specified - execute shell on a tty. */ 409 /* No command specified - execute shell on a tty. */
396 tty_flag = 1; 410 tty_flag = 1;
@@ -474,11 +488,15 @@ main(int ac, char **av)
474 options.rhosts_authentication = 0; 488 options.rhosts_authentication = 0;
475 options.rhosts_rsa_authentication = 0; 489 options.rhosts_rsa_authentication = 0;
476 } 490 }
477 /* If using rsh has been selected, exec it now (without trying 491 /*
478 anything else). Note that we must release privileges first. */ 492 * If using rsh has been selected, exec it now (without trying
493 * anything else). Note that we must release privileges first.
494 */
479 if (options.use_rsh) { 495 if (options.use_rsh) {
480 /* Restore our superuser privileges. This must be done 496 /*
481 before permanently setting the uid. */ 497 * Restore our superuser privileges. This must be done
498 * before permanently setting the uid.
499 */
482 restore_uid(); 500 restore_uid();
483 501
484 /* Switch to the original uid permanently. */ 502 /* Switch to the original uid permanently. */
@@ -491,8 +509,10 @@ main(int ac, char **av)
491 /* Restore our superuser privileges. */ 509 /* Restore our superuser privileges. */
492 restore_uid(); 510 restore_uid();
493 511
494 /* Open a connection to the remote host. This needs root 512 /*
495 privileges if rhosts_{rsa_}authentication is enabled. */ 513 * Open a connection to the remote host. This needs root privileges
514 * if rhosts_{rsa_}authentication is enabled.
515 */
496 516
497 ok = ssh_connect(host, &hostaddr, options.port, 517 ok = ssh_connect(host, &hostaddr, options.port,
498 options.connection_attempts, 518 options.connection_attempts,
@@ -501,31 +521,38 @@ main(int ac, char **av)
501 original_real_uid, 521 original_real_uid,
502 options.proxy_command); 522 options.proxy_command);
503 523
504 /* If we successfully made the connection, load the host private 524 /*
505 key in case we will need it later for combined rsa-rhosts 525 * If we successfully made the connection, load the host private key
506 authentication. This must be done before releasing extra 526 * in case we will need it later for combined rsa-rhosts
507 privileges, because the file is only readable by root. */ 527 * authentication. This must be done before releasing extra
528 * privileges, because the file is only readable by root.
529 */
508 if (ok) { 530 if (ok) {
509 host_private_key = RSA_new(); 531 host_private_key = RSA_new();
510 if (load_private_key(HOST_KEY_FILE, "", host_private_key, NULL)) 532 if (load_private_key(HOST_KEY_FILE, "", host_private_key, NULL))
511 host_private_key_loaded = 1; 533 host_private_key_loaded = 1;
512 } 534 }
513 /* Get rid of any extra privileges that we may have. We will no 535 /*
514 longer need them. Also, extra privileges could make it very 536 * Get rid of any extra privileges that we may have. We will no
515 hard to read identity files and other non-world-readable files 537 * longer need them. Also, extra privileges could make it very hard
516 from the user's home directory if it happens to be on a NFS 538 * to read identity files and other non-world-readable files from the
517 volume where root is mapped to nobody. */ 539 * user's home directory if it happens to be on a NFS volume where
518 540 * root is mapped to nobody.
519 /* Note that some legacy systems need to postpone the following 541 */
520 call to permanently_set_uid() until the private hostkey is 542
521 destroyed with RSA_free(). Otherwise the calling user could 543 /*
522 ptrace() the process, read the private hostkey and impersonate 544 * Note that some legacy systems need to postpone the following call
523 the host. OpenBSD does not allow ptracing of setuid processes. */ 545 * to permanently_set_uid() until the private hostkey is destroyed
524 546 * with RSA_free(). Otherwise the calling user could ptrace() the
547 * process, read the private hostkey and impersonate the host.
548 * OpenBSD does not allow ptracing of setuid processes.
549 */
525 permanently_set_uid(original_real_uid); 550 permanently_set_uid(original_real_uid);
526 551
527 /* Now that we are back to our own permissions, create ~/.ssh 552 /*
528 directory if it doesn\'t already exist. */ 553 * Now that we are back to our own permissions, create ~/.ssh
554 * directory if it doesn\'t already exist.
555 */
529 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_DIR); 556 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_DIR);
530 if (stat(buf, &st) < 0) 557 if (stat(buf, &st) < 0)
531 if (mkdir(buf, 0755) < 0) 558 if (mkdir(buf, 0755) < 0)
@@ -569,15 +596,6 @@ main(int ac, char **av)
569 /* Close connection cleanly after attack. */ 596 /* Close connection cleanly after attack. */
570 cipher_attack_detected = packet_disconnect; 597 cipher_attack_detected = packet_disconnect;
571 598
572 /* If requested, fork and let ssh continue in the background. */
573 if (fork_after_authentication_flag) {
574 int ret = fork();
575 if (ret == -1)
576 fatal("fork failed: %.100s", strerror(errno));
577 if (ret != 0)
578 exit(0);
579 setsid();
580 }
581 /* Enable compression if requested. */ 599 /* Enable compression if requested. */
582 if (options.compression) { 600 if (options.compression) {
583 debug("Requesting compression at level %d.", options.compression_level); 601 debug("Requesting compression at level %d.", options.compression_level);
@@ -653,12 +671,14 @@ main(int ac, char **av)
653 if (f) 671 if (f)
654 pclose(f); 672 pclose(f);
655#endif /* XAUTH_PATH */ 673#endif /* XAUTH_PATH */
656 /* If we didn't get authentication data, just make up some 674 /*
657 data. The forwarding code will check the validity of 675 * If we didn't get authentication data, just make up some
658 the response anyway, and substitute this data. The X11 676 * data. The forwarding code will check the validity of the
659 server, however, will ignore this fake data and use 677 * response anyway, and substitute this data. The X11
660 whatever authentication mechanisms it was using 678 * server, however, will ignore this fake data and use
661 otherwise for the local connection. */ 679 * whatever authentication mechanisms it was using otherwise
680 * for the local connection.
681 */
662 if (!got_data) { 682 if (!got_data) {
663 u_int32_t rand = 0; 683 u_int32_t rand = 0;
664 684
@@ -670,8 +690,10 @@ main(int ac, char **av)
670 rand >>= 8; 690 rand >>= 8;
671 } 691 }
672 } 692 }
673 /* Got local authentication reasonable information. 693 /*
674 Request forwarding with authentication spoofing. */ 694 * Got local authentication reasonable information. Request
695 * forwarding with authentication spoofing.
696 */
675 debug("Requesting X11 forwarding with authentication spoofing."); 697 debug("Requesting X11 forwarding with authentication spoofing.");
676 x11_request_forwarding_with_spoofing(proto, data); 698 x11_request_forwarding_with_spoofing(proto, data);
677 699
@@ -728,8 +750,15 @@ main(int ac, char **av)
728 options.remote_forwards[i].host_port); 750 options.remote_forwards[i].host_port);
729 } 751 }
730 752
731 /* If a command was specified on the command line, execute the 753 /* If requested, let ssh continue in the background. */
732 command now. Otherwise request the server to start a shell. */ 754 if (fork_after_authentication_flag)
755 if (daemon(1, 1) < 0)
756 fatal("daemon() failed: %.200s", strerror(errno));
757
758 /*
759 * If a command was specified on the command line, execute the
760 * command now. Otherwise request the server to start a shell.
761 */
733 if (buffer_len(&command) > 0) { 762 if (buffer_len(&command) > 0) {
734 int len = buffer_len(&command); 763 int len = buffer_len(&command);
735 if (len > 900) 764 if (len > 900)
diff --git a/ssh.h b/ssh.h
index f8426bfbb..e3fed053e 100644
--- a/ssh.h
+++ b/ssh.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: ssh.h,v 1.15 1999/11/24 13:26:23 damien Exp $"); */ 16/* RCSID("$Id: ssh.h,v 1.16 1999/11/25 00:54:59 damien Exp $"); */
17 17
18#ifndef SSH_H 18#ifndef SSH_H
19#define SSH_H 19#define SSH_H
@@ -25,9 +25,11 @@
25#include "rsa.h" 25#include "rsa.h"
26#include "cipher.h" 26#include "cipher.h"
27 27
28/* The default cipher used if IDEA is not supported by the remote host. 28/*
29 It is recommended that this be one of the mandatory ciphers (DES, 3DES), 29 * The default cipher used if IDEA is not supported by the remote host. It is
30 though that is not required. */ 30 * recommended that this be one of the mandatory ciphers (DES, 3DES), though
31 * that is not required.
32 */
31#define SSH_FALLBACK_CIPHER SSH_CIPHER_3DES 33#define SSH_FALLBACK_CIPHER SSH_CIPHER_3DES
32 34
33/* Cipher used for encrypting authentication files. */ 35/* Cipher used for encrypting authentication files. */
@@ -39,20 +41,28 @@
39/* Maximum number of TCP/IP ports forwarded per direction. */ 41/* Maximum number of TCP/IP ports forwarded per direction. */
40#define SSH_MAX_FORWARDS_PER_DIRECTION 100 42#define SSH_MAX_FORWARDS_PER_DIRECTION 100
41 43
42/* Maximum number of RSA authentication identity files that can be specified 44/*
43 in configuration files or on the command line. */ 45 * Maximum number of RSA authentication identity files that can be specified
46 * in configuration files or on the command line.
47 */
44#define SSH_MAX_IDENTITY_FILES 100 48#define SSH_MAX_IDENTITY_FILES 100
45 49
46/* Major protocol version. Different version indicates major incompatiblity 50/*
47 that prevents communication. */ 51 * Major protocol version. Different version indicates major incompatiblity
52 * that prevents communication.
53 */
48#define PROTOCOL_MAJOR 1 54#define PROTOCOL_MAJOR 1
49 55
50/* Minor protocol version. Different version indicates minor incompatibility 56/*
51 that does not prevent interoperation. */ 57 * Minor protocol version. Different version indicates minor incompatibility
58 * that does not prevent interoperation.
59 */
52#define PROTOCOL_MINOR 5 60#define PROTOCOL_MINOR 5
53 61
54/* Name for the service. The port named by this service overrides the default 62/*
55 port if present. */ 63 * Name for the service. The port named by this service overrides the
64 * default port if present.
65 */
56#define SSH_SERVICE_NAME "ssh" 66#define SSH_SERVICE_NAME "ssh"
57 67
58#ifndef ETCDIR 68#ifndef ETCDIR
@@ -63,16 +73,16 @@
63#define PIDDIR "/var/run" 73#define PIDDIR "/var/run"
64#endif /* PIDDIR */ 74#endif /* PIDDIR */
65 75
66/* System-wide file containing host keys of known hosts. This file should be 76/*
67 world-readable. */ 77 * System-wide file containing host keys of known hosts. This file should be
78 * world-readable.
79 */
68#define SSH_SYSTEM_HOSTFILE ETCDIR "/ssh_known_hosts" 80#define SSH_SYSTEM_HOSTFILE ETCDIR "/ssh_known_hosts"
69 81
70/* HOST_KEY_FILE /etc/ssh_host_key, 82/*
71 SERVER_CONFIG_FILE /etc/sshd_config, 83 * Of these, ssh_host_key must be readable only by root, whereas ssh_config
72and HOST_CONFIG_FILE /etc/ssh_config 84 * should be world-readable.
73are all defined in Makefile.in. Of these, ssh_host_key should be readable 85 */
74only by root, whereas ssh_config should be world-readable. */
75
76#define HOST_KEY_FILE ETCDIR "/ssh_host_key" 86#define HOST_KEY_FILE ETCDIR "/ssh_host_key"
77#define SERVER_CONFIG_FILE ETCDIR "/sshd_config" 87#define SERVER_CONFIG_FILE ETCDIR "/sshd_config"
78#define HOST_CONFIG_FILE ETCDIR "/ssh_config" 88#define HOST_CONFIG_FILE ETCDIR "/ssh_config"
@@ -89,73 +99,95 @@ only by root, whereas ssh_config should be world-readable. */
89#define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass" 99#define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass"
90#endif /* ASKPASS_PROGRAM */ 100#endif /* ASKPASS_PROGRAM */
91 101
92/* The process id of the daemon listening for connections is saved 102/*
93 here to make it easier to kill the correct daemon when necessary. */ 103 * The process id of the daemon listening for connections is saved here to
104 * make it easier to kill the correct daemon when necessary.
105 */
94#define SSH_DAEMON_PID_FILE PIDDIR "/sshd.pid" 106#define SSH_DAEMON_PID_FILE PIDDIR "/sshd.pid"
95 107
96/* The directory in user\'s home directory in which the files reside. 108/*
97 The directory should be world-readable (though not all files are). */ 109 * The directory in user\'s home directory in which the files reside. The
110 * directory should be world-readable (though not all files are).
111 */
98#define SSH_USER_DIR ".ssh" 112#define SSH_USER_DIR ".ssh"
99 113
100/* Per-user file containing host keys of known hosts. This file need 114/*
101 not be readable by anyone except the user him/herself, though this does 115 * Per-user file containing host keys of known hosts. This file need not be
102 not contain anything particularly secret. */ 116 * readable by anyone except the user him/herself, though this does not
117 * contain anything particularly secret.
118 */
103#define SSH_USER_HOSTFILE "~/.ssh/known_hosts" 119#define SSH_USER_HOSTFILE "~/.ssh/known_hosts"
104 120
105/* Name of the default file containing client-side authentication key. 121/*
106 This file should only be readable by the user him/herself. */ 122 * Name of the default file containing client-side authentication key. This
123 * file should only be readable by the user him/herself.
124 */
107#define SSH_CLIENT_IDENTITY ".ssh/identity" 125#define SSH_CLIENT_IDENTITY ".ssh/identity"
108 126
109/* Configuration file in user\'s home directory. This file need not be 127/*
110 readable by anyone but the user him/herself, but does not contain 128 * Configuration file in user\'s home directory. This file need not be
111 anything particularly secret. If the user\'s home directory resides 129 * readable by anyone but the user him/herself, but does not contain anything
112 on an NFS volume where root is mapped to nobody, this may need to be 130 * particularly secret. If the user\'s home directory resides on an NFS
113 world-readable. */ 131 * volume where root is mapped to nobody, this may need to be world-readable.
132 */
114#define SSH_USER_CONFFILE ".ssh/config" 133#define SSH_USER_CONFFILE ".ssh/config"
115 134
116/* File containing a list of those rsa keys that permit logging in as 135/*
117 this user. This file need not be 136 * File containing a list of those rsa keys that permit logging in as this
118 readable by anyone but the user him/herself, but does not contain 137 * user. This file need not be readable by anyone but the user him/herself,
119 anything particularly secret. If the user\'s home directory resides 138 * but does not contain anything particularly secret. If the user\'s home
120 on an NFS volume where root is mapped to nobody, this may need to be 139 * directory resides on an NFS volume where root is mapped to nobody, this
121 world-readable. (This file is read by the daemon which is running as 140 * may need to be world-readable. (This file is read by the daemon which is
122 root.) */ 141 * running as root.)
142 */
123#define SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys" 143#define SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys"
124 144
125/* Per-user and system-wide ssh "rc" files. These files are executed with 145/*
126 /bin/sh before starting the shell or command if they exist. They 146 * Per-user and system-wide ssh "rc" files. These files are executed with
127 will be passed "proto cookie" as arguments if X11 forwarding with 147 * /bin/sh before starting the shell or command if they exist. They will be
128 spoofing is in use. xauth will be run if neither of these exists. */ 148 * passed "proto cookie" as arguments if X11 forwarding with spoofing is in
149 * use. xauth will be run if neither of these exists.
150 */
129#define SSH_USER_RC ".ssh/rc" 151#define SSH_USER_RC ".ssh/rc"
130#define SSH_SYSTEM_RC ETCDIR "/sshrc" 152#define SSH_SYSTEM_RC ETCDIR "/sshrc"
131 153
132/* Ssh-only version of /etc/hosts.equiv. */ 154/*
155 * Ssh-only version of /etc/hosts.equiv. Additionally, the daemon may use
156 * ~/.rhosts and /etc/hosts.equiv if rhosts authentication is enabled.
157 */
133#define SSH_HOSTS_EQUIV ETCDIR "/shosts.equiv" 158#define SSH_HOSTS_EQUIV ETCDIR "/shosts.equiv"
134 159
135/* Additionally, the daemon may use ~/.rhosts and /etc/hosts.equiv if 160/*
136 rhosts authentication is enabled. */ 161 * Name of the environment variable containing the pathname of the
137 162 * authentication socket.
138/* Name of the environment variable containing the pathname of the 163 */
139 authentication socket. */
140#define SSH_AUTHSOCKET_ENV_NAME "SSH_AUTH_SOCK" 164#define SSH_AUTHSOCKET_ENV_NAME "SSH_AUTH_SOCK"
141 165
142/* Name of the environment variable containing the pathname of the 166/*
143 authentication socket. */ 167 * Name of the environment variable containing the pathname of the
168 * authentication socket.
169 */
144#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" 170#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID"
145 171
146/* Force host key length and server key length to differ by at least this 172/*
147 many bits. This is to make double encryption with rsaref work. */ 173 * Force host key length and server key length to differ by at least this
174 * many bits. This is to make double encryption with rsaref work.
175 */
148#define SSH_KEY_BITS_RESERVED 128 176#define SSH_KEY_BITS_RESERVED 128
149 177
150/* Length of the session key in bytes. (Specified as 256 bits in the 178/*
151 protocol.) */ 179 * Length of the session key in bytes. (Specified as 256 bits in the
180 * protocol.)
181 */
152#define SSH_SESSION_KEY_LENGTH 32 182#define SSH_SESSION_KEY_LENGTH 32
153 183
154/* Name of Kerberos service for SSH to use. */ 184/* Name of Kerberos service for SSH to use. */
155#define KRB4_SERVICE_NAME "rcmd" 185#define KRB4_SERVICE_NAME "rcmd"
156 186
157/* Authentication methods. New types can be added, but old types should not 187/*
158 be removed for compatibility. The maximum allowed value is 31. */ 188 * Authentication methods. New types can be added, but old types should not
189 * be removed for compatibility. The maximum allowed value is 31.
190 */
159#define SSH_AUTH_RHOSTS 1 191#define SSH_AUTH_RHOSTS 1
160#define SSH_AUTH_RSA 2 192#define SSH_AUTH_RSA 2
161#define SSH_AUTH_PASSWORD 3 193#define SSH_AUTH_PASSWORD 3
@@ -163,20 +195,20 @@ only by root, whereas ssh_config should be world-readable. */
163#define SSH_AUTH_TIS 5 195#define SSH_AUTH_TIS 5
164#define SSH_AUTH_KERBEROS 6 196#define SSH_AUTH_KERBEROS 6
165#define SSH_PASS_KERBEROS_TGT 7 197#define SSH_PASS_KERBEROS_TGT 7
166 /* 8 to 15 are reserved */ 198 /* 8 to 15 are reserved */
167#define SSH_PASS_AFS_TOKEN 21 199#define SSH_PASS_AFS_TOKEN 21
168 200
169/* Protocol flags. These are bit masks. */ 201/* Protocol flags. These are bit masks. */
170#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes 202#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */
171 * screen */ 203#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */
172#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain 204
173 * host */ 205/*
174 206 * Definition of message types. New values can be added, but old values
175/* Definition of message types. New values can be added, but old values 207 * should not be removed or without careful consideration of the consequences
176 should not be removed or without careful consideration of the consequences 208 * for compatibility. The maximum value is 254; value 255 is reserved for
177 for compatibility. The maximum value is 254; value 255 is reserved 209 * future extension.
178 for future extension. */ 210 */
179 /* Message name *//* msg code *//* arguments */ 211/* Message name */ /* msg code */ /* arguments */
180#define SSH_MSG_NONE 0 /* no message */ 212#define SSH_MSG_NONE 0 /* no message */
181#define SSH_MSG_DISCONNECT 1 /* cause (string) */ 213#define SSH_MSG_DISCONNECT 1 /* cause (string) */
182#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */ 214#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */
@@ -226,45 +258,54 @@ only by root, whereas ssh_config should be world-readable. */
226 258
227/*------------ definitions for login.c -------------*/ 259/*------------ definitions for login.c -------------*/
228 260
229/* Returns the time when the user last logged in. Returns 0 if the 261/*
230 information is not available. This must be called before record_login. 262 * Returns the time when the user last logged in. Returns 0 if the
231 The host from which the user logged in is stored in buf. */ 263 * information is not available. This must be called before record_login.
264 * The host from which the user logged in is stored in buf.
265 */
232unsigned long 266unsigned long
233get_last_login_time(uid_t uid, const char *logname, 267get_last_login_time(uid_t uid, const char *logname,
234 char *buf, unsigned int bufsize); 268 char *buf, unsigned int bufsize);
235 269
236/* Records that the user has logged in. This does many things normally 270/*
237 done by login(1). */ 271 * Records that the user has logged in. This does many things normally done
272 * by login(1).
273 */
238void 274void
239record_login(int pid, const char *ttyname, const char *user, uid_t uid, 275record_login(int pid, const char *ttyname, const char *user, uid_t uid,
240 const char *host, struct sockaddr_in * addr); 276 const char *host, struct sockaddr_in * addr);
241 277
242/* Records that the user has logged out. This does many thigs normally 278/*
243 done by login(1) or init. */ 279 * Records that the user has logged out. This does many thigs normally done
280 * by login(1) or init.
281 */
244void record_logout(int pid, const char *ttyname); 282void record_logout(int pid, const char *ttyname);
245 283
246/*------------ definitions for sshconnect.c ----------*/ 284/*------------ definitions for sshconnect.c ----------*/
247 285
248/* Opens a TCP/IP connection to the remote server on the given host. If 286/*
249 port is 0, the default port will be used. If anonymous is zero, 287 * Opens a TCP/IP connection to the remote server on the given host. If port
250 a privileged port will be allocated to make the connection. 288 * is 0, the default port will be used. If anonymous is zero, a privileged
251 This requires super-user privileges if anonymous is false. 289 * port will be allocated to make the connection. This requires super-user
252 Connection_attempts specifies the maximum number of tries, one per 290 * privileges if anonymous is false. Connection_attempts specifies the
253 second. This returns true on success, and zero on failure. If the 291 * maximum number of tries, one per second. This returns true on success,
254 connection is successful, this calls packet_set_connection for the 292 * and zero on failure. If the connection is successful, this calls
255 connection. */ 293 * packet_set_connection for the connection.
294 */
256int 295int
257ssh_connect(const char *host, struct sockaddr_in * hostaddr, 296ssh_connect(const char *host, struct sockaddr_in * hostaddr,
258 int port, int connection_attempts, 297 int port, int connection_attempts,
259 int anonymous, uid_t original_real_uid, 298 int anonymous, uid_t original_real_uid,
260 const char *proxy_command); 299 const char *proxy_command);
261 300
262/* Starts a dialog with the server, and authenticates the current user on the 301/*
263 server. This does not need any extra privileges. The basic connection 302 * Starts a dialog with the server, and authenticates the current user on the
264 to the server must already have been established before this is called. 303 * server. This does not need any extra privileges. The basic connection to
265 If login fails, this function prints an error and never returns. 304 * the server must already have been established before this is called. If
266 This initializes the random state, and leaves it initialized (it will also 305 * login fails, this function prints an error and never returns. This
267 have references from the packet module). */ 306 * initializes the random state, and leaves it initialized (it will also have
307 * references from the packet module).
308 */
268 309
269void 310void
270ssh_login(int host_key_valid, RSA * host_key, const char *host, 311ssh_login(int host_key_valid, RSA * host_key, const char *host,
@@ -272,41 +313,57 @@ ssh_login(int host_key_valid, RSA * host_key, const char *host,
272 313
273/*------------ Definitions for various authentication methods. -------*/ 314/*------------ Definitions for various authentication methods. -------*/
274 315
275/* Tries to authenticate the user using the .rhosts file. Returns true if 316/*
276 authentication succeeds. If ignore_rhosts is non-zero, this will not 317 * Tries to authenticate the user using the .rhosts file. Returns true if
277 consider .rhosts and .shosts (/etc/hosts.equiv will still be used). */ 318 * authentication succeeds. If ignore_rhosts is non-zero, this will not
319 * consider .rhosts and .shosts (/etc/hosts.equiv will still be used).
320 */
278int auth_rhosts(struct passwd * pw, const char *client_user); 321int auth_rhosts(struct passwd * pw, const char *client_user);
279 322
280/* Tries to authenticate the user using the .rhosts file and the host using 323/*
281 its host key. Returns true if authentication succeeds. */ 324 * Tries to authenticate the user using the .rhosts file and the host using
325 * its host key. Returns true if authentication succeeds.
326 */
282int 327int
283auth_rhosts_rsa(struct passwd * pw, const char *client_user, 328auth_rhosts_rsa(struct passwd * pw, const char *client_user,
284 BIGNUM * client_host_key_e, BIGNUM * client_host_key_n); 329 BIGNUM * client_host_key_e, BIGNUM * client_host_key_n);
285 330
286/* Tries to authenticate the user using password. Returns true if 331/*
287 authentication succeeds. */ 332 * Tries to authenticate the user using password. Returns true if
333 * authentication succeeds.
334 */
288int auth_password(struct passwd * pw, const char *password); 335int auth_password(struct passwd * pw, const char *password);
289 336
290/* Performs the RSA authentication dialog with the client. This returns 337/*
291 0 if the client could not be authenticated, and 1 if authentication was 338 * Performs the RSA authentication dialog with the client. This returns 0 if
292 successful. This may exit if there is a serious protocol violation. */ 339 * the client could not be authenticated, and 1 if authentication was
340 * successful. This may exit if there is a serious protocol violation.
341 */
293int auth_rsa(struct passwd * pw, BIGNUM * client_n); 342int auth_rsa(struct passwd * pw, BIGNUM * client_n);
294 343
295/* Parses an RSA key (number of bits, e, n) from a string. Moves the pointer 344/*
296 over the key. Skips any whitespace at the beginning and at end. */ 345 * Parses an RSA key (number of bits, e, n) from a string. Moves the pointer
346 * over the key. Skips any whitespace at the beginning and at end.
347 */
297int auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n); 348int auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n);
298 349
299/* Returns the name of the machine at the other end of the socket. The 350/*
300 returned string should be freed by the caller. */ 351 * Returns the name of the machine at the other end of the socket. The
352 * returned string should be freed by the caller.
353 */
301char *get_remote_hostname(int socket); 354char *get_remote_hostname(int socket);
302 355
303/* Return the canonical name of the host in the other side of the current 356/*
304 connection (as returned by packet_get_connection). The host name is 357 * Return the canonical name of the host in the other side of the current
305 cached, so it is efficient to call this several times. */ 358 * connection (as returned by packet_get_connection). The host name is
359 * cached, so it is efficient to call this several times.
360 */
306const char *get_canonical_hostname(void); 361const char *get_canonical_hostname(void);
307 362
308/* Returns the remote IP address as an ascii string. The value need not be 363/*
309 freed by the caller. */ 364 * Returns the remote IP address as an ascii string. The value need not be
365 * freed by the caller.
366 */
310const char *get_remote_ipaddr(void); 367const char *get_remote_ipaddr(void);
311 368
312/* Returns the port number of the peer of the socket. */ 369/* Returns the port number of the peer of the socket. */
@@ -315,16 +372,20 @@ int get_peer_port(int sock);
315/* Returns the port number of the remote host. */ 372/* Returns the port number of the remote host. */
316int get_remote_port(void); 373int get_remote_port(void);
317 374
318/* Tries to match the host name (which must be in all lowercase) against the 375/*
319 comma-separated sequence of subpatterns (each possibly preceded by ! to 376 * Tries to match the host name (which must be in all lowercase) against the
320 indicate negation). Returns true if there is a positive match; zero 377 * comma-separated sequence of subpatterns (each possibly preceded by ! to
321 otherwise. */ 378 * indicate negation). Returns true if there is a positive match; zero
379 * otherwise.
380 */
322int match_hostname(const char *host, const char *pattern, unsigned int len); 381int match_hostname(const char *host, const char *pattern, unsigned int len);
323 382
324/* Checks whether the given host is already in the list of our known hosts. 383/*
325 Returns HOST_OK if the host is known and has the specified key, 384 * Checks whether the given host is already in the list of our known hosts.
326 HOST_NEW if the host is not known, and HOST_CHANGED if the host is known 385 * Returns HOST_OK if the host is known and has the specified key, HOST_NEW
327 but used to have a different host key. The host must be in all lowercase. */ 386 * if the host is not known, and HOST_CHANGED if the host is known but used
387 * to have a different host key. The host must be in all lowercase.
388 */
328typedef enum { 389typedef enum {
329 HOST_OK, HOST_NEW, HOST_CHANGED 390 HOST_OK, HOST_NEW, HOST_CHANGED
330} HostStatus; 391} HostStatus;
@@ -332,43 +393,55 @@ HostStatus
332check_host_in_hostfile(const char *filename, const char *host, 393check_host_in_hostfile(const char *filename, const char *host,
333 BIGNUM * e, BIGNUM * n, BIGNUM * ke, BIGNUM * kn); 394 BIGNUM * e, BIGNUM * n, BIGNUM * ke, BIGNUM * kn);
334 395
335/* Appends an entry to the host file. Returns false if the entry 396/*
336 could not be appended. */ 397 * Appends an entry to the host file. Returns false if the entry could not
398 * be appended.
399 */
337int 400int
338add_host_to_hostfile(const char *filename, const char *host, 401add_host_to_hostfile(const char *filename, const char *host,
339 BIGNUM * e, BIGNUM * n); 402 BIGNUM * e, BIGNUM * n);
340 403
341/* Performs the RSA authentication challenge-response dialog with the client, 404/*
342 and returns true (non-zero) if the client gave the correct answer to 405 * Performs the RSA authentication challenge-response dialog with the client,
343 our challenge; returns zero if the client gives a wrong answer. */ 406 * and returns true (non-zero) if the client gave the correct answer to our
407 * challenge; returns zero if the client gives a wrong answer.
408 */
344int auth_rsa_challenge_dialog(BIGNUM * e, BIGNUM * n); 409int auth_rsa_challenge_dialog(BIGNUM * e, BIGNUM * n);
345 410
346/* Reads a passphrase from /dev/tty with echo turned off. Returns the 411/*
347 passphrase (allocated with xmalloc). Exits if EOF is encountered. 412 * Reads a passphrase from /dev/tty with echo turned off. Returns the
348 If from_stdin is true, the passphrase will be read from stdin instead. */ 413 * passphrase (allocated with xmalloc). Exits if EOF is encountered. If
414 * from_stdin is true, the passphrase will be read from stdin instead.
415 */
349char *read_passphrase(const char *prompt, int from_stdin); 416char *read_passphrase(const char *prompt, int from_stdin);
350 417
351/* Saves the authentication (private) key in a file, encrypting it with 418/*
352 passphrase. The identification of the file (lowest 64 bits of n) 419 * Saves the authentication (private) key in a file, encrypting it with
353 will precede the key to provide identification of the key without 420 * passphrase. The identification of the file (lowest 64 bits of n) will
354 needing a passphrase. */ 421 * precede the key to provide identification of the key without needing a
422 * passphrase.
423 */
355int 424int
356save_private_key(const char *filename, const char *passphrase, 425save_private_key(const char *filename, const char *passphrase,
357 RSA * private_key, const char *comment); 426 RSA * private_key, const char *comment);
358 427
359/* Loads the public part of the key file (public key and comment). 428/*
360 Returns 0 if an error occurred; zero if the public key was successfully 429 * Loads the public part of the key file (public key and comment). Returns 0
361 read. The comment of the key is returned in comment_return if it is 430 * if an error occurred; zero if the public key was successfully read. The
362 non-NULL; the caller must free the value with xfree. */ 431 * comment of the key is returned in comment_return if it is non-NULL; the
432 * caller must free the value with xfree.
433 */
363int 434int
364load_public_key(const char *filename, RSA * pub, 435load_public_key(const char *filename, RSA * pub,
365 char **comment_return); 436 char **comment_return);
366 437
367/* Loads the private key from the file. Returns 0 if an error is encountered 438/*
368 (file does not exist or is not readable, or passphrase is bad). 439 * Loads the private key from the file. Returns 0 if an error is encountered
369 This initializes the private key. The comment of the key is returned 440 * (file does not exist or is not readable, or passphrase is bad). This
370 in comment_return if it is non-NULL; the caller must free the value 441 * initializes the private key. The comment of the key is returned in
371 with xfree. */ 442 * comment_return if it is non-NULL; the caller must free the value with
443 * xfree.
444 */
372int 445int
373load_private_key(const char *filename, const char *passphrase, 446load_private_key(const char *filename, const char *passphrase,
374 RSA * private_key, char **comment_return); 447 RSA * private_key, char **comment_return);
@@ -418,9 +491,11 @@ void debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));
418/* same as fatal() but w/o logging */ 491/* same as fatal() but w/o logging */
419void fatal_cleanup(void); 492void fatal_cleanup(void);
420 493
421/* Registers a cleanup function to be called by fatal()/fatal_cleanup() before exiting. 494/*
422 It is permissible to call fatal_remove_cleanup for the function itself 495 * Registers a cleanup function to be called by fatal()/fatal_cleanup()
423 from the function. */ 496 * before exiting. It is permissible to call fatal_remove_cleanup for the
497 * function itself from the function.
498 */
424void fatal_add_cleanup(void (*proc) (void *context), void *context); 499void fatal_add_cleanup(void (*proc) (void *context), void *context);
425 500
426/* Removes a cleanup function to be called at fatal(). */ 501/* Removes a cleanup function to be called at fatal(). */
@@ -431,9 +506,11 @@ void fatal_remove_cleanup(void (*proc) (void *context), void *context);
431/* Sets specific protocol options. */ 506/* Sets specific protocol options. */
432void channel_set_options(int hostname_in_open); 507void channel_set_options(int hostname_in_open);
433 508
434/* Allocate a new channel object and set its type and socket. Remote_name 509/*
435 must have been allocated with xmalloc; this will free it when the channel 510 * Allocate a new channel object and set its type and socket. Remote_name
436 is freed. */ 511 * must have been allocated with xmalloc; this will free it when the channel
512 * is freed.
513 */
437int channel_allocate(int type, int sock, char *remote_name); 514int channel_allocate(int type, int sock, char *remote_name);
438 515
439/* Free the channel and close its socket. */ 516/* Free the channel and close its socket. */
@@ -442,16 +519,20 @@ void channel_free(int channel);
442/* Add any bits relevant to channels in select bitmasks. */ 519/* Add any bits relevant to channels in select bitmasks. */
443void channel_prepare_select(fd_set * readset, fd_set * writeset); 520void channel_prepare_select(fd_set * readset, fd_set * writeset);
444 521
445/* After select, perform any appropriate operations for channels which 522/*
446 have events pending. */ 523 * After select, perform any appropriate operations for channels which have
524 * events pending.
525 */
447void channel_after_select(fd_set * readset, fd_set * writeset); 526void channel_after_select(fd_set * readset, fd_set * writeset);
448 527
449/* If there is data to send to the connection, send some of it now. */ 528/* If there is data to send to the connection, send some of it now. */
450void channel_output_poll(void); 529void channel_output_poll(void);
451 530
452/* This is called when a packet of type CHANNEL_DATA has just been received. 531/*
453 The message type has already been consumed, but channel number and data 532 * This is called when a packet of type CHANNEL_DATA has just been received.
454 is still there. */ 533 * The message type has already been consumed, but channel number and data is
534 * still there.
535 */
455void channel_input_data(int payload_len); 536void channel_input_data(int payload_len);
456 537
457/* Returns true if no channel has too much buffered data. */ 538/* Returns true if no channel has too much buffered data. */
@@ -473,8 +554,10 @@ void channel_input_open_failure(void);
473 any unix domain sockets. */ 554 any unix domain sockets. */
474void channel_stop_listening(void); 555void channel_stop_listening(void);
475 556
476/* Closes the sockets of all channels. This is used to close extra file 557/*
477 descriptors after a fork. */ 558 * Closes the sockets of all channels. This is used to close extra file
559 * descriptors after a fork.
560 */
478void channel_close_all(void); 561void channel_close_all(void);
479 562
480/* Returns the maximum file descriptor number used by the channels. */ 563/* Returns the maximum file descriptor number used by the channels. */
@@ -483,92 +566,123 @@ int channel_max_fd(void);
483/* Returns true if there is still an open channel over the connection. */ 566/* Returns true if there is still an open channel over the connection. */
484int channel_still_open(void); 567int channel_still_open(void);
485 568
486/* Returns a string containing a list of all open channels. The list is 569/*
487 suitable for displaying to the user. It uses crlf instead of newlines. 570 * Returns a string containing a list of all open channels. The list is
488 The caller should free the string with xfree. */ 571 * suitable for displaying to the user. It uses crlf instead of newlines.
572 * The caller should free the string with xfree.
573 */
489char *channel_open_message(void); 574char *channel_open_message(void);
490 575
491/* Initiate forwarding of connections to local port "port" through the secure 576/*
492 channel to host:port from remote side. This never returns if there 577 * Initiate forwarding of connections to local port "port" through the secure
493 was an error. */ 578 * channel to host:port from remote side. This never returns if there was an
579 * error.
580 */
494void 581void
495channel_request_local_forwarding(int port, const char *host, 582channel_request_local_forwarding(int port, const char *host,
496 int remote_port); 583 int remote_port);
497 584
498/* Initiate forwarding of connections to port "port" on remote host through 585/*
499 the secure channel to host:port from local side. This never returns 586 * Initiate forwarding of connections to port "port" on remote host through
500 if there was an error. This registers that open requests for that 587 * the secure channel to host:port from local side. This never returns if
501 port are permitted. */ 588 * there was an error. This registers that open requests for that port are
589 * permitted.
590 */
502void 591void
503channel_request_remote_forwarding(int port, const char *host, 592channel_request_remote_forwarding(int port, const char *host,
504 int remote_port); 593 int remote_port);
505 594
506/* Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually 595/*
507 called by the server, because the user could connect to any port anyway, 596 * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually
508 and the server has no way to know but to trust the client anyway. */ 597 * called by the server, because the user could connect to any port anyway,
598 * and the server has no way to know but to trust the client anyway.
599 */
509void channel_permit_all_opens(void); 600void channel_permit_all_opens(void);
510 601
511/* This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates 602/*
512 listening for the port, and sends back a success reply (or disconnect 603 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
513 message if there was an error). This never returns if there was an 604 * listening for the port, and sends back a success reply (or disconnect
514 error. */ 605 * message if there was an error). This never returns if there was an error.
606 */
515void channel_input_port_forward_request(int is_root); 607void channel_input_port_forward_request(int is_root);
516 608
517/* This is called after receiving PORT_OPEN message. This attempts to connect 609/*
518 to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION or 610 * This is called after receiving PORT_OPEN message. This attempts to
519 CHANNEL_OPEN_FAILURE. */ 611 * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION
612 * or CHANNEL_OPEN_FAILURE.
613 */
520void channel_input_port_open(int payload_len); 614void channel_input_port_open(int payload_len);
521 615
522/* Creates a port for X11 connections, and starts listening for it. 616/*
523 Returns the display name, or NULL if an error was encountered. */ 617 * Creates a port for X11 connections, and starts listening for it. Returns
618 * the display name, or NULL if an error was encountered.
619 */
524char *x11_create_display(int screen); 620char *x11_create_display(int screen);
525 621
526/* Creates an internet domain socket for listening for X11 connections. 622/*
527 Returns a suitable value for the DISPLAY variable, or NULL if an error 623 * Creates an internet domain socket for listening for X11 connections.
528 occurs. */ 624 * Returns a suitable value for the DISPLAY variable, or NULL if an error
625 * occurs.
626 */
529char *x11_create_display_inet(int screen); 627char *x11_create_display_inet(int screen);
530 628
531/* This is called when SSH_SMSG_X11_OPEN is received. The packet contains 629/*
532 the remote channel number. We should do whatever we want, and respond 630 * This is called when SSH_SMSG_X11_OPEN is received. The packet contains
533 with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. */ 631 * the remote channel number. We should do whatever we want, and respond
632 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
633 */
534void x11_input_open(int payload_len); 634void x11_input_open(int payload_len);
535 635
536/* Requests forwarding of X11 connections. This should be called on the 636/*
537 client only. */ 637 * Requests forwarding of X11 connections. This should be called on the
638 * client only.
639 */
538void x11_request_forwarding(void); 640void x11_request_forwarding(void);
539 641
540/* Requests forwarding for X11 connections, with authentication spoofing. 642/*
541 This should be called in the client only. */ 643 * Requests forwarding for X11 connections, with authentication spoofing.
644 * This should be called in the client only.
645 */
542void x11_request_forwarding_with_spoofing(const char *proto, const char *data); 646void x11_request_forwarding_with_spoofing(const char *proto, const char *data);
543 647
544/* Sends a message to the server to request authentication fd forwarding. */ 648/* Sends a message to the server to request authentication fd forwarding. */
545void auth_request_forwarding(void); 649void auth_request_forwarding(void);
546 650
547/* Returns the name of the forwarded authentication socket. Returns NULL 651/*
548 if there is no forwarded authentication socket. The returned value points 652 * Returns the name of the forwarded authentication socket. Returns NULL if
549 to a static buffer. */ 653 * there is no forwarded authentication socket. The returned value points to
654 * a static buffer.
655 */
550char *auth_get_socket_name(void); 656char *auth_get_socket_name(void);
551 657
552/* This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. 658/*
553 This starts forwarding authentication requests. */ 659 * This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server.
660 * This starts forwarding authentication requests.
661 */
554void auth_input_request_forwarding(struct passwd * pw); 662void auth_input_request_forwarding(struct passwd * pw);
555 663
556/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ 664/* This is called to process an SSH_SMSG_AGENT_OPEN message. */
557void auth_input_open_request(void); 665void auth_input_open_request(void);
558 666
559/* Returns true if the given string matches the pattern (which may contain 667/*
560 ? and * as wildcards), and zero if it does not match. */ 668 * Returns true if the given string matches the pattern (which may contain ?
669 * and * as wildcards), and zero if it does not match.
670 */
561int match_pattern(const char *s, const char *pattern); 671int match_pattern(const char *s, const char *pattern);
562 672
563/* Expands tildes in the file name. Returns data allocated by xmalloc. 673/*
564 Warning: this calls getpw*. */ 674 * Expands tildes in the file name. Returns data allocated by xmalloc.
675 * Warning: this calls getpw*.
676 */
565char *tilde_expand_filename(const char *filename, uid_t my_uid); 677char *tilde_expand_filename(const char *filename, uid_t my_uid);
566 678
567/* Performs the interactive session. This handles data transmission between 679/*
568 the client and the program. Note that the notion of stdin, stdout, and 680 * Performs the interactive session. This handles data transmission between
569 stderr in this function is sort of reversed: this function writes to 681 * the client and the program. Note that the notion of stdin, stdout, and
570 stdin (of the child program), and reads from stdout and stderr (of the 682 * stderr in this function is sort of reversed: this function writes to stdin
571 child program). */ 683 * (of the child program), and reads from stdout and stderr (of the child
684 * program).
685 */
572void server_loop(int pid, int fdin, int fdout, int fderr); 686void server_loop(int pid, int fdin, int fdout, int fderr);
573 687
574/* Client side main loop for the interactive session. */ 688/* Client side main loop for the interactive session. */
@@ -582,9 +696,11 @@ struct envstring {
582#ifdef KRB4 696#ifdef KRB4
583#include <krb.h> 697#include <krb.h>
584 698
585/* Performs Kerberos v4 mutual authentication with the client. This returns 699/*
586 0 if the client could not be authenticated, and 1 if authentication was 700 * Performs Kerberos v4 mutual authentication with the client. This returns 0
587 successful. This may exit if there is a serious protocol violation. */ 701 * if the client could not be authenticated, and 1 if authentication was
702 * successful. This may exit if there is a serious protocol violation.
703 */
588int auth_krb4(const char *server_user, KTEXT auth, char **client); 704int auth_krb4(const char *server_user, KTEXT auth, char **client);
589int krb4_init(uid_t uid); 705int krb4_init(uid_t uid);
590void krb4_cleanup_proc(void *ignore); 706void krb4_cleanup_proc(void *ignore);
diff --git a/sshconnect.c b/sshconnect.c
index 0657c37e8..0b1c0901f 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "includes.h" 10#include "includes.h"
11RCSID("$Id: sshconnect.c,v 1.14 1999/11/24 13:26:23 damien Exp $"); 11RCSID("$Id: sshconnect.c,v 1.15 1999/11/25 00:54:59 damien Exp $");
12 12
13#ifdef HAVE_OPENSSL 13#ifdef HAVE_OPENSSL
14#include <openssl/bn.h> 14#include <openssl/bn.h>
@@ -142,8 +142,10 @@ ssh_create_socket(uid_t original_real_uid, int privileged)
142{ 142{
143 int sock; 143 int sock;
144 144
145 /* If we are running as root and want to connect to a privileged 145 /*
146 port, bind our own socket to a privileged port. */ 146 * If we are running as root and want to connect to a privileged
147 * port, bind our own socket to a privileged port.
148 */
147 if (privileged) { 149 if (privileged) {
148 int p = IPPORT_RESERVED - 1; 150 int p = IPPORT_RESERVED - 1;
149 151
@@ -227,9 +229,11 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr,
227 !anonymous && geteuid() == 0 && 229 !anonymous && geteuid() == 0 &&
228 port < IPPORT_RESERVED); 230 port < IPPORT_RESERVED);
229 231
230 /* Connect to the host. We use the user's uid in 232 /*
231 the hope that it will help with the problems of 233 * Connect to the host. We use the user's uid in the
232 tcp_wrappers showing the remote uid as root. */ 234 * hope that it will help with the problems of
235 * tcp_wrappers showing the remote uid as root.
236 */
233 temporarily_use_uid(original_real_uid); 237 temporarily_use_uid(original_real_uid);
234 if (connect(sock, (struct sockaddr *) hostaddr, sizeof(*hostaddr)) 238 if (connect(sock, (struct sockaddr *) hostaddr, sizeof(*hostaddr))
235 >= 0) { 239 >= 0) {
@@ -270,8 +274,12 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr,
270 !anonymous && geteuid() == 0 && 274 !anonymous && geteuid() == 0 &&
271 port < IPPORT_RESERVED); 275 port < IPPORT_RESERVED);
272 276
273 /* Connect to the host. We use the user's uid in the hope that 277 /*
274 it will help with tcp_wrappers showing the remote uid as root. */ 278 * Connect to the host. We use the user's
279 * uid in the hope that it will help with
280 * tcp_wrappers showing the remote uid as
281 * root.
282 */
275 temporarily_use_uid(original_real_uid); 283 temporarily_use_uid(original_real_uid);
276 if (connect(sock, (struct sockaddr *) hostaddr, 284 if (connect(sock, (struct sockaddr *) hostaddr,
277 sizeof(*hostaddr)) >= 0) { 285 sizeof(*hostaddr)) >= 0) {
@@ -282,8 +290,12 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr,
282 debug("connect: %.100s", strerror(errno)); 290 debug("connect: %.100s", strerror(errno));
283 restore_uid(); 291 restore_uid();
284 292
285 /* Close the failed socket; there appear to be some problems when 293 /*
286 reusing a socket for which connect() has already returned an error. */ 294 * Close the failed socket; there appear to
295 * be some problems when reusing a socket for
296 * which connect() has already returned an
297 * error.
298 */
287 shutdown(sock, SHUT_RDWR); 299 shutdown(sock, SHUT_RDWR);
288 close(sock); 300 close(sock);
289 } 301 }
@@ -300,10 +312,11 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr,
300 312
301 debug("Connection established."); 313 debug("Connection established.");
302 314
303 /* Set socket options. We would like the socket to disappear as 315 /*
304 soon as it has been closed for whatever reason. */ 316 * Set socket options. We would like the socket to disappear as soon
305 /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, 317 * as it has been closed for whatever reason.
306 sizeof(on)); */ 318 */
319 /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
307 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &on, sizeof(on)); 320 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &on, sizeof(on));
308 linger.l_onoff = 1; 321 linger.l_onoff = 1;
309 linger.l_linger = 5; 322 linger.l_linger = 5;
@@ -493,8 +506,10 @@ try_rsa_authentication(struct passwd * pw, const char *authfile)
493 /* Wait for server's response. */ 506 /* Wait for server's response. */
494 type = packet_read(&plen); 507 type = packet_read(&plen);
495 508
496 /* The server responds with failure if it doesn\'t like our key or 509 /*
497 doesn\'t support RSA authentication. */ 510 * The server responds with failure if it doesn\'t like our key or
511 * doesn\'t support RSA authentication.
512 */
498 if (type == SSH_SMSG_FAILURE) { 513 if (type == SSH_SMSG_FAILURE) {
499 debug("Server refused our key."); 514 debug("Server refused our key.");
500 xfree(comment); 515 xfree(comment);
@@ -514,8 +529,10 @@ try_rsa_authentication(struct passwd * pw, const char *authfile)
514 debug("Received RSA challenge from server."); 529 debug("Received RSA challenge from server.");
515 530
516 private_key = RSA_new(); 531 private_key = RSA_new();
517 /* Load the private key. Try first with empty passphrase; if it 532 /*
518 fails, ask for a passphrase. */ 533 * Load the private key. Try first with empty passphrase; if it
534 * fails, ask for a passphrase.
535 */
519 if (!load_private_key(authfile, "", private_key, NULL)) { 536 if (!load_private_key(authfile, "", private_key, NULL)) {
520 char buf[300]; 537 char buf[300];
521 snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", 538 snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
@@ -720,9 +737,11 @@ try_kerberos_authentication()
720 737
721 packet_integrity_check(plen, 4 + auth.length, type); 738 packet_integrity_check(plen, 4 + auth.length, type);
722 739
723 /* If his response isn't properly encrypted with the 740 /*
724 session key, and the decrypted checksum fails to match, 741 * If his response isn't properly encrypted with the session
725 he's bogus. Bail out. */ 742 * key, and the decrypted checksum fails to match, he's
743 * bogus. Bail out.
744 */
726 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, 745 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
727 &foreign, &local, &msg_data); 746 &foreign, &local, &msg_data);
728 if (r != KSUCCESS) { 747 if (r != KSUCCESS) {
@@ -894,8 +913,10 @@ ssh_exchange_identification()
894 } 913 }
895 buf[sizeof(buf) - 1] = 0; 914 buf[sizeof(buf) - 1] = 0;
896 915
897 /* Check that the versions match. In future this might accept 916 /*
898 several versions and set appropriate flags to handle them. */ 917 * Check that the versions match. In future this might accept
918 * several versions and set appropriate flags to handle them.
919 */
899 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, 920 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
900 remote_version) != 3) 921 remote_version) != 3)
901 fatal("Bad remote protocol version identification: '%.100s'", buf); 922 fatal("Bad remote protocol version identification: '%.100s'", buf);
@@ -916,9 +937,11 @@ ssh_exchange_identification()
916 } 937 }
917 } 938 }
918#if 0 939#if 0
919 /* Removed for now, to permit compatibility with latter versions. 940 /*
920 The server will reject our version and disconnect if it doesn't 941 * Removed for now, to permit compatibility with latter versions. The
921 support it. */ 942 * server will reject our version and disconnect if it doesn't
943 * support it.
944 */
922 if (remote_major != PROTOCOL_MAJOR) 945 if (remote_major != PROTOCOL_MAJOR)
923 fatal("Protocol major versions differ: %d vs. %d", 946 fatal("Protocol major versions differ: %d vs. %d",
924 PROTOCOL_MAJOR, remote_major); 947 PROTOCOL_MAJOR, remote_major);
@@ -1086,10 +1109,7 @@ ssh_login(int host_key_valid,
1086 protocol_flags = packet_get_int(); 1109 protocol_flags = packet_get_int();
1087 packet_set_protocol_flags(protocol_flags); 1110 packet_set_protocol_flags(protocol_flags);
1088 1111
1089 /* Get supported cipher types. */
1090 supported_ciphers = packet_get_int(); 1112 supported_ciphers = packet_get_int();
1091
1092 /* Get supported authentication types. */
1093 supported_authentications = packet_get_int(); 1113 supported_authentications = packet_get_int();
1094 1114
1095 debug("Received server public key (%d bits) and host key (%d bits).", 1115 debug("Received server public key (%d bits) and host key (%d bits).",
@@ -1099,11 +1119,12 @@ ssh_login(int host_key_valid,
1099 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, 1119 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
1100 SSH_SMSG_PUBLIC_KEY); 1120 SSH_SMSG_PUBLIC_KEY);
1101 1121
1102 /* Compute the session id. */
1103 compute_session_id(session_id, check_bytes, host_key->n, public_key->n); 1122 compute_session_id(session_id, check_bytes, host_key->n, public_key->n);
1104 1123
1105 /* Check if the host key is present in the user\'s list of known 1124 /*
1106 hosts or in the systemwide list. */ 1125 * Check if the host key is present in the user\'s list of known
1126 * hosts or in the systemwide list.
1127 */
1107 host_status = check_host_in_hostfile(options.user_hostfile, host, 1128 host_status = check_host_in_hostfile(options.user_hostfile, host,
1108 host_key->e, host_key->n, 1129 host_key->e, host_key->n,
1109 file_key->e, file_key->n); 1130 file_key->e, file_key->n);
@@ -1111,18 +1132,22 @@ ssh_login(int host_key_valid,
1111 host_status = check_host_in_hostfile(options.system_hostfile, host, 1132 host_status = check_host_in_hostfile(options.system_hostfile, host,
1112 host_key->e, host_key->n, 1133 host_key->e, host_key->n,
1113 file_key->e, file_key->n); 1134 file_key->e, file_key->n);
1114 /* Force accepting of the host key for localhost and 127.0.0.1. 1135 /*
1115 The problem is that if the home directory is NFS-mounted to 1136 * Force accepting of the host key for localhost and 127.0.0.1. The
1116 multiple machines, localhost will refer to a different machine 1137 * problem is that if the home directory is NFS-mounted to multiple
1117 in each of them, and the user will get bogus HOST_CHANGED 1138 * machines, localhost will refer to a different machine in each of
1118 warnings. This essentially disables host authentication for 1139 * them, and the user will get bogus HOST_CHANGED warnings. This
1119 localhost; however, this is probably not a real problem. */ 1140 * essentially disables host authentication for localhost; however,
1141 * this is probably not a real problem.
1142 */
1120 if (local) { 1143 if (local) {
1121 debug("Forcing accepting of host key for localhost."); 1144 debug("Forcing accepting of host key for localhost.");
1122 host_status = HOST_OK; 1145 host_status = HOST_OK;
1123 } 1146 }
1124 /* Also perform check for the ip address, skip the check if we are 1147 /*
1125 localhost or the hostname was an ip address to begin with */ 1148 * Also perform check for the ip address, skip the check if we are
1149 * localhost or the hostname was an ip address to begin with
1150 */
1126 if (options.check_host_ip && !local && strcmp(host, ip)) { 1151 if (options.check_host_ip && !local && strcmp(host, ip)) {
1127 RSA *ip_key = RSA_new(); 1152 RSA *ip_key = RSA_new();
1128 ip_key->n = BN_new(); 1153 ip_key->n = BN_new();
@@ -1226,13 +1251,18 @@ ssh_login(int host_key_valid,
1226 error("Add correct host key in %.100s to get rid of this message.", 1251 error("Add correct host key in %.100s to get rid of this message.",
1227 options.user_hostfile); 1252 options.user_hostfile);
1228 1253
1229 /* If strict host key checking is in use, the user will 1254 /*
1230 have to edit the key manually and we can only abort. */ 1255 * If strict host key checking is in use, the user will have
1256 * to edit the key manually and we can only abort.
1257 */
1231 if (options.strict_host_key_checking) 1258 if (options.strict_host_key_checking)
1232 fatal("Host key for %.200s has changed and you have requested strict checking.", host); 1259 fatal("Host key for %.200s has changed and you have requested strict checking.", host);
1233 1260
1234 /* If strict host key checking has not been requested, allow the connection 1261 /*
1235 but without password authentication or agent forwarding. */ 1262 * If strict host key checking has not been requested, allow
1263 * the connection but without password authentication or
1264 * agent forwarding.
1265 */
1236 if (options.password_authentication) { 1266 if (options.password_authentication) {
1237 error("Password authentication is disabled to avoid trojan horses."); 1267 error("Password authentication is disabled to avoid trojan horses.");
1238 options.password_authentication = 0; 1268 options.password_authentication = 0;
@@ -1241,11 +1271,13 @@ ssh_login(int host_key_valid,
1241 error("Agent forwarding is disabled to avoid trojan horses."); 1271 error("Agent forwarding is disabled to avoid trojan horses.");
1242 options.forward_agent = 0; 1272 options.forward_agent = 0;
1243 } 1273 }
1244 /* XXX Should permit the user to change to use the new id. 1274 /*
1245 This could be done by converting the host key to an 1275 * XXX Should permit the user to change to use the new id.
1246 identifying sentence, tell that the host identifies 1276 * This could be done by converting the host key to an
1247 itself by that sentence, and ask the user if he/she 1277 * identifying sentence, tell that the host identifies itself
1248 whishes to accept the authentication. */ 1278 * by that sentence, and ask the user if he/she whishes to
1279 * accept the authentication.
1280 */
1249 break; 1281 break;
1250 } 1282 }
1251 1283
@@ -1255,9 +1287,11 @@ ssh_login(int host_key_valid,
1255 /* Generate a session key. */ 1287 /* Generate a session key. */
1256 arc4random_stir(); 1288 arc4random_stir();
1257 1289
1258 /* Generate an encryption key for the session. The key is a 256 1290 /*
1259 bit random number, interpreted as a 32-byte key, with the least 1291 * Generate an encryption key for the session. The key is a 256 bit
1260 significant 8 bits being the first byte of the key. */ 1292 * random number, interpreted as a 32-byte key, with the least
1293 * significant 8 bits being the first byte of the key.
1294 */
1261 for (i = 0; i < 32; i++) { 1295 for (i = 0; i < 32; i++) {
1262 if (i % 4 == 0) 1296 if (i % 4 == 0)
1263 rand = arc4random(); 1297 rand = arc4random();
@@ -1265,9 +1299,11 @@ ssh_login(int host_key_valid,
1265 rand >>= 8; 1299 rand >>= 8;
1266 } 1300 }
1267 1301
1268 /* According to the protocol spec, the first byte of the session 1302 /*
1269 key is the highest byte of the integer. The session key is 1303 * According to the protocol spec, the first byte of the session key
1270 xored with the first 16 bytes of the session id. */ 1304 * is the highest byte of the integer. The session key is xored with
1305 * the first 16 bytes of the session id.
1306 */
1271 key = BN_new(); 1307 key = BN_new();
1272 BN_set_word(key, 0); 1308 BN_set_word(key, 0);
1273 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { 1309 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
@@ -1278,8 +1314,10 @@ ssh_login(int host_key_valid,
1278 BN_add_word(key, session_key[i]); 1314 BN_add_word(key, session_key[i]);
1279 } 1315 }
1280 1316
1281 /* Encrypt the integer using the public key and host key of the 1317 /*
1282 server (key with smaller modulus first). */ 1318 * Encrypt the integer using the public key and host key of the
1319 * server (key with smaller modulus first).
1320 */
1283 if (BN_cmp(public_key->n, host_key->n) < 0) { 1321 if (BN_cmp(public_key->n, host_key->n) < 0) {
1284 /* Public key has smaller modulus. */ 1322 /* Public key has smaller modulus. */
1285 if (BN_num_bits(host_key->n) < 1323 if (BN_num_bits(host_key->n) <
@@ -1354,8 +1392,10 @@ ssh_login(int host_key_valid,
1354 /* We will no longer need the session key here. Destroy any extra copies. */ 1392 /* We will no longer need the session key here. Destroy any extra copies. */
1355 memset(session_key, 0, sizeof(session_key)); 1393 memset(session_key, 0, sizeof(session_key));
1356 1394
1357 /* Expect a success message from the server. Note that this 1395 /*
1358 message will be received in encrypted form. */ 1396 * Expect a success message from the server. Note that this message
1397 * will be received in encrypted form.
1398 */
1359 packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); 1399 packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
1360 1400
1361 debug("Received encrypted confirmation."); 1401 debug("Received encrypted confirmation.");
@@ -1366,9 +1406,11 @@ ssh_login(int host_key_valid,
1366 packet_send(); 1406 packet_send();
1367 packet_write_wait(); 1407 packet_write_wait();
1368 1408
1369 /* The server should respond with success if no authentication is 1409 /*
1370 needed (the user has no password). Otherwise the server 1410 * The server should respond with success if no authentication is
1371 responds with failure. */ 1411 * needed (the user has no password). Otherwise the server responds
1412 * with failure.
1413 */
1372 type = packet_read(&payload_len); 1414 type = packet_read(&payload_len);
1373 1415
1374 /* check whether the connection was accepted without authentication. */ 1416 /* check whether the connection was accepted without authentication. */
@@ -1410,8 +1452,10 @@ ssh_login(int host_key_valid,
1410 } 1452 }
1411#endif /* KRB4 */ 1453#endif /* KRB4 */
1412 1454
1413 /* Use rhosts authentication if running in privileged socket and 1455 /*
1414 we do not wish to remain anonymous. */ 1456 * Use rhosts authentication if running in privileged socket and we
1457 * do not wish to remain anonymous.
1458 */
1415 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && 1459 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
1416 options.rhosts_authentication) { 1460 options.rhosts_authentication) {
1417 debug("Trying rhosts authentication."); 1461 debug("Trying rhosts authentication.");
@@ -1428,8 +1472,10 @@ ssh_login(int host_key_valid,
1428 packet_disconnect("Protocol error: got %d in response to rhosts auth", 1472 packet_disconnect("Protocol error: got %d in response to rhosts auth",
1429 type); 1473 type);
1430 } 1474 }
1431 /* Try .rhosts or /etc/hosts.equiv authentication with RSA host 1475 /*
1432 authentication. */ 1476 * Try .rhosts or /etc/hosts.equiv authentication with RSA host
1477 * authentication.
1478 */
1433 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && 1479 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
1434 options.rhosts_rsa_authentication && host_key_valid) { 1480 options.rhosts_rsa_authentication && host_key_valid) {
1435 if (try_rhosts_rsa_authentication(local_user, own_host_key)) 1481 if (try_rhosts_rsa_authentication(local_user, own_host_key))
@@ -1438,10 +1484,11 @@ ssh_login(int host_key_valid,
1438 /* Try RSA authentication if the server supports it. */ 1484 /* Try RSA authentication if the server supports it. */
1439 if ((supported_authentications & (1 << SSH_AUTH_RSA)) && 1485 if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
1440 options.rsa_authentication) { 1486 options.rsa_authentication) {
1441 /* Try RSA authentication using the authentication agent. 1487 /*
1442 The agent is tried first because no passphrase is 1488 * Try RSA authentication using the authentication agent. The
1443 needed for it, whereas identity files may require 1489 * agent is tried first because no passphrase is needed for
1444 passphrases. */ 1490 * it, whereas identity files may require passphrases.
1491 */
1445 if (try_agent_authentication()) 1492 if (try_agent_authentication())
1446 return; 1493 return;
1447 1494
diff --git a/sshd.c b/sshd.c
index d65671ddd..c4b1d1dfe 100644
--- a/sshd.c
+++ b/sshd.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include "includes.h" 13#include "includes.h"
14RCSID("$Id: sshd.c,v 1.31 1999/11/24 23:42:08 damien Exp $"); 14RCSID("$Id: sshd.c,v 1.32 1999/11/25 00:54:59 damien Exp $");
15 15
16#include "xmalloc.h" 16#include "xmalloc.h"
17#include "rsa.h" 17#include "rsa.h"
@@ -65,12 +65,16 @@ char *av0;
65/* Saved arguments to main(). */ 65/* Saved arguments to main(). */
66char **saved_argv; 66char **saved_argv;
67 67
68/* This is set to the socket that the server is listening; this is used in 68/*
69 the SIGHUP signal handler. */ 69 * This is set to the socket that the server is listening; this is used in
70 * the SIGHUP signal handler.
71 */
70int listen_sock; 72int listen_sock;
71 73
72/* the client's version string, passed by sshd2 in compat mode. 74/*
73 if != NULL, sshd will skip the version-number exchange */ 75 * the client's version string, passed by sshd2 in compat mode. if != NULL,
76 * sshd will skip the version-number exchange
77 */
74char *client_version_string = NULL; 78char *client_version_string = NULL;
75 79
76/* Flags set in auth-rsa from authorized_keys flags. These are set in auth-rsa.c. */ 80/* Flags set in auth-rsa from authorized_keys flags. These are set in auth-rsa.c. */
@@ -88,19 +92,23 @@ struct envstring *custom_environment = NULL;
88/* Session id for the current session. */ 92/* Session id for the current session. */
89unsigned char session_id[16]; 93unsigned char session_id[16];
90 94
91/* Any really sensitive data in the application is contained in this structure. 95/*
92 The idea is that this structure could be locked into memory so that the 96 * Any really sensitive data in the application is contained in this
93 pages do not get written into swap. However, there are some problems. 97 * structure. The idea is that this structure could be locked into memory so
94 The private key contains BIGNUMs, and we do not (in principle) have 98 * that the pages do not get written into swap. However, there are some
95 access to the internals of them, and locking just the structure is not 99 * problems. The private key contains BIGNUMs, and we do not (in principle)
96 very useful. Currently, memory locking is not implemented. */ 100 * have access to the internals of them, and locking just the structure is
101 * not very useful. Currently, memory locking is not implemented.
102 */
97struct { 103struct {
98 RSA *private_key; /* Private part of server key. */ 104 RSA *private_key; /* Private part of server key. */
99 RSA *host_key; /* Private part of host key. */ 105 RSA *host_key; /* Private part of host key. */
100} sensitive_data; 106} sensitive_data;
101 107
102/* Flag indicating whether the current session key has been used. This flag 108/*
103 is set whenever the key is used, and cleared when the key is regenerated. */ 109 * Flag indicating whether the current session key has been used. This flag
110 * is set whenever the key is used, and cleared when the key is regenerated.
111 */
104int key_used = 0; 112int key_used = 0;
105 113
106/* This is set to true when SIGHUP is received. */ 114/* This is set to true when SIGHUP is received. */
@@ -466,7 +474,7 @@ main(int ac, char **av)
466 fprintf(stderr, "sshd version %s\n", SSH_VERSION); 474 fprintf(stderr, "sshd version %s\n", SSH_VERSION);
467 fprintf(stderr, "Usage: %s [options]\n", av0); 475 fprintf(stderr, "Usage: %s [options]\n", av0);
468 fprintf(stderr, "Options:\n"); 476 fprintf(stderr, "Options:\n");
469 fprintf(stderr, " -f file Configuration file (default %s/sshd_config)\n", ETCDIR); 477 fprintf(stderr, " -f file Configuration file (default %s)\n", SERVER_CONFIG_FILE);
470 fprintf(stderr, " -d Debugging mode\n"); 478 fprintf(stderr, " -d Debugging mode\n");
471 fprintf(stderr, " -i Started from inetd\n"); 479 fprintf(stderr, " -i Started from inetd\n");
472 fprintf(stderr, " -q Quiet (no logging)\n"); 480 fprintf(stderr, " -q Quiet (no logging)\n");
@@ -614,13 +622,11 @@ main(int ac, char **av)
614 setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *) &linger, 622 setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *) &linger,
615 sizeof(linger)); 623 sizeof(linger));
616 624
617 /* Initialize the socket address. */
618 memset(&sin, 0, sizeof(sin)); 625 memset(&sin, 0, sizeof(sin));
619 sin.sin_family = AF_INET; 626 sin.sin_family = AF_INET;
620 sin.sin_addr = options.listen_addr; 627 sin.sin_addr = options.listen_addr;
621 sin.sin_port = htons(options.port); 628 sin.sin_port = htons(options.port);
622 629
623 /* Bind the socket to the desired port. */
624 if (bind(listen_sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) { 630 if (bind(listen_sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) {
625 error("bind: %.100s", strerror(errno)); 631 error("bind: %.100s", strerror(errno));
626 shutdown(listen_sock, SHUT_RDWR); 632 shutdown(listen_sock, SHUT_RDWR);
@@ -628,12 +634,13 @@ main(int ac, char **av)
628 fatal("Bind to port %d failed.", options.port); 634 fatal("Bind to port %d failed.", options.port);
629 } 635 }
630 if (!debug_flag) { 636 if (!debug_flag) {
631 /* Record our pid in /etc/sshd_pid to make it 637 /*
632 easier to kill the correct sshd. We don\'t 638 * Record our pid in /etc/sshd_pid to make it easier
633 want to do this before the bind above because 639 * to kill the correct sshd. We don\'t want to do
634 the bind will fail if there already is a 640 * this before the bind above because the bind will
635 daemon, and this will overwrite any old pid in 641 * fail if there already is a daemon, and this will
636 the file. */ 642 * overwrite any old pid in the file.
643 */
637 f = fopen(SSH_DAEMON_PID_FILE, "w"); 644 f = fopen(SSH_DAEMON_PID_FILE, "w");
638 if (f) { 645 if (f) {
639 fprintf(f, "%u\n", (unsigned int) getpid()); 646 fprintf(f, "%u\n", (unsigned int) getpid());
@@ -666,8 +673,10 @@ main(int ac, char **av)
666 /* Arrange SIGCHLD to be caught. */ 673 /* Arrange SIGCHLD to be caught. */
667 signal(SIGCHLD, main_sigchld_handler); 674 signal(SIGCHLD, main_sigchld_handler);
668 675
669 /* Stay listening for connections until the system crashes 676 /*
670 or the daemon is killed with a signal. */ 677 * Stay listening for connections until the system crashes or
678 * the daemon is killed with a signal.
679 */
671 for (;;) { 680 for (;;) {
672 if (received_sighup) 681 if (received_sighup)
673 sighup_restart(); 682 sighup_restart();
@@ -682,12 +691,16 @@ main(int ac, char **av)
682 error("accept: %.100s", strerror(errno)); 691 error("accept: %.100s", strerror(errno));
683 continue; 692 continue;
684 } 693 }
685 /* Got connection. Fork a child to handle it, 694 /*
686 unless we are in debugging mode. */ 695 * Got connection. Fork a child to handle it, unless
696 * we are in debugging mode.
697 */
687 if (debug_flag) { 698 if (debug_flag) {
688 /* In debugging mode. Close the listening 699 /*
689 socket, and start processing the 700 * In debugging mode. Close the listening
690 connection without forking. */ 701 * socket, and start processing the
702 * connection without forking.
703 */
691 debug("Server will not fork when running in debugging mode."); 704 debug("Server will not fork when running in debugging mode.");
692 close(listen_sock); 705 close(listen_sock);
693 sock_in = newsock; 706 sock_in = newsock;
@@ -695,16 +708,17 @@ main(int ac, char **av)
695 pid = getpid(); 708 pid = getpid();
696 break; 709 break;
697 } else { 710 } else {
698 /* Normal production daemon. Fork, and 711 /*
699 have the child process the connection. 712 * Normal production daemon. Fork, and have
700 The parent continues listening. */ 713 * the child process the connection. The
714 * parent continues listening.
715 */
701 if ((pid = fork()) == 0) { 716 if ((pid = fork()) == 0) {
702 /* Child. Close the listening 717 /*
703 socket, and start using the 718 * Child. Close the listening socket, and start using the
704 accepted socket. Reinitialize 719 * accepted socket. Reinitialize logging (since our pid has
705 logging (since our pid has 720 * changed). We break out of the loop to handle the connection.
706 changed). We break out of the 721 */
707 loop to handle the connection. */
708 close(listen_sock); 722 close(listen_sock);
709 sock_in = newsock; 723 sock_in = newsock;
710 sock_out = newsock; 724 sock_out = newsock;
@@ -731,9 +745,11 @@ main(int ac, char **av)
731 745
732 /* This is the child processing a new connection. */ 746 /* This is the child processing a new connection. */
733 747
734 /* Disable the key regeneration alarm. We will not regenerate the 748 /*
735 key since we are no longer in a position to give it to anyone. 749 * Disable the key regeneration alarm. We will not regenerate the
736 We will not restart on SIGHUP since it no longer makes sense. */ 750 * key since we are no longer in a position to give it to anyone. We
751 * will not restart on SIGHUP since it no longer makes sense.
752 */
737 alarm(0); 753 alarm(0);
738 signal(SIGALRM, SIG_DFL); 754 signal(SIGALRM, SIG_DFL);
739 signal(SIGHUP, SIG_DFL); 755 signal(SIGHUP, SIG_DFL);
@@ -741,17 +757,20 @@ main(int ac, char **av)
741 signal(SIGQUIT, SIG_DFL); 757 signal(SIGQUIT, SIG_DFL);
742 signal(SIGCHLD, SIG_DFL); 758 signal(SIGCHLD, SIG_DFL);
743 759
744 /* Set socket options for the connection. We want the socket to 760 /*
745 close as fast as possible without waiting for anything. If the 761 * Set socket options for the connection. We want the socket to
746 connection is not a socket, these will do nothing. */ 762 * close as fast as possible without waiting for anything. If the
747 /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, 763 * connection is not a socket, these will do nothing.
748 sizeof(on)); */ 764 */
765 /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
749 linger.l_onoff = 1; 766 linger.l_onoff = 1;
750 linger.l_linger = 5; 767 linger.l_linger = 5;
751 setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); 768 setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
752 769
753 /* Register our connection. This turns encryption off because we 770 /*
754 do not have a key. */ 771 * Register our connection. This turns encryption off because we do
772 * not have a key.
773 */
755 packet_set_connection(sock_in, sock_out); 774 packet_set_connection(sock_in, sock_out);
756 775
757 remote_port = get_remote_port(); 776 remote_port = get_remote_port();
@@ -777,12 +796,14 @@ main(int ac, char **av)
777 verbose("Connection from %.500s port %d", remote_ip, remote_port); 796 verbose("Connection from %.500s port %d", remote_ip, remote_port);
778#endif /* LIBWRAP */ 797#endif /* LIBWRAP */
779 798
780 /* We don\'t want to listen forever unless the other side 799 /*
781 successfully authenticates itself. So we set up an alarm which 800 * We don\'t want to listen forever unless the other side
782 is cleared after successful authentication. A limit of zero 801 * successfully authenticates itself. So we set up an alarm which is
783 indicates no limit. Note that we don\'t set the alarm in 802 * cleared after successful authentication. A limit of zero
784 debugging mode; it is just annoying to have the server exit 803 * indicates no limit. Note that we don\'t set the alarm in debugging
785 just when you are about to discover the bug. */ 804 * mode; it is just annoying to have the server exit just when you
805 * are about to discover the bug.
806 */
786 signal(SIGALRM, grace_alarm_handler); 807 signal(SIGALRM, grace_alarm_handler);
787 if (!debug_flag) 808 if (!debug_flag)
788 alarm(options.login_grace_time); 809 alarm(options.login_grace_time);
@@ -815,8 +836,10 @@ main(int ac, char **av)
815 buf[sizeof(buf) - 1] = 0; 836 buf[sizeof(buf) - 1] = 0;
816 } 837 }
817 838
818 /* Check that the versions match. In future this might accept 839 /*
819 several versions and set appropriate flags to handle them. */ 840 * Check that the versions match. In future this might accept
841 * several versions and set appropriate flags to handle them.
842 */
820 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, 843 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
821 remote_version) != 3) { 844 remote_version) != 3) {
822 const char *s = "Protocol mismatch.\n"; 845 const char *s = "Protocol mismatch.\n";
@@ -848,11 +871,13 @@ main(int ac, char **av)
848 no_agent_forwarding_flag = 1; 871 no_agent_forwarding_flag = 1;
849 } 872 }
850 } 873 }
851 /* Check that the connection comes from a privileged port. Rhosts- 874 /*
852 and Rhosts-RSA-Authentication only make sense from priviledged 875 * Check that the connection comes from a privileged port. Rhosts-
853 programs. Of course, if the intruder has root access on his 876 * and Rhosts-RSA-Authentication only make sense from priviledged
854 local machine, he can connect from any port. So do not use 877 * programs. Of course, if the intruder has root access on his local
855 these authentication methods from machines that you do not trust. */ 878 * machine, he can connect from any port. So do not use these
879 * authentication methods from machines that you do not trust.
880 */
856 if (remote_port >= IPPORT_RESERVED || 881 if (remote_port >= IPPORT_RESERVED ||
857 remote_port < IPPORT_RESERVED / 2) { 882 remote_port < IPPORT_RESERVED / 2) {
858 options.rhosts_authentication = 0; 883 options.rhosts_authentication = 0;
@@ -914,13 +939,15 @@ do_connection()
914 int plen, slen; 939 int plen, slen;
915 u_int32_t rand = 0; 940 u_int32_t rand = 0;
916 941
917 /* Generate check bytes that the client must send back in the user 942 /*
918 packet in order for it to be accepted; this is used to defy ip 943 * Generate check bytes that the client must send back in the user
919 spoofing attacks. Note that this only works against somebody 944 * packet in order for it to be accepted; this is used to defy ip
920 doing IP spoofing from a remote machine; any machine on the 945 * spoofing attacks. Note that this only works against somebody
921 local network can still see outgoing packets and catch the 946 * doing IP spoofing from a remote machine; any machine on the local
922 random cookie. This only affects rhosts authentication, and 947 * network can still see outgoing packets and catch the random
923 this is one of the reasons why it is inherently insecure. */ 948 * cookie. This only affects rhosts authentication, and this is one
949 * of the reasons why it is inherently insecure.
950 */
924 for (i = 0; i < 8; i++) { 951 for (i = 0; i < 8; i++) {
925 if (i % 4 == 0) 952 if (i % 4 == 0)
926 rand = arc4random(); 953 rand = arc4random();
@@ -928,9 +955,11 @@ do_connection()
928 rand >>= 8; 955 rand >>= 8;
929 } 956 }
930 957
931 /* Send our public key. We include in the packet 64 bits of 958 /*
932 random data that must be matched in the reply in order to 959 * Send our public key. We include in the packet 64 bits of random
933 prevent IP spoofing. */ 960 * data that must be matched in the reply in order to prevent IP
961 * spoofing.
962 */
934 packet_start(SSH_SMSG_PUBLIC_KEY); 963 packet_start(SSH_SMSG_PUBLIC_KEY);
935 for (i = 0; i < 8; i++) 964 for (i = 0; i < 8; i++)
936 packet_put_char(check_bytes[i]); 965 packet_put_char(check_bytes[i]);
@@ -1002,14 +1031,15 @@ do_connection()
1002 session_key_int = BN_new(); 1031 session_key_int = BN_new();
1003 packet_get_bignum(session_key_int, &slen); 1032 packet_get_bignum(session_key_int, &slen);
1004 1033
1005 /* Get protocol flags. */
1006 protocol_flags = packet_get_int(); 1034 protocol_flags = packet_get_int();
1007 packet_set_protocol_flags(protocol_flags); 1035 packet_set_protocol_flags(protocol_flags);
1008 1036
1009 packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY); 1037 packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY);
1010 1038
1011 /* Decrypt it using our private server key and private host key 1039 /*
1012 (key with larger modulus first). */ 1040 * Decrypt it using our private server key and private host key (key
1041 * with larger modulus first).
1042 */
1013 if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) { 1043 if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) {
1014 /* Private key has bigger modulus. */ 1044 /* Private key has bigger modulus. */
1015 if (BN_num_bits(sensitive_data.private_key->n) < 1045 if (BN_num_bits(sensitive_data.private_key->n) <
@@ -1040,14 +1070,15 @@ do_connection()
1040 sensitive_data.private_key); 1070 sensitive_data.private_key);
1041 } 1071 }
1042 1072
1043 /* Compute session id for this session. */
1044 compute_session_id(session_id, check_bytes, 1073 compute_session_id(session_id, check_bytes,
1045 sensitive_data.host_key->n, 1074 sensitive_data.host_key->n,
1046 sensitive_data.private_key->n); 1075 sensitive_data.private_key->n);
1047 1076
1048 /* Extract session key from the decrypted integer. The key is in 1077 /*
1049 the least significant 256 bits of the integer; the first byte 1078 * Extract session key from the decrypted integer. The key is in the
1050 of the key is in the highest bits. */ 1079 * least significant 256 bits of the integer; the first byte of the
1080 * key is in the highest bits.
1081 */
1051 BN_mask_bits(session_key_int, sizeof(session_key) * 8); 1082 BN_mask_bits(session_key_int, sizeof(session_key) * 8);
1052 len = BN_num_bytes(session_key_int); 1083 len = BN_num_bytes(session_key_int);
1053 if (len < 0 || len > sizeof(session_key)) 1084 if (len < 0 || len > sizeof(session_key))
@@ -1125,8 +1156,7 @@ allowed_user(struct passwd * pw)
1125 if (match_pattern(pw->pw_name, options.deny_users[i])) 1156 if (match_pattern(pw->pw_name, options.deny_users[i]))
1126 return 0; 1157 return 0;
1127 } 1158 }
1128 /* Return false if AllowUsers isn't empty and user isn't listed 1159 /* Return false if AllowUsers isn't empty and user isn't listed there */
1129 there */
1130 if (options.num_allow_users > 0) { 1160 if (options.num_allow_users > 0) {
1131 if (!pw->pw_name) 1161 if (!pw->pw_name)
1132 return 0; 1162 return 0;
@@ -1151,8 +1181,10 @@ allowed_user(struct passwd * pw)
1151 if (match_pattern(grp->gr_name, options.deny_groups[i])) 1181 if (match_pattern(grp->gr_name, options.deny_groups[i]))
1152 return 0; 1182 return 0;
1153 } 1183 }
1154 /* Return false if AllowGroups isn't empty and user's 1184 /*
1155 group isn't listed there */ 1185 * Return false if AllowGroups isn't empty and user's group
1186 * isn't listed there
1187 */
1156 if (options.num_allow_groups > 0) { 1188 if (options.num_allow_groups > 0) {
1157 if (!grp->gr_name) 1189 if (!grp->gr_name)
1158 return 0; 1190 return 0;
@@ -1216,8 +1248,10 @@ do_authentication(char *user)
1216 } 1248 }
1217#endif 1249#endif
1218 1250
1219 /* If we are not running as root, the user must have the same uid 1251 /*
1220 as the server. */ 1252 * If we are not running as root, the user must have the same uid as
1253 * the server.
1254 */
1221 if (getuid() != 0 && pw->pw_uid != getuid()) 1255 if (getuid() != 0 && pw->pw_uid != getuid())
1222 packet_disconnect("Cannot change user when server not running as root."); 1256 packet_disconnect("Cannot change user when server not running as root.");
1223 1257
@@ -1357,10 +1391,12 @@ do_authloop(struct passwd * pw)
1357 verbose("Rhosts authentication disabled."); 1391 verbose("Rhosts authentication disabled.");
1358 break; 1392 break;
1359 } 1393 }
1360 /* Get client user name. Note that we just have 1394 /*
1361 to trust the client; this is one reason why 1395 * Get client user name. Note that we just have to
1362 rhosts authentication is insecure. (Another is 1396 * trust the client; this is one reason why rhosts
1363 IP-spoofing on a local network.) */ 1397 * authentication is insecure. (Another is
1398 * IP-spoofing on a local network.)
1399 */
1364 client_user = packet_get_string(&ulen); 1400 client_user = packet_get_string(&ulen);
1365 packet_integrity_check(plen, 4 + ulen, type); 1401 packet_integrity_check(plen, 4 + ulen, type);
1366 1402
@@ -1379,9 +1415,11 @@ do_authloop(struct passwd * pw)
1379 verbose("Rhosts with RSA authentication disabled."); 1415 verbose("Rhosts with RSA authentication disabled.");
1380 break; 1416 break;
1381 } 1417 }
1382 /* Get client user name. Note that we just have 1418 /*
1383 to trust the client; root on the client machine 1419 * Get client user name. Note that we just have to
1384 can claim to be any user. */ 1420 * trust the client; root on the client machine can
1421 * claim to be any user.
1422 */
1385 client_user = packet_get_string(&ulen); 1423 client_user = packet_get_string(&ulen);
1386 1424
1387 /* Get the client host key. */ 1425 /* Get the client host key. */
@@ -1425,9 +1463,11 @@ do_authloop(struct passwd * pw)
1425 verbose("Password authentication disabled."); 1463 verbose("Password authentication disabled.");
1426 break; 1464 break;
1427 } 1465 }
1428 /* Read user password. It is in plain text, but 1466 /*
1429 was transmitted over the encrypted channel so 1467 * Read user password. It is in plain text, but was
1430 it is not visible to an outside observer. */ 1468 * transmitted over the encrypted channel so it is
1469 * not visible to an outside observer.
1470 */
1431 password = packet_get_string(&dlen); 1471 password = packet_get_string(&dlen);
1432 packet_integrity_check(plen, 4 + dlen, type); 1472 packet_integrity_check(plen, 4 + dlen, type);
1433 1473
@@ -1463,8 +1503,7 @@ do_authloop(struct passwd * pw)
1463 skeyinfo = skey_fake_keyinfo(pw->pw_name); 1503 skeyinfo = skey_fake_keyinfo(pw->pw_name);
1464 } 1504 }
1465 if (skeyinfo != NULL) { 1505 if (skeyinfo != NULL) {
1466 /* we send our s/key- in 1506 /* we send our s/key- in tis-challenge messages */
1467 tis-challenge messages */
1468 debug("sending challenge '%s'", skeyinfo); 1507 debug("sending challenge '%s'", skeyinfo);
1469 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); 1508 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
1470 packet_put_string(skeyinfo, strlen(skeyinfo)); 1509 packet_put_string(skeyinfo, strlen(skeyinfo));
@@ -1493,8 +1532,10 @@ do_authloop(struct passwd * pw)
1493#endif 1532#endif
1494 1533
1495 default: 1534 default:
1496 /* Any unknown messages will be ignored (and 1535 /*
1497 failure returned) during authentication. */ 1536 * Any unknown messages will be ignored (and failure
1537 * returned) during authentication.
1538 */
1498 log("Unknown message during authentication: type %d", type); 1539 log("Unknown message during authentication: type %d", type);
1499 break; 1540 break;
1500 } 1541 }
@@ -1559,11 +1600,12 @@ do_fake_authloop(char *user)
1559 packet_send(); 1600 packet_send();
1560 packet_write_wait(); 1601 packet_write_wait();
1561 1602
1562 /* Keep reading packets, and always respond with a failure. This 1603 /*
1563 is to avoid disclosing whether such a user really exists. */ 1604 * Keep reading packets, and always respond with a failure. This is
1605 * to avoid disclosing whether such a user really exists.
1606 */
1564 for (attempt = 1;; attempt++) { 1607 for (attempt = 1;; attempt++) {
1565 /* Read a packet. This will not return if the client 1608 /* Read a packet. This will not return if the client disconnects. */
1566 disconnects. */
1567 int plen; 1609 int plen;
1568 int type = packet_read(&plen); 1610 int type = packet_read(&plen);
1569#ifdef SKEY 1611#ifdef SKEY
@@ -1583,8 +1625,10 @@ do_fake_authloop(char *user)
1583 if (attempt > AUTH_FAIL_MAX) 1625 if (attempt > AUTH_FAIL_MAX)
1584 packet_disconnect(AUTH_FAIL_MSG, user); 1626 packet_disconnect(AUTH_FAIL_MSG, user);
1585 1627
1586 /* Send failure. This should be indistinguishable from a 1628 /*
1587 failed authentication. */ 1629 * Send failure. This should be indistinguishable from a
1630 * failed authentication.
1631 */
1588 packet_start(SSH_SMSG_FAILURE); 1632 packet_start(SSH_SMSG_FAILURE);
1589 packet_send(); 1633 packet_send();
1590 packet_write_wait(); 1634 packet_write_wait();
@@ -1630,19 +1674,25 @@ do_authenticated(struct passwd * pw)
1630 mode_t tty_mode; 1674 mode_t tty_mode;
1631 int n_bytes; 1675 int n_bytes;
1632 1676
1633 /* Cancel the alarm we set to limit the time taken for 1677 /*
1634 authentication. */ 1678 * Cancel the alarm we set to limit the time taken for
1679 * authentication.
1680 */
1635 alarm(0); 1681 alarm(0);
1636 1682
1637 /* Inform the channel mechanism that we are the server side and 1683 /*
1638 that the client may request to connect to any port at all. 1684 * Inform the channel mechanism that we are the server side and that
1639 (The user could do it anyway, and we wouldn\'t know what is 1685 * the client may request to connect to any port at all. (The user
1640 permitted except by the client telling us, so we can equally 1686 * could do it anyway, and we wouldn\'t know what is permitted except
1641 well trust the client not to request anything bogus.) */ 1687 * by the client telling us, so we can equally well trust the client
1688 * not to request anything bogus.)
1689 */
1642 channel_permit_all_opens(); 1690 channel_permit_all_opens();
1643 1691
1644 /* We stay in this loop until the client requests to execute a 1692 /*
1645 shell or a command. */ 1693 * We stay in this loop until the client requests to execute a shell
1694 * or a command.
1695 */
1646 while (1) { 1696 while (1) {
1647 int plen, dlen; 1697 int plen, dlen;
1648 1698
@@ -1826,8 +1876,10 @@ do_authenticated(struct passwd * pw)
1826 return; 1876 return;
1827 1877
1828 default: 1878 default:
1829 /* Any unknown messages in this phase are ignored, 1879 /*
1830 and a failure message is returned. */ 1880 * Any unknown messages in this phase are ignored,
1881 * and a failure message is returned.
1882 */
1831 log("Unknown packet type received after authentication: %d", type); 1883 log("Unknown packet type received after authentication: %d", type);
1832 goto fail; 1884 goto fail;
1833 } 1885 }
@@ -1852,8 +1904,10 @@ fail:
1852 continue; 1904 continue;
1853 1905
1854do_forced_command: 1906do_forced_command:
1855 /* There is a forced command specified for this login. 1907 /*
1856 Execute it. */ 1908 * There is a forced command specified for this login.
1909 * Execute it.
1910 */
1857 debug("Executing forced command: %.900s", forced_command); 1911 debug("Executing forced command: %.900s", forced_command);
1858 if (have_pty) 1912 if (have_pty)
1859 do_exec_pty(forced_command, ptyfd, ttyfd, ttyname, pw, term, display, proto, data); 1913 do_exec_pty(forced_command, ptyfd, ttyfd, ttyname, pw, term, display, proto, data);
@@ -1897,14 +1951,18 @@ do_exec_no_pty(const char *command, struct passwd * pw,
1897 /* Child. Reinitialize the log since the pid has changed. */ 1951 /* Child. Reinitialize the log since the pid has changed. */
1898 log_init(av0, options.log_level, options.log_facility, log_stderr); 1952 log_init(av0, options.log_level, options.log_facility, log_stderr);
1899 1953
1900 /* Create a new session and process group since the 4.4BSD 1954 /*
1901 setlogin() affects the entire process group. */ 1955 * Create a new session and process group since the 4.4BSD
1956 * setlogin() affects the entire process group.
1957 */
1902 if (setsid() < 0) 1958 if (setsid() < 0)
1903 error("setsid failed: %.100s", strerror(errno)); 1959 error("setsid failed: %.100s", strerror(errno));
1904 1960
1905#ifdef USE_PIPES 1961#ifdef USE_PIPES
1906 /* Redirect stdin. We close the parent side of the socket 1962 /*
1907 pair, and make the child side the standard input. */ 1963 * Redirect stdin. We close the parent side of the socket
1964 * pair, and make the child side the standard input.
1965 */
1908 close(pin[1]); 1966 close(pin[1]);
1909 if (dup2(pin[0], 0) < 0) 1967 if (dup2(pin[0], 0) < 0)
1910 perror("dup2 stdin"); 1968 perror("dup2 stdin");
@@ -1922,9 +1980,11 @@ do_exec_no_pty(const char *command, struct passwd * pw,
1922 perror("dup2 stderr"); 1980 perror("dup2 stderr");
1923 close(perr[1]); 1981 close(perr[1]);
1924#else /* USE_PIPES */ 1982#else /* USE_PIPES */
1925 /* Redirect stdin, stdout, and stderr. Stdin and stdout 1983 /*
1926 will use the same socket, as some programs 1984 * Redirect stdin, stdout, and stderr. Stdin and stdout will
1927 (particularly rdist) seem to depend on it. */ 1985 * use the same socket, as some programs (particularly rdist)
1986 * seem to depend on it.
1987 */
1928 close(inout[1]); 1988 close(inout[1]);
1929 close(err[1]); 1989 close(err[1]);
1930 if (dup2(inout[0], 0) < 0) /* stdin */ 1990 if (dup2(inout[0], 0) < 0) /* stdin */
@@ -1955,8 +2015,10 @@ do_exec_no_pty(const char *command, struct passwd * pw,
1955 close(inout[0]); 2015 close(inout[0]);
1956 close(err[0]); 2016 close(err[0]);
1957 2017
1958 /* Enter the interactive session. Note: server_loop must be able 2018 /*
1959 to handle the case that fdin and fdout are the same. */ 2019 * Enter the interactive session. Note: server_loop must be able to
2020 * handle the case that fdin and fdout are the same.
2021 */
1960 server_loop(pid, inout[1], inout[1], err[1]); 2022 server_loop(pid, inout[1], inout[1], err[1]);
1961 /* server_loop has closed inout[1] and err[1]. */ 2023 /* server_loop has closed inout[1] and err[1]. */
1962#endif /* USE_PIPES */ 2024#endif /* USE_PIPES */
@@ -2012,8 +2074,10 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
2012 /* Get remote host name. */ 2074 /* Get remote host name. */
2013 hostname = get_canonical_hostname(); 2075 hostname = get_canonical_hostname();
2014 2076
2015 /* Get the time when the user last logged in. Buf will be set to 2077 /*
2016 contain the hostname the last login was from. */ 2078 * Get the time when the user last logged in. Buf will be set to
2079 * contain the hostname the last login was from.
2080 */
2017 if (!options.use_login) { 2081 if (!options.use_login) {
2018 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, 2082 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
2019 buf, sizeof(buf)); 2083 buf, sizeof(buf));
@@ -2049,9 +2113,11 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
2049 /* Close the extra descriptor for the pseudo tty. */ 2113 /* Close the extra descriptor for the pseudo tty. */
2050 close(ttyfd); 2114 close(ttyfd);
2051 2115
2052 /* Get IP address of client. This is needed because we 2116 /*
2053 want to record where the user logged in from. If the 2117 * Get IP address of client. This is needed because we want
2054 connection is not a socket, let the ip address be 0.0.0.0. */ 2118 * to record where the user logged in from. If the
2119 * connection is not a socket, let the ip address be 0.0.0.0.
2120 */
2055 memset(&from, 0, sizeof(from)); 2121 memset(&from, 0, sizeof(from));
2056 if (packet_get_connection_in() == packet_get_connection_out()) { 2122 if (packet_get_connection_in() == packet_get_connection_out()) {
2057 fromlen = sizeof(from); 2123 fromlen = sizeof(from);
@@ -2075,12 +2141,14 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
2075 fprintf(stderr, pamconv_msg); 2141 fprintf(stderr, pamconv_msg);
2076#endif 2142#endif
2077 2143
2078 /* If the user has logged in before, display the time of 2144 /*
2079 last login. However, don't display anything extra if a 2145 * If the user has logged in before, display the time of last
2080 command has been specified (so that ssh can be used to 2146 * login. However, don't display anything extra if a command
2081 execute commands on a remote machine without users 2147 * has been specified (so that ssh can be used to execute
2082 knowing they are going to another machine). Login(1) 2148 * commands on a remote machine without users knowing they
2083 will do this for us as well, so check if login(1) is used */ 2149 * are going to another machine). Login(1) will do this for
2150 * us as well, so check if login(1) is used
2151 */
2084 if (command == NULL && last_login_time != 0 && !quiet_login && 2152 if (command == NULL && last_login_time != 0 && !quiet_login &&
2085 !options.use_login) { 2153 !options.use_login) {
2086 /* Convert the date to a string. */ 2154 /* Convert the date to a string. */
@@ -2095,10 +2163,12 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
2095 else 2163 else
2096 printf("Last login: %s from %s\r\n", time_string, buf); 2164 printf("Last login: %s from %s\r\n", time_string, buf);
2097 } 2165 }
2098 /* Print /etc/motd unless a command was specified or 2166 /*
2099 printing it was disabled in server options or login(1) 2167 * Print /etc/motd unless a command was specified or printing
2100 will be used. Note that some machines appear to print 2168 * it was disabled in server options or login(1) will be
2101 it in /etc/profile or similar. */ 2169 * used. Note that some machines appear to print it in
2170 * /etc/profile or similar.
2171 */
2102 if (command == NULL && options.print_motd && !quiet_login && 2172 if (command == NULL && options.print_motd && !quiet_login &&
2103 !options.use_login) { 2173 !options.use_login) {
2104 /* Print /etc/motd if it exists. */ 2174 /* Print /etc/motd if it exists. */
@@ -2118,15 +2188,19 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
2118 /* Parent. Close the slave side of the pseudo tty. */ 2188 /* Parent. Close the slave side of the pseudo tty. */
2119 close(ttyfd); 2189 close(ttyfd);
2120 2190
2121 /* Create another descriptor of the pty master side for use as the 2191 /*
2122 standard input. We could use the original descriptor, but this 2192 * Create another descriptor of the pty master side for use as the
2123 simplifies code in server_loop. The descriptor is bidirectional. */ 2193 * standard input. We could use the original descriptor, but this
2194 * simplifies code in server_loop. The descriptor is bidirectional.
2195 */
2124 fdout = dup(ptyfd); 2196 fdout = dup(ptyfd);
2125 if (fdout < 0) 2197 if (fdout < 0)
2126 packet_disconnect("dup failed: %.100s", strerror(errno)); 2198 packet_disconnect("dup failed: %.100s", strerror(errno));
2127 2199
2128 /* Add a cleanup function to clear the utmp entry and record logout 2200 /*
2129 time in case we call fatal() (e.g., the connection gets closed). */ 2201 * Add a cleanup function to clear the utmp entry and record logout
2202 * time in case we call fatal() (e.g., the connection gets closed).
2203 */
2130 cleanup_context.pid = pid; 2204 cleanup_context.pid = pid;
2131 cleanup_context.ttyname = ttyname; 2205 cleanup_context.ttyname = ttyname;
2132 fatal_add_cleanup(pty_cleanup_proc, (void *) &cleanup_context); 2206 fatal_add_cleanup(pty_cleanup_proc, (void *) &cleanup_context);
@@ -2144,9 +2218,11 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
2144 /* Release the pseudo-tty. */ 2218 /* Release the pseudo-tty. */
2145 pty_release(ttyname); 2219 pty_release(ttyname);
2146 2220
2147 /* Close the server side of the socket pairs. We must do this 2221 /*
2148 after the pty cleanup, so that another process doesn't get this 2222 * Close the server side of the socket pairs. We must do this after
2149 pty while we're still cleaning up. */ 2223 * the pty cleanup, so that another process doesn't get this pty
2224 * while we're still cleaning up.
2225 */
2150 close(ptyfd); 2226 close(ptyfd);
2151 close(fdout); 2227 close(fdout);
2152} 2228}
@@ -2162,19 +2238,21 @@ child_set_env(char ***envp, unsigned int *envsizep, const char *name,
2162 unsigned int i, namelen; 2238 unsigned int i, namelen;
2163 char **env; 2239 char **env;
2164 2240
2165 /* Find the slot where the value should be stored. If the 2241 /*
2166 variable already exists, we reuse the slot; otherwise we append 2242 * Find the slot where the value should be stored. If the variable
2167 a new slot at the end of the array, expanding if necessary. */ 2243 * already exists, we reuse the slot; otherwise we append a new slot
2244 * at the end of the array, expanding if necessary.
2245 */
2168 env = *envp; 2246 env = *envp;
2169 namelen = strlen(name); 2247 namelen = strlen(name);
2170 for (i = 0; env[i]; i++) 2248 for (i = 0; env[i]; i++)
2171 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') 2249 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
2172 break; 2250 break;
2173 if (env[i]) { 2251 if (env[i]) {
2174 /* Name already exists. Reuse the slot. */ 2252 /* Reuse the slot. */
2175 xfree(env[i]); 2253 xfree(env[i]);
2176 } else { 2254 } else {
2177 /* New variable. Expand the array if necessary. */ 2255 /* New variable. Expand if necessary. */
2178 if (i >= (*envsizep) - 1) { 2256 if (i >= (*envsizep) - 1) {
2179 (*envsizep) += 50; 2257 (*envsizep) += 50;
2180 env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); 2258 env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
@@ -2202,40 +2280,27 @@ read_environment_file(char ***env, unsigned int *envsize,
2202 char buf[4096]; 2280 char buf[4096];
2203 char *cp, *value; 2281 char *cp, *value;
2204 2282
2205 /* Open the environment file. */
2206 f = fopen(filename, "r"); 2283 f = fopen(filename, "r");
2207 if (!f) 2284 if (!f)
2208 return; 2285 return;
2209 2286
2210 /* Process each line. */
2211 while (fgets(buf, sizeof(buf), f)) { 2287 while (fgets(buf, sizeof(buf), f)) {
2212 /* Skip leading whitespace. */ 2288 for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
2213 for (cp = buf; *cp == ' ' || *cp == '\t'; cp++); 2289 ;
2214
2215 /* Ignore empty and comment lines. */
2216 if (!*cp || *cp == '#' || *cp == '\n') 2290 if (!*cp || *cp == '#' || *cp == '\n')
2217 continue; 2291 continue;
2218
2219 /* Remove newline. */
2220 if (strchr(cp, '\n')) 2292 if (strchr(cp, '\n'))
2221 *strchr(cp, '\n') = '\0'; 2293 *strchr(cp, '\n') = '\0';
2222
2223 /* Find the equals sign. Its lack indicates badly
2224 formatted line. */
2225 value = strchr(cp, '='); 2294 value = strchr(cp, '=');
2226 if (value == NULL) { 2295 if (value == NULL) {
2227 fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf); 2296 fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
2228 continue; 2297 continue;
2229 } 2298 }
2230 /* Replace the equals sign by nul, and advance value to 2299 /* Replace the equals sign by nul, and advance value to the value string. */
2231 the value string. */
2232 *value = '\0'; 2300 *value = '\0';
2233 value++; 2301 value++;
2234
2235 /* Set the value in environment. */
2236 child_set_env(env, envsize, cp, value); 2302 child_set_env(env, envsize, cp, value);
2237 } 2303 }
2238
2239 fclose(f); 2304 fclose(f);
2240} 2305}
2241 2306
@@ -2299,8 +2364,10 @@ do_child(const char *command, struct passwd * pw, const char *term,
2299 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) 2364 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
2300 fatal("Failed to set uids to %d.", (int) pw->pw_uid); 2365 fatal("Failed to set uids to %d.", (int) pw->pw_uid);
2301 } 2366 }
2302 /* Get the shell from the password data. An empty shell field is 2367 /*
2303 legal, and means /bin/sh. */ 2368 * Get the shell from the password data. An empty shell field is
2369 * legal, and means /bin/sh.
2370 */
2304 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; 2371 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
2305 2372
2306#ifdef AFS 2373#ifdef AFS
@@ -2315,8 +2382,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
2315 } 2382 }
2316#endif /* AFS */ 2383#endif /* AFS */
2317 2384
2318 /* Initialize the environment. In the first part we allocate 2385 /* Initialize the environment. */
2319 space for all environment variables. */
2320 envsize = 100; 2386 envsize = 100;
2321 env = xmalloc(envsize * sizeof(char *)); 2387 env = xmalloc(envsize * sizeof(char *));
2322 env[0] = NULL; 2388 env[0] = NULL;
@@ -2335,7 +2401,6 @@ do_child(const char *command, struct passwd * pw, const char *term,
2335 /* Normal systems set SHELL by default. */ 2401 /* Normal systems set SHELL by default. */
2336 child_set_env(&env, &envsize, "SHELL", shell); 2402 child_set_env(&env, &envsize, "SHELL", shell);
2337 } 2403 }
2338 /* Let it inherit timezone if we have one. */
2339 if (getenv("TZ")) 2404 if (getenv("TZ"))
2340 child_set_env(&env, &envsize, "TZ", getenv("TZ")); 2405 child_set_env(&env, &envsize, "TZ", getenv("TZ"));
2341 2406
@@ -2354,20 +2419,14 @@ do_child(const char *command, struct passwd * pw, const char *term,
2354 xfree(ce); 2419 xfree(ce);
2355 } 2420 }
2356 2421
2357 /* Set SSH_CLIENT. */
2358 snprintf(buf, sizeof buf, "%.50s %d %d", 2422 snprintf(buf, sizeof buf, "%.50s %d %d",
2359 get_remote_ipaddr(), get_remote_port(), options.port); 2423 get_remote_ipaddr(), get_remote_port(), options.port);
2360 child_set_env(&env, &envsize, "SSH_CLIENT", buf); 2424 child_set_env(&env, &envsize, "SSH_CLIENT", buf);
2361 2425
2362 /* Set SSH_TTY if we have a pty. */
2363 if (ttyname) 2426 if (ttyname)
2364 child_set_env(&env, &envsize, "SSH_TTY", ttyname); 2427 child_set_env(&env, &envsize, "SSH_TTY", ttyname);
2365
2366 /* Set TERM if we have a pty. */
2367 if (term) 2428 if (term)
2368 child_set_env(&env, &envsize, "TERM", term); 2429 child_set_env(&env, &envsize, "TERM", term);
2369
2370 /* Set DISPLAY if we have one. */
2371 if (display) 2430 if (display)
2372 child_set_env(&env, &envsize, "DISPLAY", display); 2431 child_set_env(&env, &envsize, "DISPLAY", display);
2373 2432
@@ -2400,52 +2459,57 @@ do_child(const char *command, struct passwd * pw, const char *term,
2400 } 2459 }
2401#endif /* HAVE_LIBPAM */ 2460#endif /* HAVE_LIBPAM */
2402 2461
2403 /* Set XAUTHORITY to always be a local file. */
2404 if (xauthfile) 2462 if (xauthfile)
2405 child_set_env(&env, &envsize, "XAUTHORITY", xauthfile); 2463 child_set_env(&env, &envsize, "XAUTHORITY", xauthfile);
2406 2464
2407 /* Set variable for forwarded authentication connection, if we
2408 have one. */
2409 if (auth_get_socket_name() != NULL) 2465 if (auth_get_socket_name() != NULL)
2410 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, 2466 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
2411 auth_get_socket_name()); 2467 auth_get_socket_name());
2412 2468
2413 /* Read $HOME/.ssh/environment. */ 2469 /* read $HOME/.ssh/environment. */
2414 if (!options.use_login) { 2470 if (!options.use_login) {
2415 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir); 2471 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir);
2416 read_environment_file(&env, &envsize, buf); 2472 read_environment_file(&env, &envsize, buf);
2417 } 2473 }
2418 /* If debugging, dump the environment to stderr. */
2419 if (debug_flag) { 2474 if (debug_flag) {
2475 /* dump the environment */
2420 fprintf(stderr, "Environment:\n"); 2476 fprintf(stderr, "Environment:\n");
2421 for (i = 0; env[i]; i++) 2477 for (i = 0; env[i]; i++)
2422 fprintf(stderr, " %.200s\n", env[i]); 2478 fprintf(stderr, " %.200s\n", env[i]);
2423 } 2479 }
2424 /* Close the connection descriptors; note that this is the child, 2480 /*
2425 and the server will still have the socket open, and it is 2481 * Close the connection descriptors; note that this is the child, and
2426 important that we do not shutdown it. Note that the 2482 * the server will still have the socket open, and it is important
2427 descriptors cannot be closed before building the environment, 2483 * that we do not shutdown it. Note that the descriptors cannot be
2428 as we call get_remote_ipaddr there. */ 2484 * closed before building the environment, as we call
2485 * get_remote_ipaddr there.
2486 */
2429 if (packet_get_connection_in() == packet_get_connection_out()) 2487 if (packet_get_connection_in() == packet_get_connection_out())
2430 close(packet_get_connection_in()); 2488 close(packet_get_connection_in());
2431 else { 2489 else {
2432 close(packet_get_connection_in()); 2490 close(packet_get_connection_in());
2433 close(packet_get_connection_out()); 2491 close(packet_get_connection_out());
2434 } 2492 }
2435 /* Close all descriptors related to channels. They will still 2493 /*
2436 remain open in the parent. */ 2494 * Close all descriptors related to channels. They will still remain
2495 * open in the parent.
2496 */
2497 /* XXX better use close-on-exec? -markus */
2437 channel_close_all(); 2498 channel_close_all();
2438 2499
2439 /* Close any extra file descriptors. Note that there may still be 2500 /*
2440 descriptors left by system functions. They will be closed 2501 * Close any extra file descriptors. Note that there may still be
2441 later. */ 2502 * descriptors left by system functions. They will be closed later.
2503 */
2442 endpwent(); 2504 endpwent();
2443 endhostent(); 2505 endhostent();
2444 2506
2445 /* Close any extra open file descriptors so that we don\'t have 2507 /*
2446 them hanging around in clients. Note that we want to do this 2508 * Close any extra open file descriptors so that we don\'t have them
2447 after initgroups, because at least on Solaris 2.3 it leaves 2509 * hanging around in clients. Note that we want to do this after
2448 file descriptors open. */ 2510 * initgroups, because at least on Solaris 2.3 it leaves file
2511 * descriptors open.
2512 */
2449 for (i = 3; i < 64; i++) 2513 for (i = 3; i < 64; i++)
2450 close(i); 2514 close(i);
2451 2515
@@ -2454,12 +2518,16 @@ do_child(const char *command, struct passwd * pw, const char *term,
2454 fprintf(stderr, "Could not chdir to home directory %s: %s\n", 2518 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
2455 pw->pw_dir, strerror(errno)); 2519 pw->pw_dir, strerror(errno));
2456 2520
2457 /* Must take new environment into use so that .ssh/rc, /etc/sshrc 2521 /*
2458 and xauth are run in the proper environment. */ 2522 * Must take new environment into use so that .ssh/rc, /etc/sshrc and
2523 * xauth are run in the proper environment.
2524 */
2459 environ = env; 2525 environ = env;
2460 2526
2461 /* Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found 2527 /*
2462 first in this order). */ 2528 * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
2529 * in this order).
2530 */
2463 if (!options.use_login) { 2531 if (!options.use_login) {
2464 if (stat(SSH_USER_RC, &st) >= 0) { 2532 if (stat(SSH_USER_RC, &st) >= 0) {
2465 if (debug_flag) 2533 if (debug_flag)
@@ -2486,8 +2554,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
2486 } 2554 }
2487#ifdef XAUTH_PATH 2555#ifdef XAUTH_PATH
2488 else { 2556 else {
2489 /* Add authority data to .Xauthority if 2557 /* Add authority data to .Xauthority if appropriate. */
2490 appropriate. */
2491 if (auth_proto != NULL && auth_data != NULL) { 2558 if (auth_proto != NULL && auth_data != NULL) {
2492 if (debug_flag) 2559 if (debug_flag)
2493 fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n", 2560 fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n",
@@ -2510,15 +2577,19 @@ do_child(const char *command, struct passwd * pw, const char *term,
2510 else 2577 else
2511 cp = shell; 2578 cp = shell;
2512 } 2579 }
2513 /* If we have no command, execute the shell. In this case, the 2580 /*
2514 shell name to be passed in argv[0] is preceded by '-' to 2581 * If we have no command, execute the shell. In this case, the shell
2515 indicate that this is a login shell. */ 2582 * name to be passed in argv[0] is preceded by '-' to indicate that
2583 * this is a login shell.
2584 */
2516 if (!command) { 2585 if (!command) {
2517 if (!options.use_login) { 2586 if (!options.use_login) {
2518 char buf[256]; 2587 char buf[256];
2519 2588
2520 /* Check for mail if we have a tty and it was 2589 /*
2521 enabled in server options. */ 2590 * Check for mail if we have a tty and it was enabled
2591 * in server options.
2592 */
2522 if (ttyname && options.check_mail) { 2593 if (ttyname && options.check_mail) {
2523 char *mailbox; 2594 char *mailbox;
2524 struct stat mailstat; 2595 struct stat mailstat;
@@ -2558,8 +2629,10 @@ do_child(const char *command, struct passwd * pw, const char *term,
2558 exit(1); 2629 exit(1);
2559 } 2630 }
2560 } 2631 }
2561 /* Execute the command using the user's shell. This uses the -c 2632 /*
2562 option to execute the command. */ 2633 * Execute the command using the user's shell. This uses the -c
2634 * option to execute the command.
2635 */
2563 argv[0] = (char *) cp; 2636 argv[0] = (char *) cp;
2564 argv[1] = "-c"; 2637 argv[1] = "-c";
2565 argv[2] = (char *) command; 2638 argv[2] = (char *) command;
diff --git a/tildexpand.c b/tildexpand.c
index 92422ee3f..8ee551f13 100644
--- a/tildexpand.c
+++ b/tildexpand.c
@@ -6,7 +6,7 @@
6 */ 6 */
7 7
8#include "includes.h" 8#include "includes.h"
9RCSID("$Id: tildexpand.c,v 1.2 1999/11/24 13:26:23 damien Exp $"); 9RCSID("$Id: tildexpand.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
10 10
11#include "xmalloc.h" 11#include "xmalloc.h"
12#include "ssh.h" 12#include "ssh.h"
@@ -38,7 +38,7 @@ tilde_expand_filename(const char *filename, uid_t my_uid)
38 else 38 else
39 userlen = strlen(filename); /* Nothing after username. */ 39 userlen = strlen(filename); /* Nothing after username. */
40 if (userlen == 0) 40 if (userlen == 0)
41 pw = getpwuid(my_uid); /* Own home directory. */ 41 pw = getpwuid(my_uid); /* Own home directory. */
42 else { 42 else {
43 /* Tilde refers to someone elses home directory. */ 43 /* Tilde refers to someone elses home directory. */
44 if (userlen > sizeof(user) - 1) 44 if (userlen > sizeof(user) - 1)
@@ -47,12 +47,12 @@ tilde_expand_filename(const char *filename, uid_t my_uid)
47 user[userlen] = 0; 47 user[userlen] = 0;
48 pw = getpwnam(user); 48 pw = getpwnam(user);
49 } 49 }
50 /* Check that we found the user. */
51 if (!pw) 50 if (!pw)
52 fatal("Unknown user %100s.", user); 51 fatal("Unknown user %100s.", user);
53 52
54 /* If referring to someones home directory, return it now. */ 53 /* If referring to someones home directory, return it now. */
55 if (!cp) { /* Only home directory specified */ 54 if (!cp) {
55 /* Only home directory specified */
56 return xstrdup(pw->pw_dir); 56 return xstrdup(pw->pw_dir);
57 } 57 }
58 /* Build a path combining the specified directory and path. */ 58 /* Build a path combining the specified directory and path. */
diff --git a/ttymodes.c b/ttymodes.c
index 6810ce26c..fffc6d5bf 100644
--- a/ttymodes.c
+++ b/ttymodes.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$Id: ttymodes.c,v 1.2 1999/11/24 13:26:23 damien Exp $"); 13RCSID("$Id: ttymodes.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
14 14
15#include "packet.h" 15#include "packet.h"
16#include "ssh.h" 16#include "ssh.h"
@@ -209,7 +209,6 @@ tty_make_modes(int fd)
209 struct termios tio; 209 struct termios tio;
210 int baud; 210 int baud;
211 211
212 /* Get the modes. */
213 if (tcgetattr(fd, &tio) < 0) { 212 if (tcgetattr(fd, &tio) < 0) {
214 packet_put_char(TTY_OP_END); 213 packet_put_char(TTY_OP_END);
215 log("tcgetattr: %.100s", strerror(errno)); 214 log("tcgetattr: %.100s", strerror(errno));
diff --git a/ttymodes.h b/ttymodes.h
index e9301f281..79726aa47 100644
--- a/ttymodes.h
+++ b/ttymodes.h
@@ -12,7 +12,7 @@
12 * 12 *
13 */ 13 */
14 14
15/* RCSID("$Id: ttymodes.h,v 1.2 1999/11/24 13:26:23 damien Exp $"); */ 15/* RCSID("$Id: ttymodes.h,v 1.3 1999/11/25 00:54:59 damien Exp $"); */
16 16
17/* The tty mode description is a stream of bytes. The stream consists of 17/* The tty mode description is a stream of bytes. The stream consists of
18 * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). 18 * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0).
@@ -29,112 +29,113 @@
29 29
30/* 30/*
31 * Some constants and prototypes are defined in packet.h; this file 31 * Some constants and prototypes are defined in packet.h; this file
32 * is only intended for including from ttymodes.h. 32 * is only intended for including from ttymodes.c.
33 */ 33 */
34 34
35 /* termios macro *//* sgtty macro */ 35/* termios macro */ /* sgtty macro */
36/* name, op */ 36/* name, op */
37TTYCHAR(VINTR, 1) SGTTYCHAR(tiotc.t_intrc, 1) 37TTYCHAR(VINTR, 1) SGTTYCHAR(tiotc.t_intrc, 1)
38TTYCHAR(VQUIT, 2) SGTTYCHAR(tiotc.t_quitc, 2) 38TTYCHAR(VQUIT, 2) SGTTYCHAR(tiotc.t_quitc, 2)
39TTYCHAR(VERASE, 3) SGTTYCHAR(tio.sg_erase, 3) 39TTYCHAR(VERASE, 3) SGTTYCHAR(tio.sg_erase, 3)
40#if defined(VKILL) 40#if defined(VKILL)
41TTYCHAR(VKILL, 4) SGTTYCHAR(tio.sg_kill, 4) 41TTYCHAR(VKILL, 4) SGTTYCHAR(tio.sg_kill, 4)
42#endif /* VKILL */ 42#endif /* VKILL */
43TTYCHAR(VEOF, 5) SGTTYCHAR(tiotc.t_eofc, 5) 43TTYCHAR(VEOF, 5) SGTTYCHAR(tiotc.t_eofc, 5)
44#if defined(VEOL) 44#if defined(VEOL)
45TTYCHAR(VEOL, 6) SGTTYCHAR(tiotc.t_brkc, 6) 45TTYCHAR(VEOL, 6) SGTTYCHAR(tiotc.t_brkc, 6)
46#endif /* VEOL */ 46#endif /* VEOL */
47#ifdef VEOL2 /* n/a */ 47#ifdef VEOL2 /* n/a */
48TTYCHAR(VEOL2, 7) 48TTYCHAR(VEOL2, 7)
49#endif /* VEOL2 */ 49#endif /* VEOL2 */
50TTYCHAR(VSTART, 8) SGTTYCHAR(tiotc.t_startc, 8) 50TTYCHAR(VSTART, 8) SGTTYCHAR(tiotc.t_startc, 8)
51TTYCHAR(VSTOP, 9) SGTTYCHAR(tiotc.t_stopc, 9) 51TTYCHAR(VSTOP, 9) SGTTYCHAR(tiotc.t_stopc, 9)
52#if defined(VSUSP) 52#if defined(VSUSP)
53TTYCHAR(VSUSP, 10) SGTTYCHAR(tioltc.t_suspc, 10) 53TTYCHAR(VSUSP, 10) SGTTYCHAR(tioltc.t_suspc, 10)
54#endif /* VSUSP */ 54#endif /* VSUSP */
55#if defined(VDSUSP) 55#if defined(VDSUSP)
56TTYCHAR(VDSUSP, 11) SGTTYCHAR(tioltc.t_dsuspc, 11) 56TTYCHAR(VDSUSP, 11) SGTTYCHAR(tioltc.t_dsuspc, 11)
57#endif /* VDSUSP */ 57#endif /* VDSUSP */
58#if defined(VREPRINT) 58#if defined(VREPRINT)
59TTYCHAR(VREPRINT, 12) SGTTYCHAR(tioltc.t_rprntc, 12) 59TTYCHAR(VREPRINT, 12) SGTTYCHAR(tioltc.t_rprntc, 12)
60#endif /* VREPRINT */ 60#endif /* VREPRINT */
61#if defined(VWERASE) 61#if defined(VWERASE)
62TTYCHAR(VWERASE, 13) SGTTYCHAR(tioltc.t_werasc, 13) 62TTYCHAR(VWERASE, 13) SGTTYCHAR(tioltc.t_werasc, 13)
63#endif /* VWERASE */ 63#endif /* VWERASE */
64#if defined(VLNEXT) 64#if defined(VLNEXT)
65TTYCHAR(VLNEXT, 14) SGTTYCHAR(tioltc.t_lnextc, 14) 65TTYCHAR(VLNEXT, 14) SGTTYCHAR(tioltc.t_lnextc, 14)
66#endif /* VLNEXT */ 66#endif /* VLNEXT */
67#if defined(VFLUSH) 67#if defined(VFLUSH)
68TTYCHAR(VFLUSH, 15) SGTTYCHAR(tioltc.t_flushc, 15) 68TTYCHAR(VFLUSH, 15) SGTTYCHAR(tioltc.t_flushc, 15)
69#endif /* VFLUSH */ 69#endif /* VFLUSH */
70#ifdef VSWTCH 70#ifdef VSWTCH
71TTYCHAR(VSWTCH, 16) /* n/a */ 71TTYCHAR(VSWTCH, 16) /* n/a */
72#endif /* VSWTCH */ 72#endif /* VSWTCH */
73#if defined(VSTATUS) 73#if defined(VSTATUS)
74TTYCHAR(VSTATUS, 17) SGTTYCHAR(tiots.tc_statusc, 17) 74TTYCHAR(VSTATUS, 17) SGTTYCHAR(tiots.tc_statusc, 17)
75#endif /* VSTATUS */ 75#endif /* VSTATUS */
76#ifdef VDISCARD 76#ifdef VDISCARD
77TTYCHAR(VDISCARD, 18) /* n/a */ 77TTYCHAR(VDISCARD, 18) /* n/a */
78#endif /* VDISCARD */ 78#endif /* VDISCARD */
79 79
80/* name, field, op */ 80/* name, field, op */
81TTYMODE(IGNPAR, c_iflag, 30) /* n/a */ 81TTYMODE(IGNPAR, c_iflag, 30) /* n/a */
82TTYMODE(PARMRK, c_iflag, 31) /* n/a */ 82TTYMODE(PARMRK, c_iflag, 31) /* n/a */
83TTYMODE(INPCK, c_iflag, 32) SGTTYMODEN(ANYP, tio.sg_flags, 32) 83TTYMODE(INPCK, c_iflag, 32) SGTTYMODEN(ANYP, tio.sg_flags, 32)
84TTYMODE(ISTRIP, c_iflag, 33) SGTTYMODEN(LPASS8, tiolm, 33) 84TTYMODE(ISTRIP, c_iflag, 33) SGTTYMODEN(LPASS8, tiolm, 33)
85TTYMODE(INLCR, c_iflag, 34) /* n/a */ 85TTYMODE(INLCR, c_iflag, 34) /* n/a */
86TTYMODE(IGNCR, c_iflag, 35) /* n/a */ 86TTYMODE(IGNCR, c_iflag, 35) /* n/a */
87TTYMODE(ICRNL, c_iflag, 36) SGTTYMODE(CRMOD, tio.sg_flags, 36) 87TTYMODE(ICRNL, c_iflag, 36) SGTTYMODE(CRMOD, tio.sg_flags, 36)
88#if defined(IUCLC) 88#if defined(IUCLC)
89TTYMODE(IUCLC, c_iflag, 37) SGTTYMODE(LCASE, tio.sg_flags, 37) 89TTYMODE(IUCLC, c_iflag, 37) SGTTYMODE(LCASE, tio.sg_flags, 37)
90#endif 90#endif
91TTYMODE(IXON, c_iflag, 38) /* n/a */ 91TTYMODE(IXON, c_iflag, 38) /* n/a */
92TTYMODE(IXANY, c_iflag, 39) SGTTYMODEN(LDECCTQ, tiolm, 39) 92TTYMODE(IXANY, c_iflag, 39) SGTTYMODEN(LDECCTQ, tiolm, 39)
93TTYMODE(IXOFF, c_iflag, 40) SGTTYMODE(TANDEM, tio.sg_flags, 40) 93TTYMODE(IXOFF, c_iflag, 40) SGTTYMODE(TANDEM, tio.sg_flags, 40)
94#ifdef IMAXBEL 94#ifdef IMAXBEL
95TTYMODE(IMAXBEL, c_iflag, 41) /* n/a */ 95TTYMODE(IMAXBEL,c_iflag, 41) /* n/a */
96#endif /* IMAXBEL */ 96#endif /* IMAXBEL */
97 97
98TTYMODE(ISIG, c_lflag, 50) /* n/a */ 98TTYMODE(ISIG, c_lflag, 50) /* n/a */
99TTYMODE(ICANON, c_lflag, 51) SGTTYMODEN(CBREAK, tio.sg_flags, 51) 99TTYMODE(ICANON, c_lflag, 51) SGTTYMODEN(CBREAK, tio.sg_flags, 51)
100#ifdef XCASE 100#ifdef XCASE
101TTYMODE(XCASE, c_lflag, 52) /* n/a */ 101TTYMODE(XCASE, c_lflag, 52) /* n/a */
102#endif 102#endif
103TTYMODE(ECHO, c_lflag, 53) SGTTYMODE(ECHO, tio.sg_flags, 53) 103TTYMODE(ECHO, c_lflag, 53) SGTTYMODE(ECHO, tio.sg_flags, 53)
104TTYMODE(ECHOE, c_lflag, 54) SGTTYMODE(LCRTERA, tiolm, 54) 104TTYMODE(ECHOE, c_lflag, 54) SGTTYMODE(LCRTERA, tiolm, 54)
105TTYMODE(ECHOK, c_lflag, 55) SGTTYMODE(LCRTKIL, tiolm, 55) 105TTYMODE(ECHOK, c_lflag, 55) SGTTYMODE(LCRTKIL, tiolm, 55)
106TTYMODE(ECHONL, c_lflag, 56) /* n/a */ 106TTYMODE(ECHONL, c_lflag, 56) /* n/a */
107TTYMODE(NOFLSH, c_lflag, 57) SGTTYMODE(LNOFLSH, tiolm, 57) 107TTYMODE(NOFLSH, c_lflag, 57) SGTTYMODE(LNOFLSH, tiolm, 57)
108TTYMODE(TOSTOP, c_lflag, 58) SGTTYMODE(LTOSTOP, tiolm, 58) 108TTYMODE(TOSTOP, c_lflag, 58) SGTTYMODE(LTOSTOP, tiolm, 58)
109#ifdef IEXTEN 109#ifdef IEXTEN
110TTYMODE(IEXTEN, c_lflag, 59) /* n/a */ 110TTYMODE(IEXTEN, c_lflag, 59) /* n/a */
111#endif /* IEXTEN */ 111#endif /* IEXTEN */
112#if defined(ECHOCTL) 112#if defined(ECHOCTL)
113TTYMODE(ECHOCTL, c_lflag, 60) SGTTYMODE(LCTLECH, tiolm, 60) 113TTYMODE(ECHOCTL,c_lflag, 60) SGTTYMODE(LCTLECH, tiolm, 60)
114#endif /* ECHOCTL */ 114#endif /* ECHOCTL */
115#ifdef ECHOKE 115#ifdef ECHOKE
116TTYMODE(ECHOKE, c_lflag, 61) /* n/a */ 116TTYMODE(ECHOKE, c_lflag, 61) /* n/a */
117#endif /* ECHOKE */ 117#endif /* ECHOKE */
118#if defined(PENDIN) 118#if defined(PENDIN)
119TTYMODE(PENDIN, c_lflag, 62) SGTTYMODE(LPENDIN, tiolm, 62) 119TTYMODE(PENDIN, c_lflag, 62) SGTTYMODE(LPENDIN, tiolm, 62)
120#endif /* PENDIN */ 120#endif /* PENDIN */
121 121
122TTYMODE(OPOST, c_oflag, 70) /* n/a */ 122TTYMODE(OPOST, c_oflag, 70) /* n/a */
123#if defined(OLCUC) 123#if defined(OLCUC)
124TTYMODE(OLCUC, c_oflag, 71) SGTTYMODE(LCASE, tio.sg_flags, 71) 124TTYMODE(OLCUC, c_oflag, 71) SGTTYMODE(LCASE, tio.sg_flags, 71)
125#endif 125#endif
126TTYMODE(ONLCR, c_oflag, 72) SGTTYMODE(CRMOD, tio.sg_flags, 72) 126TTYMODE(ONLCR, c_oflag, 72) SGTTYMODE(CRMOD, tio.sg_flags, 72)
127#ifdef OCRNL 127#ifdef OCRNL
128TTYMODE(OCRNL, c_oflag, 73) /* n/a */ 128TTYMODE(OCRNL, c_oflag, 73) /* n/a */
129#endif 129#endif
130#ifdef ONOCR 130#ifdef ONOCR
131TTYMODE(ONOCR, c_oflag, 74) /* n/a */ 131TTYMODE(ONOCR, c_oflag, 74) /* n/a */
132#endif 132#endif
133#ifdef ONLRET 133#ifdef ONLRET
134TTYMODE(ONLRET, c_oflag, 75) /* n/a */ 134TTYMODE(ONLRET, c_oflag, 75) /* n/a */
135#endif 135#endif
136 136
137TTYMODE(CS7, c_cflag, 90) /* n/a */ 137TTYMODE(CS7, c_cflag, 90) /* n/a */
138TTYMODE(CS8, c_cflag, 91) SGTTYMODE(LPASS8, tiolm, 91) 138TTYMODE(CS8, c_cflag, 91) SGTTYMODE(LPASS8, tiolm, 91)
139TTYMODE(PARENB, c_cflag, 92) /* n/a */ 139TTYMODE(PARENB, c_cflag, 92) /* n/a */
140TTYMODE(PARODD, c_cflag, 93) SGTTYMODE(ODDP, tio.sg_flags, 93) 140TTYMODE(PARODD, c_cflag, 93) SGTTYMODE(ODDP, tio.sg_flags, 93)
141
diff --git a/uidswap.c b/uidswap.c
index 72c2cc6ef..d81fde9d2 100644
--- a/uidswap.c
+++ b/uidswap.c
@@ -7,7 +7,7 @@
7 */ 7 */
8 8
9#include "includes.h" 9#include "includes.h"
10RCSID("$Id: uidswap.c,v 1.2 1999/11/24 13:26:23 damien Exp $"); 10RCSID("$Id: uidswap.c,v 1.3 1999/11/25 00:55:00 damien Exp $");
11 11
12#include "ssh.h" 12#include "ssh.h"
13#include "uidswap.h" 13#include "uidswap.h"
@@ -66,10 +66,11 @@ restore_uid()
66 if (seteuid(saved_euid) < 0) 66 if (seteuid(saved_euid) < 0)
67 debug("seteuid %d: %.100s", (int) saved_euid, strerror(errno)); 67 debug("seteuid %d: %.100s", (int) saved_euid, strerror(errno));
68#else /* SAVED_IDS_WORK_WITH_SETEUID */ 68#else /* SAVED_IDS_WORK_WITH_SETEUID */
69 /* We are unable to restore the real uid to its unprivileged 69 /*
70 value. */ 70 * We are unable to restore the real uid to its unprivileged value.
71 /* Propagate the real uid (usually more privileged) to effective 71 * Propagate the real uid (usually more privileged) to effective uid
72 uid as well. */ 72 * as well.
73 */
73 setuid(getuid()); 74 setuid(getuid());
74#endif /* SAVED_IDS_WORK_WITH_SETEUID */ 75#endif /* SAVED_IDS_WORK_WITH_SETEUID */
75} 76}