diff options
-rw-r--r-- | ChangeLog | 39 | ||||
-rw-r--r-- | auth-rsa.c | 6 | ||||
-rw-r--r-- | auth.h | 2 | ||||
-rw-r--r-- | auth2.c | 4 | ||||
-rw-r--r-- | authfd.c | 142 | ||||
-rw-r--r-- | cipher.c | 9 | ||||
-rw-r--r-- | compat.c | 8 | ||||
-rw-r--r-- | kex.c | 14 | ||||
-rw-r--r-- | readconf.c | 152 | ||||
-rw-r--r-- | scp.1 | 3 | ||||
-rw-r--r-- | servconf.c | 137 | ||||
-rw-r--r-- | servconf.h | 5 | ||||
-rw-r--r-- | serverloop.c | 2 | ||||
-rw-r--r-- | session.c | 15 | ||||
-rw-r--r-- | ssh-agent.1 | 3 | ||||
-rw-r--r-- | ssh-keygen.1 | 3 | ||||
-rw-r--r-- | ssh-keygen.c | 6 | ||||
-rw-r--r-- | sshd.8 | 11 | ||||
-rw-r--r-- | sshd.c | 167 |
19 files changed, 389 insertions, 339 deletions
@@ -10,6 +10,45 @@ | |||
10 | to compile on more platforms (incl NeXT). | 10 | to compile on more platforms (incl NeXT). |
11 | - (djm) Added bsd-inet_aton and configure support for NeXT | 11 | - (djm) Added bsd-inet_aton and configure support for NeXT |
12 | - (djm) Misc NeXT fixes from Ben Lindstrom <mouring@pconline.com> | 12 | - (djm) Misc NeXT fixes from Ben Lindstrom <mouring@pconline.com> |
13 | - (djm) OpenBSD CVS updates: | ||
14 | - markus@cvs.openbsd.org 2000/06/26 03:22:29 | ||
15 | [authfd.c] | ||
16 | cleanup, less cut&paste | ||
17 | - markus@cvs.openbsd.org 2000/06/26 15:59:19 | ||
18 | [servconf.c servconf.h session.c sshd.8 sshd.c] | ||
19 | MaxStartups: limit number of unauthenticated connections, work by | ||
20 | theo and me | ||
21 | - deraadt@cvs.openbsd.org 2000/07/05 14:18:07 | ||
22 | [session.c] | ||
23 | use no_x11_forwarding_flag correctly; provos ok | ||
24 | - provos@cvs.openbsd.org 2000/07/05 15:35:57 | ||
25 | [sshd.c] | ||
26 | typo | ||
27 | - aaron@cvs.openbsd.org 2000/07/05 22:06:58 | ||
28 | [scp.1 ssh-agent.1 ssh-keygen.1 sshd.8] | ||
29 | Insert more missing .El directives. Our troff really should identify | ||
30 | these and spit out a warning. | ||
31 | - todd@cvs.openbsd.org 2000/07/06 21:55:04 | ||
32 | [auth-rsa.c auth2.c ssh-keygen.c] | ||
33 | clean code is good code | ||
34 | - deraadt@cvs.openbsd.org 2000/07/07 02:14:29 | ||
35 | [serverloop.c] | ||
36 | sense of port forwarding flag test was backwards | ||
37 | - provos@cvs.openbsd.org 2000/07/08 17:17:31 | ||
38 | [compat.c readconf.c] | ||
39 | replace strtok with strsep; from David Young <dyoung@onthejob.net> | ||
40 | - deraadt@cvs.openbsd.org 2000/07/08 19:21:15 | ||
41 | [auth.h] | ||
42 | KNF | ||
43 | - ho@cvs.openbsd.org 2000/07/08 19:27:33 | ||
44 | [compat.c readconf.c] | ||
45 | Better conditions for strsep() ending. | ||
46 | - ho@cvs.openbsd.org 2000/07/10 10:27:05 | ||
47 | [readconf.c] | ||
48 | Get the correct message on errors. (niels@ ok) | ||
49 | - ho@cvs.openbsd.org 2000/07/10 10:30:25 | ||
50 | [cipher.c kex.c servconf.c] | ||
51 | strtok() --> strsep(). (niels@ ok) | ||
13 | 52 | ||
14 | 20000709 | 53 | 20000709 |
15 | - (djm) Only enable PAM_TTY kludge for Linux. Problem report from | 54 | - (djm) Only enable PAM_TTY kludge for Linux. Problem report from |
diff --git a/auth-rsa.c b/auth-rsa.c index 1a246f7f2..65f9bf757 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" |
19 | RCSID("$OpenBSD: auth-rsa.c,v 1.26 2000/06/20 01:39:38 markus Exp $"); | 19 | RCSID("$OpenBSD: auth-rsa.c,v 1.27 2000/07/07 03:55:03 todd Exp $"); |
20 | 20 | ||
21 | #include "rsa.h" | 21 | #include "rsa.h" |
22 | #include "packet.h" | 22 | #include "packet.h" |
@@ -179,8 +179,8 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) | |||
179 | } | 179 | } |
180 | if (fail) { | 180 | if (fail) { |
181 | fclose(f); | 181 | fclose(f); |
182 | log(buf); | 182 | log("%s",buf); |
183 | packet_send_debug(buf); | 183 | packet_send_debug("%s",buf); |
184 | restore_uid(); | 184 | restore_uid(); |
185 | return 0; | 185 | return 0; |
186 | } | 186 | } |
@@ -7,7 +7,7 @@ void do_authentication2(void); | |||
7 | struct passwd * | 7 | struct passwd * |
8 | auth_get_user(void); | 8 | auth_get_user(void); |
9 | 9 | ||
10 | int allowed_user(struct passwd * pw);; | 10 | int allowed_user(struct passwd * pw); |
11 | 11 | ||
12 | #define AUTH_FAIL_MAX 6 | 12 | #define AUTH_FAIL_MAX 6 |
13 | #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) | 13 | #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) |
@@ -27,7 +27,7 @@ | |||
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | */ | 28 | */ |
29 | #include "includes.h" | 29 | #include "includes.h" |
30 | RCSID("$OpenBSD: auth2.c,v 1.11 2000/06/19 00:50:11 markus Exp $"); | 30 | RCSID("$OpenBSD: auth2.c,v 1.12 2000/07/07 03:55:03 todd Exp $"); |
31 | 31 | ||
32 | #include <openssl/dsa.h> | 32 | #include <openssl/dsa.h> |
33 | #include <openssl/rsa.h> | 33 | #include <openssl/rsa.h> |
@@ -489,8 +489,8 @@ user_dsa_key_allowed(struct passwd *pw, Key *key) | |||
489 | } | 489 | } |
490 | } | 490 | } |
491 | if (fail) { | 491 | if (fail) { |
492 | log(buf); | ||
493 | fclose(f); | 492 | fclose(f); |
493 | log("%s",buf); | ||
494 | restore_uid(); | 494 | restore_uid(); |
495 | return 0; | 495 | return 0; |
496 | } | 496 | } |
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$OpenBSD: authfd.c,v 1.20 2000/06/20 01:39:38 markus Exp $"); | 17 | RCSID("$OpenBSD: authfd.c,v 1.21 2000/06/26 09:22:29 markus Exp $"); |
18 | 18 | ||
19 | #include "ssh.h" | 19 | #include "ssh.h" |
20 | #include "rsa.h" | 20 | #include "rsa.h" |
@@ -26,6 +26,9 @@ RCSID("$OpenBSD: authfd.c,v 1.20 2000/06/20 01:39:38 markus Exp $"); | |||
26 | 26 | ||
27 | #include <openssl/rsa.h> | 27 | #include <openssl/rsa.h> |
28 | 28 | ||
29 | /* helper */ | ||
30 | int ssh_agent_get_reply(AuthenticationConnection *auth); | ||
31 | |||
29 | /* Returns the number of the authentication fd, or -1 if there is none. */ | 32 | /* Returns the number of the authentication fd, or -1 if there is none. */ |
30 | 33 | ||
31 | int | 34 | int |
@@ -344,7 +347,7 @@ ssh_add_identity(AuthenticationConnection *auth, | |||
344 | { | 347 | { |
345 | Buffer buffer; | 348 | Buffer buffer; |
346 | unsigned char buf[8192]; | 349 | unsigned char buf[8192]; |
347 | int len, l, type; | 350 | int len; |
348 | 351 | ||
349 | /* Format a message to the agent. */ | 352 | /* Format a message to the agent. */ |
350 | buffer_init(&buffer); | 353 | buffer_init(&buffer); |
@@ -368,57 +371,11 @@ ssh_add_identity(AuthenticationConnection *auth, | |||
368 | atomicio(write, auth->fd, buffer_ptr(&buffer), | 371 | atomicio(write, auth->fd, buffer_ptr(&buffer), |
369 | buffer_len(&buffer)) != buffer_len(&buffer)) { | 372 | buffer_len(&buffer)) != buffer_len(&buffer)) { |
370 | error("Error writing to authentication socket."); | 373 | error("Error writing to authentication socket."); |
371 | error_cleanup: | ||
372 | buffer_free(&buffer); | 374 | buffer_free(&buffer); |
373 | return 0; | 375 | return 0; |
374 | } | 376 | } |
375 | /* Wait for response from the agent. First read the length of the | 377 | buffer_free(&buffer); |
376 | response packet. */ | 378 | return ssh_agent_get_reply(auth); |
377 | len = 4; | ||
378 | while (len > 0) { | ||
379 | l = read(auth->fd, buf + 4 - len, len); | ||
380 | if (l <= 0) { | ||
381 | error("Error reading response length from authentication socket."); | ||
382 | goto error_cleanup; | ||
383 | } | ||
384 | len -= l; | ||
385 | } | ||
386 | |||
387 | /* Extract the length, and check it for sanity. */ | ||
388 | len = GET_32BIT(buf); | ||
389 | if (len > 256 * 1024) | ||
390 | fatal("Add identity response too long: %d", len); | ||
391 | |||
392 | /* Read the rest of the response in tothe buffer. */ | ||
393 | buffer_clear(&buffer); | ||
394 | while (len > 0) { | ||
395 | l = len; | ||
396 | if (l > sizeof(buf)) | ||
397 | l = sizeof(buf); | ||
398 | l = read(auth->fd, buf, l); | ||
399 | if (l <= 0) { | ||
400 | error("Error reading response from authentication socket."); | ||
401 | goto error_cleanup; | ||
402 | } | ||
403 | buffer_append(&buffer, (char *) buf, l); | ||
404 | len -= l; | ||
405 | } | ||
406 | |||
407 | /* Get the type of the packet. */ | ||
408 | type = buffer_get_char(&buffer); | ||
409 | switch (type) { | ||
410 | case SSH_AGENT_FAILURE: | ||
411 | buffer_free(&buffer); | ||
412 | return 0; | ||
413 | case SSH_AGENT_SUCCESS: | ||
414 | buffer_free(&buffer); | ||
415 | return 1; | ||
416 | default: | ||
417 | fatal("Bad response to add identity from authentication agent: %d", | ||
418 | type); | ||
419 | } | ||
420 | /* NOTREACHED */ | ||
421 | return 0; | ||
422 | } | 379 | } |
423 | 380 | ||
424 | /* | 381 | /* |
@@ -430,8 +387,8 @@ int | |||
430 | ssh_remove_identity(AuthenticationConnection *auth, RSA *key) | 387 | ssh_remove_identity(AuthenticationConnection *auth, RSA *key) |
431 | { | 388 | { |
432 | Buffer buffer; | 389 | Buffer buffer; |
433 | unsigned char buf[8192]; | 390 | unsigned char buf[5]; |
434 | int len, l, type; | 391 | int len; |
435 | 392 | ||
436 | /* Format a message to the agent. */ | 393 | /* Format a message to the agent. */ |
437 | buffer_init(&buffer); | 394 | buffer_init(&buffer); |
@@ -449,59 +406,11 @@ ssh_remove_identity(AuthenticationConnection *auth, RSA *key) | |||
449 | atomicio(write, auth->fd, buffer_ptr(&buffer), | 406 | atomicio(write, auth->fd, buffer_ptr(&buffer), |
450 | buffer_len(&buffer)) != buffer_len(&buffer)) { | 407 | buffer_len(&buffer)) != buffer_len(&buffer)) { |
451 | error("Error writing to authentication socket."); | 408 | error("Error writing to authentication socket."); |
452 | error_cleanup: | ||
453 | buffer_free(&buffer); | 409 | buffer_free(&buffer); |
454 | return 0; | 410 | return 0; |
455 | } | 411 | } |
456 | /* | 412 | buffer_free(&buffer); |
457 | * Wait for response from the agent. First read the length of the | 413 | return ssh_agent_get_reply(auth); |
458 | * response packet. | ||
459 | */ | ||
460 | len = 4; | ||
461 | while (len > 0) { | ||
462 | l = read(auth->fd, buf + 4 - len, len); | ||
463 | if (l <= 0) { | ||
464 | error("Error reading response length from authentication socket."); | ||
465 | goto error_cleanup; | ||
466 | } | ||
467 | len -= l; | ||
468 | } | ||
469 | |||
470 | /* Extract the length, and check it for sanity. */ | ||
471 | len = GET_32BIT(buf); | ||
472 | if (len > 256 * 1024) | ||
473 | fatal("Remove identity response too long: %d", len); | ||
474 | |||
475 | /* Read the rest of the response in tothe buffer. */ | ||
476 | buffer_clear(&buffer); | ||
477 | while (len > 0) { | ||
478 | l = len; | ||
479 | if (l > sizeof(buf)) | ||
480 | l = sizeof(buf); | ||
481 | l = read(auth->fd, buf, l); | ||
482 | if (l <= 0) { | ||
483 | error("Error reading response from authentication socket."); | ||
484 | goto error_cleanup; | ||
485 | } | ||
486 | buffer_append(&buffer, (char *) buf, l); | ||
487 | len -= l; | ||
488 | } | ||
489 | |||
490 | /* Get the type of the packet. */ | ||
491 | type = buffer_get_char(&buffer); | ||
492 | switch (type) { | ||
493 | case SSH_AGENT_FAILURE: | ||
494 | buffer_free(&buffer); | ||
495 | return 0; | ||
496 | case SSH_AGENT_SUCCESS: | ||
497 | buffer_free(&buffer); | ||
498 | return 1; | ||
499 | default: | ||
500 | fatal("Bad response to remove identity from authentication agent: %d", | ||
501 | type); | ||
502 | } | ||
503 | /* NOTREACHED */ | ||
504 | return 0; | ||
505 | } | 414 | } |
506 | 415 | ||
507 | /* | 416 | /* |
@@ -512,9 +421,7 @@ error_cleanup: | |||
512 | int | 421 | int |
513 | ssh_remove_all_identities(AuthenticationConnection *auth) | 422 | ssh_remove_all_identities(AuthenticationConnection *auth) |
514 | { | 423 | { |
515 | Buffer buffer; | 424 | unsigned char buf[5]; |
516 | unsigned char buf[8192]; | ||
517 | int len, l, type; | ||
518 | 425 | ||
519 | /* Get the length of the message, and format it in the buffer. */ | 426 | /* Get the length of the message, and format it in the buffer. */ |
520 | PUT_32BIT(buf, 1); | 427 | PUT_32BIT(buf, 1); |
@@ -525,6 +432,20 @@ ssh_remove_all_identities(AuthenticationConnection *auth) | |||
525 | error("Error writing to authentication socket."); | 432 | error("Error writing to authentication socket."); |
526 | return 0; | 433 | return 0; |
527 | } | 434 | } |
435 | return ssh_agent_get_reply(auth); | ||
436 | } | ||
437 | |||
438 | /* | ||
439 | * Read for reply from agent. returns 1 for success, 0 on error | ||
440 | */ | ||
441 | |||
442 | int | ||
443 | ssh_agent_get_reply(AuthenticationConnection *auth) | ||
444 | { | ||
445 | Buffer buffer; | ||
446 | unsigned char buf[8192]; | ||
447 | int len, l, type; | ||
448 | |||
528 | /* | 449 | /* |
529 | * Wait for response from the agent. First read the length of the | 450 | * Wait for response from the agent. First read the length of the |
530 | * response packet. | 451 | * response packet. |
@@ -534,6 +455,7 @@ ssh_remove_all_identities(AuthenticationConnection *auth) | |||
534 | l = read(auth->fd, buf + 4 - len, len); | 455 | l = read(auth->fd, buf + 4 - len, len); |
535 | if (l <= 0) { | 456 | if (l <= 0) { |
536 | error("Error reading response length from authentication socket."); | 457 | error("Error reading response length from authentication socket."); |
458 | buffer_free(&buffer); | ||
537 | return 0; | 459 | return 0; |
538 | } | 460 | } |
539 | len -= l; | 461 | len -= l; |
@@ -542,9 +464,9 @@ ssh_remove_all_identities(AuthenticationConnection *auth) | |||
542 | /* Extract the length, and check it for sanity. */ | 464 | /* Extract the length, and check it for sanity. */ |
543 | len = GET_32BIT(buf); | 465 | len = GET_32BIT(buf); |
544 | if (len > 256 * 1024) | 466 | if (len > 256 * 1024) |
545 | fatal("Remove identity response too long: %d", len); | 467 | fatal("Response from agent too long: %d", len); |
546 | 468 | ||
547 | /* Read the rest of the response into the buffer. */ | 469 | /* Read the rest of the response in to the buffer. */ |
548 | buffer_init(&buffer); | 470 | buffer_init(&buffer); |
549 | while (len > 0) { | 471 | while (len > 0) { |
550 | l = len; | 472 | l = len; |
@@ -562,16 +484,14 @@ ssh_remove_all_identities(AuthenticationConnection *auth) | |||
562 | 484 | ||
563 | /* Get the type of the packet. */ | 485 | /* Get the type of the packet. */ |
564 | type = buffer_get_char(&buffer); | 486 | type = buffer_get_char(&buffer); |
487 | buffer_free(&buffer); | ||
565 | switch (type) { | 488 | switch (type) { |
566 | case SSH_AGENT_FAILURE: | 489 | case SSH_AGENT_FAILURE: |
567 | buffer_free(&buffer); | ||
568 | return 0; | 490 | return 0; |
569 | case SSH_AGENT_SUCCESS: | 491 | case SSH_AGENT_SUCCESS: |
570 | buffer_free(&buffer); | ||
571 | return 1; | 492 | return 1; |
572 | default: | 493 | default: |
573 | fatal("Bad response to remove identity from authentication agent: %d", | 494 | fatal("Bad response from authentication agent: %d", type); |
574 | type); | ||
575 | } | 495 | } |
576 | /* NOTREACHED */ | 496 | /* NOTREACHED */ |
577 | return 0; | 497 | return 0; |
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$OpenBSD: cipher.c,v 1.28 2000/06/20 01:39:40 markus Exp $"); | 15 | RCSID("$OpenBSD: cipher.c,v 1.29 2000/07/10 16:30:25 ho Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "cipher.h" | 18 | #include "cipher.h" |
@@ -174,14 +174,15 @@ cipher_name(int cipher) | |||
174 | int | 174 | int |
175 | ciphers_valid(const char *names) | 175 | ciphers_valid(const char *names) |
176 | { | 176 | { |
177 | char *ciphers; | 177 | char *ciphers, *cp; |
178 | char *p; | 178 | char *p; |
179 | int i; | 179 | int i; |
180 | 180 | ||
181 | if (names == NULL || strcmp(names, "") == 0) | 181 | if (names == NULL || strcmp(names, "") == 0) |
182 | return 0; | 182 | return 0; |
183 | ciphers = xstrdup(names); | 183 | ciphers = cp = xstrdup(names); |
184 | for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) { | 184 | for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; |
185 | (p = strsep(&cp, CIPHER_SEP))) { | ||
185 | i = cipher_number(p); | 186 | i = cipher_number(p); |
186 | if (i == -1 || !(cipher_mask2() & (1 << i))) { | 187 | if (i == -1 || !(cipher_mask2() & (1 << i))) { |
187 | xfree(ciphers); | 188 | xfree(ciphers); |
@@ -28,7 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$OpenBSD: compat.c,v 1.17 2000/06/20 01:39:40 markus Exp $"); | 31 | RCSID("$OpenBSD: compat.c,v 1.19 2000/07/09 01:27:32 ho Exp $"); |
32 | 32 | ||
33 | #include "ssh.h" | 33 | #include "ssh.h" |
34 | #include "packet.h" | 34 | #include "packet.h" |
@@ -81,13 +81,13 @@ compat_datafellows(const char *version) | |||
81 | int | 81 | int |
82 | proto_spec(const char *spec) | 82 | proto_spec(const char *spec) |
83 | { | 83 | { |
84 | char *s, *p; | 84 | char *s, *p, *q; |
85 | int ret = SSH_PROTO_UNKNOWN; | 85 | int ret = SSH_PROTO_UNKNOWN; |
86 | 86 | ||
87 | if (spec == NULL) | 87 | if (spec == NULL) |
88 | return ret; | 88 | return ret; |
89 | s = xstrdup(spec); | 89 | q = s = xstrdup(spec); |
90 | for ((p = strtok(s, SEP)); p; (p = strtok(NULL, SEP))) { | 90 | for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { |
91 | switch(atoi(p)) { | 91 | switch(atoi(p)) { |
92 | case 1: | 92 | case 1: |
93 | if (ret == SSH_PROTO_UNKNOWN) | 93 | if (ret == SSH_PROTO_UNKNOWN) |
@@ -28,7 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$OpenBSD: kex.c,v 1.8 2000/06/20 01:39:41 markus Exp $"); | 31 | RCSID("$OpenBSD: kex.c,v 1.9 2000/07/10 16:30:25 ho Exp $"); |
32 | 32 | ||
33 | #include "ssh.h" | 33 | #include "ssh.h" |
34 | #include "ssh2.h" | 34 | #include "ssh2.h" |
@@ -287,13 +287,14 @@ char * | |||
287 | get_match(char *client, char *server) | 287 | get_match(char *client, char *server) |
288 | { | 288 | { |
289 | char *sproposals[MAX_PROP]; | 289 | char *sproposals[MAX_PROP]; |
290 | char *c, *s, *p, *ret; | 290 | char *c, *s, *p, *ret, *cp, *sp; |
291 | int i, j, nproposals; | 291 | int i, j, nproposals; |
292 | 292 | ||
293 | c = xstrdup(client); | 293 | c = cp = xstrdup(client); |
294 | s = xstrdup(server); | 294 | s = sp = xstrdup(server); |
295 | 295 | ||
296 | for ((p = strtok(s, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { | 296 | for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0'; |
297 | (p = strsep(&sp, SEP)), i++) { | ||
297 | if (i < MAX_PROP) | 298 | if (i < MAX_PROP) |
298 | sproposals[i] = p; | 299 | sproposals[i] = p; |
299 | else | 300 | else |
@@ -301,7 +302,8 @@ get_match(char *client, char *server) | |||
301 | } | 302 | } |
302 | nproposals = i; | 303 | nproposals = i; |
303 | 304 | ||
304 | for ((p = strtok(c, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { | 305 | for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0'; |
306 | (p = strsep(&cp, SEP)), i++) { | ||
305 | for (j = 0; j < nproposals; j++) { | 307 | for (j = 0; j < nproposals; j++) { |
306 | if (strcmp(p, sproposals[j]) == 0) { | 308 | if (strcmp(p, sproposals[j]) == 0) { |
307 | ret = xstrdup(p); | 309 | ret = xstrdup(p); |
diff --git a/readconf.c b/readconf.c index 6d015a202..28aa0a8b8 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$OpenBSD: readconf.c,v 1.37 2000/06/20 01:39:43 markus Exp $"); | 17 | RCSID("$OpenBSD: readconf.c,v 1.40 2000/07/10 16:27:05 ho Exp $"); |
18 | 18 | ||
19 | #include "ssh.h" | 19 | #include "ssh.h" |
20 | #include "cipher.h" | 20 | #include "cipher.h" |
@@ -164,7 +164,7 @@ static struct { | |||
164 | { NULL, 0 } | 164 | { NULL, 0 } |
165 | }; | 165 | }; |
166 | 166 | ||
167 | /* Characters considered whitespace in strtok calls. */ | 167 | /* Characters considered whitespace in strsep calls. */ |
168 | #define WHITESPACE " \t\r\n=" | 168 | #define WHITESPACE " \t\r\n=" |
169 | 169 | ||
170 | 170 | ||
@@ -237,18 +237,18 @@ process_config_line(Options *options, const char *host, | |||
237 | char *line, const char *filename, int linenum, | 237 | char *line, const char *filename, int linenum, |
238 | int *activep) | 238 | int *activep) |
239 | { | 239 | { |
240 | char buf[256], *cp, *string, **charptr, *cp2; | 240 | char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg; |
241 | int opcode, *intptr, value; | 241 | int opcode, *intptr, value; |
242 | u_short fwd_port, fwd_host_port; | 242 | u_short fwd_port, fwd_host_port; |
243 | 243 | ||
244 | /* Skip leading whitespace. */ | 244 | /* Skip leading whitespace. */ |
245 | cp = line + strspn(line, WHITESPACE); | 245 | s = line + strspn(line, WHITESPACE); |
246 | if (!*cp || *cp == '\n' || *cp == '#') | 246 | if (!*s || *s == '\n' || *s == '#') |
247 | return 0; | 247 | return 0; |
248 | 248 | ||
249 | /* Get the keyword. (Each line is supposed to begin with a keyword). */ | 249 | /* Get the keyword. (Each line is supposed to begin with a keyword). */ |
250 | cp = strtok(cp, WHITESPACE); | 250 | keyword = strsep(&s, WHITESPACE); |
251 | opcode = parse_token(cp, filename, linenum); | 251 | opcode = parse_token(keyword, filename, linenum); |
252 | 252 | ||
253 | switch (opcode) { | 253 | switch (opcode) { |
254 | case oBadOption: | 254 | case oBadOption: |
@@ -258,13 +258,13 @@ process_config_line(Options *options, const char *host, | |||
258 | case oForwardAgent: | 258 | case oForwardAgent: |
259 | intptr = &options->forward_agent; | 259 | intptr = &options->forward_agent; |
260 | parse_flag: | 260 | parse_flag: |
261 | cp = strtok(NULL, WHITESPACE); | 261 | arg = strsep(&s, WHITESPACE); |
262 | if (!cp) | 262 | if (!arg || *arg == '\0') |
263 | fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); | 263 | fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); |
264 | value = 0; /* To avoid compiler warning... */ | 264 | value = 0; /* To avoid compiler warning... */ |
265 | if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) | 265 | if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) |
266 | value = 1; | 266 | value = 1; |
267 | else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) | 267 | else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) |
268 | value = 0; | 268 | value = 0; |
269 | else | 269 | else |
270 | fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); | 270 | fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); |
@@ -344,16 +344,16 @@ parse_flag: | |||
344 | 344 | ||
345 | case oStrictHostKeyChecking: | 345 | case oStrictHostKeyChecking: |
346 | intptr = &options->strict_host_key_checking; | 346 | intptr = &options->strict_host_key_checking; |
347 | cp = strtok(NULL, WHITESPACE); | 347 | arg = strsep(&s, WHITESPACE); |
348 | if (!cp) | 348 | if (!arg || *arg == '\0') |
349 | fatal("%.200s line %d: Missing yes/no argument.", | 349 | fatal("%.200s line %d: Missing yes/no argument.", |
350 | filename, linenum); | 350 | filename, linenum); |
351 | value = 0; /* To avoid compiler warning... */ | 351 | value = 0; /* To avoid compiler warning... */ |
352 | if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) | 352 | if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) |
353 | value = 1; | 353 | value = 1; |
354 | else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) | 354 | else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) |
355 | value = 0; | 355 | value = 0; |
356 | else if (strcmp(cp, "ask") == 0) | 356 | else if (strcmp(arg, "ask") == 0) |
357 | value = 2; | 357 | value = 2; |
358 | else | 358 | else |
359 | fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); | 359 | fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); |
@@ -379,8 +379,8 @@ parse_flag: | |||
379 | 379 | ||
380 | case oIdentityFile: | 380 | case oIdentityFile: |
381 | case oIdentityFile2: | 381 | case oIdentityFile2: |
382 | cp = strtok(NULL, WHITESPACE); | 382 | arg = strsep(&s, WHITESPACE); |
383 | if (!cp) | 383 | if (!arg || *arg == '\0') |
384 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 384 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
385 | if (*activep) { | 385 | if (*activep) { |
386 | intptr = (opcode == oIdentityFile) ? | 386 | intptr = (opcode == oIdentityFile) ? |
@@ -392,7 +392,7 @@ parse_flag: | |||
392 | charptr = (opcode == oIdentityFile) ? | 392 | charptr = (opcode == oIdentityFile) ? |
393 | &options->identity_files[*intptr] : | 393 | &options->identity_files[*intptr] : |
394 | &options->identity_files2[*intptr]; | 394 | &options->identity_files2[*intptr]; |
395 | *charptr = xstrdup(cp); | 395 | *charptr = xstrdup(arg); |
396 | *intptr = *intptr + 1; | 396 | *intptr = *intptr + 1; |
397 | } | 397 | } |
398 | break; | 398 | break; |
@@ -404,11 +404,11 @@ parse_flag: | |||
404 | case oUser: | 404 | case oUser: |
405 | charptr = &options->user; | 405 | charptr = &options->user; |
406 | parse_string: | 406 | parse_string: |
407 | cp = strtok(NULL, WHITESPACE); | 407 | arg = strsep(&s, WHITESPACE); |
408 | if (!cp) | 408 | if (!arg || *arg == '\0') |
409 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 409 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
410 | if (*activep && *charptr == NULL) | 410 | if (*activep && *charptr == NULL) |
411 | *charptr = xstrdup(cp); | 411 | *charptr = xstrdup(arg); |
412 | break; | 412 | break; |
413 | 413 | ||
414 | case oGlobalKnownHostsFile: | 414 | case oGlobalKnownHostsFile: |
@@ -434,10 +434,10 @@ parse_string: | |||
434 | case oProxyCommand: | 434 | case oProxyCommand: |
435 | charptr = &options->proxy_command; | 435 | charptr = &options->proxy_command; |
436 | string = xstrdup(""); | 436 | string = xstrdup(""); |
437 | while ((cp = strtok(NULL, WHITESPACE)) != NULL) { | 437 | while ((arg = strsep(&s, WHITESPACE)) != NULL && *arg != '\0') { |
438 | string = xrealloc(string, strlen(string) + strlen(cp) + 2); | 438 | string = xrealloc(string, strlen(string) + strlen(arg) + 2); |
439 | strcat(string, " "); | 439 | strcat(string, " "); |
440 | strcat(string, cp); | 440 | strcat(string, arg); |
441 | } | 441 | } |
442 | if (*activep && *charptr == NULL) | 442 | if (*activep && *charptr == NULL) |
443 | *charptr = string; | 443 | *charptr = string; |
@@ -448,15 +448,15 @@ parse_string: | |||
448 | case oPort: | 448 | case oPort: |
449 | intptr = &options->port; | 449 | intptr = &options->port; |
450 | parse_int: | 450 | parse_int: |
451 | cp = strtok(NULL, WHITESPACE); | 451 | arg = strsep(&s, WHITESPACE); |
452 | if (!cp) | 452 | if (!arg || *arg == '\0') |
453 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 453 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
454 | if (cp[0] < '0' || cp[0] > '9') | 454 | if (arg[0] < '0' || arg[0] > '9') |
455 | fatal("%.200s line %d: Bad number.", filename, linenum); | 455 | fatal("%.200s line %d: Bad number.", filename, linenum); |
456 | 456 | ||
457 | /* Octal, decimal, or hex format? */ | 457 | /* Octal, decimal, or hex format? */ |
458 | value = strtol(cp, &cp2, 0); | 458 | value = strtol(arg, &endofnumber, 0); |
459 | if (cp == cp2) | 459 | if (arg == endofnumber) |
460 | fatal("%.200s line %d: Bad number.", filename, linenum); | 460 | fatal("%.200s line %d: Bad number.", filename, linenum); |
461 | if (*activep && *intptr == -1) | 461 | if (*activep && *intptr == -1) |
462 | *intptr = value; | 462 | *intptr = value; |
@@ -468,65 +468,65 @@ parse_int: | |||
468 | 468 | ||
469 | case oCipher: | 469 | case oCipher: |
470 | intptr = &options->cipher; | 470 | intptr = &options->cipher; |
471 | cp = strtok(NULL, WHITESPACE); | 471 | arg = strsep(&s, WHITESPACE); |
472 | if (!cp) | 472 | if (!arg || *arg == '\0') |
473 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 473 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
474 | value = cipher_number(cp); | 474 | value = cipher_number(arg); |
475 | if (value == -1) | 475 | if (value == -1) |
476 | fatal("%.200s line %d: Bad cipher '%s'.", | 476 | fatal("%.200s line %d: Bad cipher '%s'.", |
477 | filename, linenum, cp ? cp : "<NONE>"); | 477 | filename, linenum, arg ? arg : "<NONE>"); |
478 | if (*activep && *intptr == -1) | 478 | if (*activep && *intptr == -1) |
479 | *intptr = value; | 479 | *intptr = value; |
480 | break; | 480 | break; |
481 | 481 | ||
482 | case oCiphers: | 482 | case oCiphers: |
483 | cp = strtok(NULL, WHITESPACE); | 483 | arg = strsep(&s, WHITESPACE); |
484 | if (!cp) | 484 | if (!arg || *arg == '\0') |
485 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 485 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
486 | if (!ciphers_valid(cp)) | 486 | if (!ciphers_valid(arg)) |
487 | fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", | 487 | fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", |
488 | filename, linenum, cp ? cp : "<NONE>"); | 488 | filename, linenum, arg ? arg : "<NONE>"); |
489 | if (*activep && options->ciphers == NULL) | 489 | if (*activep && options->ciphers == NULL) |
490 | options->ciphers = xstrdup(cp); | 490 | options->ciphers = xstrdup(arg); |
491 | break; | 491 | break; |
492 | 492 | ||
493 | case oProtocol: | 493 | case oProtocol: |
494 | intptr = &options->protocol; | 494 | intptr = &options->protocol; |
495 | cp = strtok(NULL, WHITESPACE); | 495 | arg = strsep(&s, WHITESPACE); |
496 | if (!cp) | 496 | if (!arg || *arg == '\0') |
497 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 497 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
498 | value = proto_spec(cp); | 498 | value = proto_spec(arg); |
499 | if (value == SSH_PROTO_UNKNOWN) | 499 | if (value == SSH_PROTO_UNKNOWN) |
500 | fatal("%.200s line %d: Bad protocol spec '%s'.", | 500 | fatal("%.200s line %d: Bad protocol spec '%s'.", |
501 | filename, linenum, cp ? cp : "<NONE>"); | 501 | filename, linenum, arg ? arg : "<NONE>"); |
502 | if (*activep && *intptr == SSH_PROTO_UNKNOWN) | 502 | if (*activep && *intptr == SSH_PROTO_UNKNOWN) |
503 | *intptr = value; | 503 | *intptr = value; |
504 | break; | 504 | break; |
505 | 505 | ||
506 | case oLogLevel: | 506 | case oLogLevel: |
507 | intptr = (int *) &options->log_level; | 507 | intptr = (int *) &options->log_level; |
508 | cp = strtok(NULL, WHITESPACE); | 508 | arg = strsep(&s, WHITESPACE); |
509 | value = log_level_number(cp); | 509 | value = log_level_number(arg); |
510 | if (value == (LogLevel) - 1) | 510 | if (value == (LogLevel) - 1) |
511 | fatal("%.200s line %d: unsupported log level '%s'\n", | 511 | fatal("%.200s line %d: unsupported log level '%s'\n", |
512 | filename, linenum, cp ? cp : "<NONE>"); | 512 | filename, linenum, arg ? arg : "<NONE>"); |
513 | if (*activep && (LogLevel) * intptr == -1) | 513 | if (*activep && (LogLevel) * intptr == -1) |
514 | *intptr = (LogLevel) value; | 514 | *intptr = (LogLevel) value; |
515 | break; | 515 | break; |
516 | 516 | ||
517 | case oRemoteForward: | 517 | case oRemoteForward: |
518 | cp = strtok(NULL, WHITESPACE); | 518 | arg = strsep(&s, WHITESPACE); |
519 | if (!cp) | 519 | if (!arg || *arg == '\0') |
520 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 520 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
521 | if (cp[0] < '0' || cp[0] > '9') | 521 | if (arg[0] < '0' || arg[0] > '9') |
522 | fatal("%.200s line %d: Badly formatted port number.", | 522 | fatal("%.200s line %d: Badly formatted port number.", |
523 | filename, linenum); | 523 | filename, linenum); |
524 | fwd_port = atoi(cp); | 524 | fwd_port = atoi(arg); |
525 | cp = strtok(NULL, WHITESPACE); | 525 | arg = strsep(&s, WHITESPACE); |
526 | if (!cp) | 526 | if (!arg || *arg == '\0') |
527 | fatal("%.200s line %d: Missing second argument.", | 527 | fatal("%.200s line %d: Missing second argument.", |
528 | filename, linenum); | 528 | filename, linenum); |
529 | if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2) | 529 | if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) |
530 | fatal("%.200s line %d: Badly formatted host:port.", | 530 | fatal("%.200s line %d: Badly formatted host:port.", |
531 | filename, linenum); | 531 | filename, linenum); |
532 | if (*activep) | 532 | if (*activep) |
@@ -534,18 +534,18 @@ parse_int: | |||
534 | break; | 534 | break; |
535 | 535 | ||
536 | case oLocalForward: | 536 | case oLocalForward: |
537 | cp = strtok(NULL, WHITESPACE); | 537 | arg = strsep(&s, WHITESPACE); |
538 | if (!cp) | 538 | if (!arg || *arg == '\0') |
539 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 539 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
540 | if (cp[0] < '0' || cp[0] > '9') | 540 | if (arg[0] < '0' || arg[0] > '9') |
541 | fatal("%.200s line %d: Badly formatted port number.", | 541 | fatal("%.200s line %d: Badly formatted port number.", |
542 | filename, linenum); | 542 | filename, linenum); |
543 | fwd_port = atoi(cp); | 543 | fwd_port = atoi(arg); |
544 | cp = strtok(NULL, WHITESPACE); | 544 | arg = strsep(&s, WHITESPACE); |
545 | if (!cp) | 545 | if (!arg || *arg == '\0') |
546 | fatal("%.200s line %d: Missing second argument.", | 546 | fatal("%.200s line %d: Missing second argument.", |
547 | filename, linenum); | 547 | filename, linenum); |
548 | if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2) | 548 | if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) |
549 | fatal("%.200s line %d: Badly formatted host:port.", | 549 | fatal("%.200s line %d: Badly formatted host:port.", |
550 | filename, linenum); | 550 | filename, linenum); |
551 | if (*activep) | 551 | if (*activep) |
@@ -554,26 +554,26 @@ parse_int: | |||
554 | 554 | ||
555 | case oHost: | 555 | case oHost: |
556 | *activep = 0; | 556 | *activep = 0; |
557 | while ((cp = strtok(NULL, WHITESPACE)) != NULL) | 557 | while ((arg = strsep(&s, WHITESPACE)) != NULL && *arg != '\0') |
558 | if (match_pattern(host, cp)) { | 558 | if (match_pattern(host, arg)) { |
559 | debug("Applying options for %.100s", cp); | 559 | debug("Applying options for %.100s", arg); |
560 | *activep = 1; | 560 | *activep = 1; |
561 | break; | 561 | break; |
562 | } | 562 | } |
563 | /* Avoid garbage check below, as strtok already returned NULL. */ | 563 | /* Avoid garbage check below, as strsep is done. */ |
564 | return 0; | 564 | return 0; |
565 | 565 | ||
566 | case oEscapeChar: | 566 | case oEscapeChar: |
567 | intptr = &options->escape_char; | 567 | intptr = &options->escape_char; |
568 | cp = strtok(NULL, WHITESPACE); | 568 | arg = strsep(&s, WHITESPACE); |
569 | if (!cp) | 569 | if (!arg || *arg == '\0') |
570 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 570 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
571 | if (cp[0] == '^' && cp[2] == 0 && | 571 | if (arg[0] == '^' && arg[2] == 0 && |
572 | (unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128) | 572 | (unsigned char) arg[1] >= 64 && (unsigned char) arg[1] < 128) |
573 | value = (unsigned char) cp[1] & 31; | 573 | value = (unsigned char) arg[1] & 31; |
574 | else if (strlen(cp) == 1) | 574 | else if (strlen(arg) == 1) |
575 | value = (unsigned char) cp[0]; | 575 | value = (unsigned char) arg[0]; |
576 | else if (strcmp(cp, "none") == 0) | 576 | else if (strcmp(arg, "none") == 0) |
577 | value = -2; | 577 | value = -2; |
578 | else { | 578 | else { |
579 | fatal("%.200s line %d: Bad escape character.", | 579 | fatal("%.200s line %d: Bad escape character.", |
@@ -590,9 +590,11 @@ parse_int: | |||
590 | } | 590 | } |
591 | 591 | ||
592 | /* Check that there is no garbage at end of line. */ | 592 | /* Check that there is no garbage at end of line. */ |
593 | if (strtok(NULL, WHITESPACE) != NULL) | 593 | if ((arg = strsep(&s, WHITESPACE)) != NULL && *arg != '\0') |
594 | fatal("%.200s line %d: garbage at end of line.", | 594 | { |
595 | filename, linenum); | 595 | fatal("%.200s line %d: garbage at end of line; \"%.200s\".", |
596 | filename, linenum, arg); | ||
597 | } | ||
596 | return 0; | 598 | return 0; |
597 | } | 599 | } |
598 | 600 | ||
@@ -9,7 +9,7 @@ | |||
9 | .\" | 9 | .\" |
10 | .\" Created: Sun May 7 00:14:37 1995 ylo | 10 | .\" Created: Sun May 7 00:14:37 1995 ylo |
11 | .\" | 11 | .\" |
12 | .\" $Id: scp.1,v 1.7 2000/04/13 02:26:37 damien Exp $ | 12 | .\" $Id: scp.1,v 1.8 2000/07/11 07:31:38 djm Exp $ |
13 | .\" | 13 | .\" |
14 | .Dd September 25, 1999 | 14 | .Dd September 25, 1999 |
15 | .Dt SCP 1 | 15 | .Dt SCP 1 |
@@ -106,6 +106,7 @@ to use IPv4 addresses only. | |||
106 | Forces | 106 | Forces |
107 | .Nm | 107 | .Nm |
108 | to use IPv6 addresses only. | 108 | to use IPv6 addresses only. |
109 | .El | ||
109 | .Sh AUTHORS | 110 | .Sh AUTHORS |
110 | Timo Rinne <tri@iki.fi> and Tatu Ylonen <ylo@cs.hut.fi> | 111 | Timo Rinne <tri@iki.fi> and Tatu Ylonen <ylo@cs.hut.fi> |
111 | .Sh HISTORY | 112 | .Sh HISTORY |
diff --git a/servconf.c b/servconf.c index 12cc15260..77ac84527 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$OpenBSD: servconf.c,v 1.45 2000/06/20 01:39:44 markus Exp $"); | 15 | RCSID("$OpenBSD: servconf.c,v 1.47 2000/07/10 16:30:25 ho Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "servconf.h" | 18 | #include "servconf.h" |
@@ -76,6 +76,7 @@ initialize_server_options(ServerOptions *options) | |||
76 | options->protocol = SSH_PROTO_UNKNOWN; | 76 | options->protocol = SSH_PROTO_UNKNOWN; |
77 | options->gateway_ports = -1; | 77 | options->gateway_ports = -1; |
78 | options->num_subsystems = 0; | 78 | options->num_subsystems = 0; |
79 | options->max_startups = -1; | ||
79 | } | 80 | } |
80 | 81 | ||
81 | void | 82 | void |
@@ -159,6 +160,8 @@ fill_default_server_options(ServerOptions *options) | |||
159 | options->protocol = SSH_PROTO_1|SSH_PROTO_2; | 160 | options->protocol = SSH_PROTO_1|SSH_PROTO_2; |
160 | if (options->gateway_ports == -1) | 161 | if (options->gateway_ports == -1) |
161 | options->gateway_ports = 0; | 162 | options->gateway_ports = 0; |
163 | if (options->max_startups == -1) | ||
164 | options->max_startups = 10; | ||
162 | } | 165 | } |
163 | 166 | ||
164 | #define WHITESPACE " \t\r\n=" | 167 | #define WHITESPACE " \t\r\n=" |
@@ -183,7 +186,7 @@ typedef enum { | |||
183 | sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, | 186 | sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, |
184 | sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, | 187 | sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, |
185 | sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, | 188 | sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, |
186 | sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem | 189 | sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups |
187 | } ServerOpCodes; | 190 | } ServerOpCodes; |
188 | 191 | ||
189 | /* Textual representation of the tokens. */ | 192 | /* Textual representation of the tokens. */ |
@@ -239,6 +242,7 @@ static struct { | |||
239 | { "protocol", sProtocol }, | 242 | { "protocol", sProtocol }, |
240 | { "gatewayports", sGatewayPorts }, | 243 | { "gatewayports", sGatewayPorts }, |
241 | { "subsystem", sSubsystem }, | 244 | { "subsystem", sSubsystem }, |
245 | { "maxstartups", sMaxStartups }, | ||
242 | { NULL, 0 } | 246 | { NULL, 0 } |
243 | }; | 247 | }; |
244 | 248 | ||
@@ -300,7 +304,7 @@ read_server_config(ServerOptions *options, const char *filename) | |||
300 | { | 304 | { |
301 | FILE *f; | 305 | FILE *f; |
302 | char line[1024]; | 306 | char line[1024]; |
303 | char *cp, **charptr; | 307 | char *cp, **charptr, *arg; |
304 | int linenum, *intptr, value; | 308 | int linenum, *intptr, value; |
305 | int bad_options = 0; | 309 | int bad_options = 0; |
306 | ServerOpCodes opcode; | 310 | ServerOpCodes opcode; |
@@ -317,8 +321,8 @@ read_server_config(ServerOptions *options, const char *filename) | |||
317 | cp = line + strspn(line, WHITESPACE); | 321 | cp = line + strspn(line, WHITESPACE); |
318 | if (!*cp || *cp == '#') | 322 | if (!*cp || *cp == '#') |
319 | continue; | 323 | continue; |
320 | cp = strtok(cp, WHITESPACE); | 324 | arg = strsep(&cp, WHITESPACE); |
321 | opcode = parse_token(cp, filename, linenum); | 325 | opcode = parse_token(arg, filename, linenum); |
322 | switch (opcode) { | 326 | switch (opcode) { |
323 | case sBadOption: | 327 | case sBadOption: |
324 | bad_options++; | 328 | bad_options++; |
@@ -333,23 +337,23 @@ read_server_config(ServerOptions *options, const char *filename) | |||
333 | if (options->num_ports >= MAX_PORTS) | 337 | if (options->num_ports >= MAX_PORTS) |
334 | fatal("%s line %d: too many ports.\n", | 338 | fatal("%s line %d: too many ports.\n", |
335 | filename, linenum); | 339 | filename, linenum); |
336 | cp = strtok(NULL, WHITESPACE); | 340 | arg = strsep(&cp, WHITESPACE); |
337 | if (!cp) | 341 | if (!arg || *arg == '\0') |
338 | fatal("%s line %d: missing port number.\n", | 342 | fatal("%s line %d: missing port number.\n", |
339 | filename, linenum); | 343 | filename, linenum); |
340 | options->ports[options->num_ports++] = atoi(cp); | 344 | options->ports[options->num_ports++] = atoi(arg); |
341 | break; | 345 | break; |
342 | 346 | ||
343 | case sServerKeyBits: | 347 | case sServerKeyBits: |
344 | intptr = &options->server_key_bits; | 348 | intptr = &options->server_key_bits; |
345 | parse_int: | 349 | parse_int: |
346 | cp = strtok(NULL, WHITESPACE); | 350 | arg = strsep(&cp, WHITESPACE); |
347 | if (!cp) { | 351 | if (!arg || *arg == '\0') { |
348 | fprintf(stderr, "%s line %d: missing integer value.\n", | 352 | fprintf(stderr, "%s line %d: missing integer value.\n", |
349 | filename, linenum); | 353 | filename, linenum); |
350 | exit(1); | 354 | exit(1); |
351 | } | 355 | } |
352 | value = atoi(cp); | 356 | value = atoi(arg); |
353 | if (*intptr == -1) | 357 | if (*intptr == -1) |
354 | *intptr = value; | 358 | *intptr = value; |
355 | break; | 359 | break; |
@@ -363,11 +367,11 @@ parse_int: | |||
363 | goto parse_int; | 367 | goto parse_int; |
364 | 368 | ||
365 | case sListenAddress: | 369 | case sListenAddress: |
366 | cp = strtok(NULL, WHITESPACE); | 370 | arg = strsep(&cp, WHITESPACE); |
367 | if (!cp) | 371 | if (!arg || *arg == '\0') |
368 | fatal("%s line %d: missing inet addr.\n", | 372 | fatal("%s line %d: missing inet addr.\n", |
369 | filename, linenum); | 373 | filename, linenum); |
370 | add_listen_addr(options, cp); | 374 | add_listen_addr(options, arg); |
371 | break; | 375 | break; |
372 | 376 | ||
373 | case sHostKeyFile: | 377 | case sHostKeyFile: |
@@ -375,14 +379,14 @@ parse_int: | |||
375 | charptr = (opcode == sHostKeyFile ) ? | 379 | charptr = (opcode == sHostKeyFile ) ? |
376 | &options->host_key_file : &options->host_dsa_key_file; | 380 | &options->host_key_file : &options->host_dsa_key_file; |
377 | parse_filename: | 381 | parse_filename: |
378 | cp = strtok(NULL, WHITESPACE); | 382 | arg = strsep(&cp, WHITESPACE); |
379 | if (!cp) { | 383 | if (!arg || *arg == '\0') { |
380 | fprintf(stderr, "%s line %d: missing file name.\n", | 384 | fprintf(stderr, "%s line %d: missing file name.\n", |
381 | filename, linenum); | 385 | filename, linenum); |
382 | exit(1); | 386 | exit(1); |
383 | } | 387 | } |
384 | if (*charptr == NULL) | 388 | if (*charptr == NULL) |
385 | *charptr = tilde_expand_filename(cp, getuid()); | 389 | *charptr = tilde_expand_filename(arg, getuid()); |
386 | break; | 390 | break; |
387 | 391 | ||
388 | case sPidFile: | 392 | case sPidFile: |
@@ -392,26 +396,26 @@ parse_filename: | |||
392 | case sRandomSeedFile: | 396 | case sRandomSeedFile: |
393 | fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", | 397 | fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", |
394 | filename, linenum); | 398 | filename, linenum); |
395 | cp = strtok(NULL, WHITESPACE); | 399 | arg = strsep(&cp, WHITESPACE); |
396 | break; | 400 | break; |
397 | 401 | ||
398 | case sPermitRootLogin: | 402 | case sPermitRootLogin: |
399 | intptr = &options->permit_root_login; | 403 | intptr = &options->permit_root_login; |
400 | cp = strtok(NULL, WHITESPACE); | 404 | arg = strsep(&cp, WHITESPACE); |
401 | if (!cp) { | 405 | if (!arg || *arg == '\0') { |
402 | fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", | 406 | fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", |
403 | filename, linenum); | 407 | filename, linenum); |
404 | exit(1); | 408 | exit(1); |
405 | } | 409 | } |
406 | if (strcmp(cp, "without-password") == 0) | 410 | if (strcmp(arg, "without-password") == 0) |
407 | value = 2; | 411 | value = 2; |
408 | else if (strcmp(cp, "yes") == 0) | 412 | else if (strcmp(arg, "yes") == 0) |
409 | value = 1; | 413 | value = 1; |
410 | else if (strcmp(cp, "no") == 0) | 414 | else if (strcmp(arg, "no") == 0) |
411 | value = 0; | 415 | value = 0; |
412 | else { | 416 | else { |
413 | fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", | 417 | fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", |
414 | filename, linenum, cp); | 418 | filename, linenum, arg); |
415 | exit(1); | 419 | exit(1); |
416 | } | 420 | } |
417 | if (*intptr == -1) | 421 | if (*intptr == -1) |
@@ -421,19 +425,19 @@ parse_filename: | |||
421 | case sIgnoreRhosts: | 425 | case sIgnoreRhosts: |
422 | intptr = &options->ignore_rhosts; | 426 | intptr = &options->ignore_rhosts; |
423 | parse_flag: | 427 | parse_flag: |
424 | cp = strtok(NULL, WHITESPACE); | 428 | arg = strsep(&cp, WHITESPACE); |
425 | if (!cp) { | 429 | if (!arg || *arg == '\0') { |
426 | fprintf(stderr, "%s line %d: missing yes/no argument.\n", | 430 | fprintf(stderr, "%s line %d: missing yes/no argument.\n", |
427 | filename, linenum); | 431 | filename, linenum); |
428 | exit(1); | 432 | exit(1); |
429 | } | 433 | } |
430 | if (strcmp(cp, "yes") == 0) | 434 | if (strcmp(arg, "yes") == 0) |
431 | value = 1; | 435 | value = 1; |
432 | else if (strcmp(cp, "no") == 0) | 436 | else if (strcmp(arg, "no") == 0) |
433 | value = 0; | 437 | value = 0; |
434 | else { | 438 | else { |
435 | fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", | 439 | fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", |
436 | filename, linenum, cp); | 440 | filename, linenum, arg); |
437 | exit(1); | 441 | exit(1); |
438 | } | 442 | } |
439 | if (*intptr == -1) | 443 | if (*intptr == -1) |
@@ -536,82 +540,82 @@ parse_flag: | |||
536 | 540 | ||
537 | case sLogFacility: | 541 | case sLogFacility: |
538 | intptr = (int *) &options->log_facility; | 542 | intptr = (int *) &options->log_facility; |
539 | cp = strtok(NULL, WHITESPACE); | 543 | arg = strsep(&cp, WHITESPACE); |
540 | value = log_facility_number(cp); | 544 | value = log_facility_number(arg); |
541 | if (value == (SyslogFacility) - 1) | 545 | if (value == (SyslogFacility) - 1) |
542 | fatal("%.200s line %d: unsupported log facility '%s'\n", | 546 | fatal("%.200s line %d: unsupported log facility '%s'\n", |
543 | filename, linenum, cp ? cp : "<NONE>"); | 547 | filename, linenum, arg ? arg : "<NONE>"); |
544 | if (*intptr == -1) | 548 | if (*intptr == -1) |
545 | *intptr = (SyslogFacility) value; | 549 | *intptr = (SyslogFacility) value; |
546 | break; | 550 | break; |
547 | 551 | ||
548 | case sLogLevel: | 552 | case sLogLevel: |
549 | intptr = (int *) &options->log_level; | 553 | intptr = (int *) &options->log_level; |
550 | cp = strtok(NULL, WHITESPACE); | 554 | arg = strsep(&cp, WHITESPACE); |
551 | value = log_level_number(cp); | 555 | value = log_level_number(arg); |
552 | if (value == (LogLevel) - 1) | 556 | if (value == (LogLevel) - 1) |
553 | fatal("%.200s line %d: unsupported log level '%s'\n", | 557 | fatal("%.200s line %d: unsupported log level '%s'\n", |
554 | filename, linenum, cp ? cp : "<NONE>"); | 558 | filename, linenum, arg ? arg : "<NONE>"); |
555 | if (*intptr == -1) | 559 | if (*intptr == -1) |
556 | *intptr = (LogLevel) value; | 560 | *intptr = (LogLevel) value; |
557 | break; | 561 | break; |
558 | 562 | ||
559 | case sAllowUsers: | 563 | case sAllowUsers: |
560 | while ((cp = strtok(NULL, WHITESPACE))) { | 564 | while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') { |
561 | if (options->num_allow_users >= MAX_ALLOW_USERS) | 565 | if (options->num_allow_users >= MAX_ALLOW_USERS) |
562 | fatal("%s line %d: too many allow users.\n", | 566 | fatal("%s line %d: too many allow users.\n", |
563 | filename, linenum); | 567 | filename, linenum); |
564 | options->allow_users[options->num_allow_users++] = xstrdup(cp); | 568 | options->allow_users[options->num_allow_users++] = xstrdup(arg); |
565 | } | 569 | } |
566 | break; | 570 | break; |
567 | 571 | ||
568 | case sDenyUsers: | 572 | case sDenyUsers: |
569 | while ((cp = strtok(NULL, WHITESPACE))) { | 573 | while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') { |
570 | if (options->num_deny_users >= MAX_DENY_USERS) | 574 | if (options->num_deny_users >= MAX_DENY_USERS) |
571 | fatal( "%s line %d: too many deny users.\n", | 575 | fatal( "%s line %d: too many deny users.\n", |
572 | filename, linenum); | 576 | filename, linenum); |
573 | options->deny_users[options->num_deny_users++] = xstrdup(cp); | 577 | options->deny_users[options->num_deny_users++] = xstrdup(arg); |
574 | } | 578 | } |
575 | break; | 579 | break; |
576 | 580 | ||
577 | case sAllowGroups: | 581 | case sAllowGroups: |
578 | while ((cp = strtok(NULL, WHITESPACE))) { | 582 | while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') { |
579 | if (options->num_allow_groups >= MAX_ALLOW_GROUPS) | 583 | if (options->num_allow_groups >= MAX_ALLOW_GROUPS) |
580 | fatal("%s line %d: too many allow groups.\n", | 584 | fatal("%s line %d: too many allow groups.\n", |
581 | filename, linenum); | 585 | filename, linenum); |
582 | options->allow_groups[options->num_allow_groups++] = xstrdup(cp); | 586 | options->allow_groups[options->num_allow_groups++] = xstrdup(arg); |
583 | } | 587 | } |
584 | break; | 588 | break; |
585 | 589 | ||
586 | case sDenyGroups: | 590 | case sDenyGroups: |
587 | while ((cp = strtok(NULL, WHITESPACE))) { | 591 | while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') { |
588 | if (options->num_deny_groups >= MAX_DENY_GROUPS) | 592 | if (options->num_deny_groups >= MAX_DENY_GROUPS) |
589 | fatal("%s line %d: too many deny groups.\n", | 593 | fatal("%s line %d: too many deny groups.\n", |
590 | filename, linenum); | 594 | filename, linenum); |
591 | options->deny_groups[options->num_deny_groups++] = xstrdup(cp); | 595 | options->deny_groups[options->num_deny_groups++] = xstrdup(arg); |
592 | } | 596 | } |
593 | break; | 597 | break; |
594 | 598 | ||
595 | case sCiphers: | 599 | case sCiphers: |
596 | cp = strtok(NULL, WHITESPACE); | 600 | arg = strsep(&cp, WHITESPACE); |
597 | if (!cp) | 601 | if (!arg || *arg == '\0') |
598 | fatal("%s line %d: Missing argument.", filename, linenum); | 602 | fatal("%s line %d: Missing argument.", filename, linenum); |
599 | if (!ciphers_valid(cp)) | 603 | if (!ciphers_valid(arg)) |
600 | fatal("%s line %d: Bad SSH2 cipher spec '%s'.", | 604 | fatal("%s line %d: Bad SSH2 cipher spec '%s'.", |
601 | filename, linenum, cp ? cp : "<NONE>"); | 605 | filename, linenum, arg ? arg : "<NONE>"); |
602 | if (options->ciphers == NULL) | 606 | if (options->ciphers == NULL) |
603 | options->ciphers = xstrdup(cp); | 607 | options->ciphers = xstrdup(arg); |
604 | break; | 608 | break; |
605 | 609 | ||
606 | case sProtocol: | 610 | case sProtocol: |
607 | intptr = &options->protocol; | 611 | intptr = &options->protocol; |
608 | cp = strtok(NULL, WHITESPACE); | 612 | arg = strsep(&cp, WHITESPACE); |
609 | if (!cp) | 613 | if (!arg || *arg == '\0') |
610 | fatal("%s line %d: Missing argument.", filename, linenum); | 614 | fatal("%s line %d: Missing argument.", filename, linenum); |
611 | value = proto_spec(cp); | 615 | value = proto_spec(arg); |
612 | if (value == SSH_PROTO_UNKNOWN) | 616 | if (value == SSH_PROTO_UNKNOWN) |
613 | fatal("%s line %d: Bad protocol spec '%s'.", | 617 | fatal("%s line %d: Bad protocol spec '%s'.", |
614 | filename, linenum, cp ? cp : "<NONE>"); | 618 | filename, linenum, arg ? arg : "<NONE>"); |
615 | if (*intptr == SSH_PROTO_UNKNOWN) | 619 | if (*intptr == SSH_PROTO_UNKNOWN) |
616 | *intptr = value; | 620 | *intptr = value; |
617 | break; | 621 | break; |
@@ -621,31 +625,36 @@ parse_flag: | |||
621 | fatal("%s line %d: too many subsystems defined.", | 625 | fatal("%s line %d: too many subsystems defined.", |
622 | filename, linenum); | 626 | filename, linenum); |
623 | } | 627 | } |
624 | cp = strtok(NULL, WHITESPACE); | 628 | arg = strsep(&cp, WHITESPACE); |
625 | if (!cp) | 629 | if (!arg || *arg == '\0') |
626 | fatal("%s line %d: Missing subsystem name.", | 630 | fatal("%s line %d: Missing subsystem name.", |
627 | filename, linenum); | 631 | filename, linenum); |
628 | for (i = 0; i < options->num_subsystems; i++) | 632 | for (i = 0; i < options->num_subsystems; i++) |
629 | if(strcmp(cp, options->subsystem_name[i]) == 0) | 633 | if(strcmp(arg, options->subsystem_name[i]) == 0) |
630 | fatal("%s line %d: Subsystem '%s' already defined.", | 634 | fatal("%s line %d: Subsystem '%s' already defined.", |
631 | filename, linenum, cp); | 635 | filename, linenum, arg); |
632 | options->subsystem_name[options->num_subsystems] = xstrdup(cp); | 636 | options->subsystem_name[options->num_subsystems] = xstrdup(arg); |
633 | cp = strtok(NULL, WHITESPACE); | 637 | arg = strsep(&cp, WHITESPACE); |
634 | if (!cp) | 638 | if (!arg || *arg == '\0') |
635 | fatal("%s line %d: Missing subsystem command.", | 639 | fatal("%s line %d: Missing subsystem command.", |
636 | filename, linenum); | 640 | filename, linenum); |
637 | options->subsystem_command[options->num_subsystems] = xstrdup(cp); | 641 | options->subsystem_command[options->num_subsystems] = xstrdup(arg); |
638 | options->num_subsystems++; | 642 | options->num_subsystems++; |
639 | break; | 643 | break; |
640 | 644 | ||
645 | case sMaxStartups: | ||
646 | intptr = &options->max_startups; | ||
647 | goto parse_int; | ||
648 | |||
641 | default: | 649 | default: |
642 | fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", | 650 | fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", |
643 | filename, linenum, cp, opcode); | 651 | filename, linenum, arg, opcode); |
644 | exit(1); | 652 | exit(1); |
645 | } | 653 | } |
646 | if (strtok(NULL, WHITESPACE) != NULL) { | 654 | if ((arg = strsep(&cp, WHITESPACE)) != NULL && *arg != '\0') { |
647 | fprintf(stderr, "%s line %d: garbage at end of line.\n", | 655 | fprintf(stderr, |
648 | filename, linenum); | 656 | "%s line %d: garbage at end of line; \"%.200s\".\n", |
657 | filename, linenum, arg); | ||
649 | exit(1); | 658 | exit(1); |
650 | } | 659 | } |
651 | } | 660 | } |
diff --git a/servconf.h b/servconf.h index c698bc74e..95593722d 100644 --- a/servconf.h +++ b/servconf.h | |||
@@ -13,7 +13,7 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | /* RCSID("$OpenBSD: servconf.h,v 1.25 2000/06/20 01:39:44 markus Exp $"); */ | 16 | /* RCSID("$OpenBSD: servconf.h,v 1.26 2000/06/26 21:59:18 markus Exp $"); */ |
17 | 17 | ||
18 | #ifndef SERVCONF_H | 18 | #ifndef SERVCONF_H |
19 | #define SERVCONF_H | 19 | #define SERVCONF_H |
@@ -99,6 +99,9 @@ typedef struct { | |||
99 | unsigned int num_subsystems; | 99 | unsigned int num_subsystems; |
100 | char *subsystem_name[MAX_SUBSYSTEMS]; | 100 | char *subsystem_name[MAX_SUBSYSTEMS]; |
101 | char *subsystem_command[MAX_SUBSYSTEMS]; | 101 | char *subsystem_command[MAX_SUBSYSTEMS]; |
102 | |||
103 | int max_startups; | ||
104 | |||
102 | } ServerOptions; | 105 | } ServerOptions; |
103 | /* | 106 | /* |
104 | * Initializes the server options to special values that indicate that they | 107 | * Initializes the server options to special values that indicate that they |
diff --git a/serverloop.c b/serverloop.c index 311a285c3..00617bb81 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -722,7 +722,7 @@ input_direct_tcpip(void) | |||
722 | originator, originator_port, target, target_port); | 722 | originator, originator_port, target, target_port); |
723 | 723 | ||
724 | /* XXX check permission */ | 724 | /* XXX check permission */ |
725 | if (! no_port_forwarding_flag) { | 725 | if (no_port_forwarding_flag) { |
726 | xfree(target); | 726 | xfree(target); |
727 | xfree(originator); | 727 | xfree(originator); |
728 | return -1; | 728 | return -1; |
@@ -8,10 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "includes.h" | 10 | #include "includes.h" |
11 | RCSID("$OpenBSD: session.c,v 1.20 2000/06/18 04:42:54 markus Exp $"); | 11 | RCSID("$OpenBSD: session.c,v 1.22 2000/07/05 20:18:07 deraadt Exp $"); |
12 | #if defined(HAVE_USERSEC_H) | ||
13 | #include <usersec.h> | ||
14 | #endif | ||
15 | 12 | ||
16 | #include "xmalloc.h" | 13 | #include "xmalloc.h" |
17 | #include "ssh.h" | 14 | #include "ssh.h" |
@@ -35,6 +32,10 @@ RCSID("$OpenBSD: session.c,v 1.20 2000/06/18 04:42:54 markus Exp $"); | |||
35 | #include <proj.h> | 32 | #include <proj.h> |
36 | #endif /* WITH_IRIX_PROJECT */ | 33 | #endif /* WITH_IRIX_PROJECT */ |
37 | 34 | ||
35 | #if defined(HAVE_USERSEC_H) | ||
36 | #include <usersec.h> | ||
37 | #endif | ||
38 | |||
38 | #ifdef HAVE_OSF_SIA | 39 | #ifdef HAVE_OSF_SIA |
39 | # include <sia.h> | 40 | # include <sia.h> |
40 | # include <siad.h> | 41 | # include <siad.h> |
@@ -90,6 +91,8 @@ static const char *__progname = "sshd"; | |||
90 | extern int log_stderr; | 91 | extern int log_stderr; |
91 | extern int debug_flag; | 92 | extern int debug_flag; |
92 | 93 | ||
94 | extern int startup_pipe; | ||
95 | |||
93 | /* Local Xauthority file. */ | 96 | /* Local Xauthority file. */ |
94 | static char *xauthfile; | 97 | static char *xauthfile; |
95 | 98 | ||
@@ -166,6 +169,7 @@ do_authenticated(struct passwd * pw) | |||
166 | * authentication. | 169 | * authentication. |
167 | */ | 170 | */ |
168 | alarm(0); | 171 | alarm(0); |
172 | close(startup_pipe); | ||
169 | 173 | ||
170 | /* | 174 | /* |
171 | * Inform the channel mechanism that we are the server side and that | 175 | * Inform the channel mechanism that we are the server side and that |
@@ -1457,7 +1461,7 @@ session_subsystem_req(Session *s) | |||
1457 | int | 1461 | int |
1458 | session_x11_req(Session *s) | 1462 | session_x11_req(Session *s) |
1459 | { | 1463 | { |
1460 | if (!no_port_forwarding_flag) { | 1464 | if (no_x11_forwarding_flag) { |
1461 | debug("X11 forwarding disabled in user configuration file."); | 1465 | debug("X11 forwarding disabled in user configuration file."); |
1462 | return 0; | 1466 | return 0; |
1463 | } | 1467 | } |
@@ -1788,6 +1792,7 @@ do_authenticated2(void) | |||
1788 | * authentication. | 1792 | * authentication. |
1789 | */ | 1793 | */ |
1790 | alarm(0); | 1794 | alarm(0); |
1795 | close(startup_pipe); | ||
1791 | server_loop2(); | 1796 | server_loop2(); |
1792 | if (xauthfile) | 1797 | if (xauthfile) |
1793 | xauthfile_cleanup_proc(NULL); | 1798 | xauthfile_cleanup_proc(NULL); |
diff --git a/ssh-agent.1 b/ssh-agent.1 index 66a475692..47b1e5cc5 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: ssh-agent.1,v 1.12 2000/05/03 18:04:39 markus Exp $ | 1 | .\" $OpenBSD: ssh-agent.1,v 1.13 2000/07/06 04:06:56 aaron Exp $ |
2 | .\" | 2 | .\" |
3 | .\" -*- nroff -*- | 3 | .\" -*- nroff -*- |
4 | .\" | 4 | .\" |
@@ -133,6 +133,7 @@ Unix-domain sockets used to contain the connection to the | |||
133 | authentication agent. | 133 | authentication agent. |
134 | These sockets should only be readable by the owner. | 134 | These sockets should only be readable by the owner. |
135 | The sockets should get automatically removed when the agent exits. | 135 | The sockets should get automatically removed when the agent exits. |
136 | .El | ||
136 | .Sh AUTHOR | 137 | .Sh AUTHOR |
137 | Tatu Ylonen <ylo@cs.hut.fi> | 138 | Tatu Ylonen <ylo@cs.hut.fi> |
138 | .Pp | 139 | .Pp |
diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 9a32ad859..02f52ec65 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.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-keygen.1,v 1.15 2000/05/09 01:03:02 damien Exp $ | 12 | .\" $Id: ssh-keygen.1,v 1.16 2000/07/11 07:31:38 djm Exp $ |
13 | .\" | 13 | .\" |
14 | .Dd September 25, 1999 | 14 | .Dd September 25, 1999 |
15 | .Dt SSH-KEYGEN 1 | 15 | .Dt SSH-KEYGEN 1 |
@@ -188,6 +188,7 @@ The contents of this file should be added to | |||
188 | on all machines | 188 | on all machines |
189 | where you wish to log in using DSA authentication. | 189 | where you wish to log in using DSA authentication. |
190 | There is no need to keep the contents of this file secret. | 190 | There is no need to keep the contents of this file secret. |
191 | .El | ||
191 | .Sh AUTHOR | 192 | .Sh AUTHOR |
192 | Tatu Ylonen <ylo@cs.hut.fi> | 193 | Tatu Ylonen <ylo@cs.hut.fi> |
193 | .Pp | 194 | .Pp |
diff --git a/ssh-keygen.c b/ssh-keygen.c index dbd0443fc..b38ebfb91 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" |
10 | RCSID("$OpenBSD: ssh-keygen.c,v 1.27 2000/06/20 01:39:44 markus Exp $"); | 10 | RCSID("$OpenBSD: ssh-keygen.c,v 1.28 2000/07/07 03:55:04 todd Exp $"); |
11 | 11 | ||
12 | #include <openssl/evp.h> | 12 | #include <openssl/evp.h> |
13 | #include <openssl/pem.h> | 13 | #include <openssl/pem.h> |
@@ -127,13 +127,13 @@ do_convert_to_ssh2(struct passwd *pw) | |||
127 | exit(1); | 127 | exit(1); |
128 | } | 128 | } |
129 | dsa_make_key_blob(k, &blob, &len); | 129 | dsa_make_key_blob(k, &blob, &len); |
130 | fprintf(stdout, SSH_COM_MAGIC_BEGIN "\n"); | 130 | fprintf(stdout, "%s\n", SSH_COM_MAGIC_BEGIN); |
131 | fprintf(stdout, | 131 | fprintf(stdout, |
132 | "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n", | 132 | "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n", |
133 | BN_num_bits(k->dsa->p), | 133 | BN_num_bits(k->dsa->p), |
134 | pw->pw_name, hostname); | 134 | pw->pw_name, hostname); |
135 | dump_base64(stdout, blob, len); | 135 | dump_base64(stdout, blob, len); |
136 | fprintf(stdout, SSH_COM_MAGIC_END "\n"); | 136 | fprintf(stdout, "%s\n", SSH_COM_MAGIC_END); |
137 | key_free(k); | 137 | key_free(k); |
138 | xfree(blob); | 138 | xfree(blob); |
139 | exit(0); | 139 | exit(0); |
@@ -9,7 +9,7 @@ | |||
9 | .\" | 9 | .\" |
10 | .\" Created: Sat Apr 22 21:55:14 1995 ylo | 10 | .\" Created: Sat Apr 22 21:55:14 1995 ylo |
11 | .\" | 11 | .\" |
12 | .\" $Id: sshd.8,v 1.24 2000/06/18 04:50:45 djm Exp $ | 12 | .\" $Id: sshd.8,v 1.25 2000/07/11 07:31:39 djm Exp $ |
13 | .\" | 13 | .\" |
14 | .Dd September 25, 1999 | 14 | .Dd September 25, 1999 |
15 | .Dt SSHD 8 | 15 | .Dt SSHD 8 |
@@ -435,6 +435,14 @@ QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. | |||
435 | The default is INFO. | 435 | The default is INFO. |
436 | Logging with level DEBUG violates the privacy of users | 436 | Logging with level DEBUG violates the privacy of users |
437 | and is not recommended. | 437 | and is not recommended. |
438 | .It Cm MaxStartups | ||
439 | Specifies the maximum number of concurrent unauthenticated connections to the | ||
440 | .Nm | ||
441 | daemon. | ||
442 | Additional connections will be dropped until authentication succeeds or the | ||
443 | .Cm LoginGraceTime | ||
444 | expires for a connection. | ||
445 | The default is 10. | ||
438 | .It Cm PasswordAuthentication | 446 | .It Cm PasswordAuthentication |
439 | Specifies whether password authentication is allowed. | 447 | Specifies whether password authentication is allowed. |
440 | The default is | 448 | The default is |
@@ -954,6 +962,7 @@ Like | |||
954 | This can be used to specify | 962 | This can be used to specify |
955 | machine-specific login-time initializations globally. | 963 | machine-specific login-time initializations globally. |
956 | This file should be writable only by root, and should be world-readable. | 964 | This file should be writable only by root, and should be world-readable. |
965 | .El | ||
957 | .Sh AUTHOR | 966 | .Sh AUTHOR |
958 | OpenSSH | 967 | OpenSSH |
959 | is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, | 968 | is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, |
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$OpenBSD: sshd.c,v 1.119 2000/06/22 16:32:27 markus Exp $"); | 17 | RCSID("$OpenBSD: sshd.c,v 1.121 2000/07/05 21:35:56 provos Exp $"); |
18 | 18 | ||
19 | #include "xmalloc.h" | 19 | #include "xmalloc.h" |
20 | #include "rsa.h" | 20 | #include "rsa.h" |
@@ -350,7 +350,7 @@ sshd_exchange_identification(int sock_in, int sock_out) | |||
350 | break; | 350 | break; |
351 | } | 351 | } |
352 | if (remote_minor < 3) { | 352 | if (remote_minor < 3) { |
353 | packet_disconnect("Your ssh version is too old and" | 353 | packet_disconnect("Your ssh version is too old and " |
354 | "is no longer supported. Please install a newer version."); | 354 | "is no longer supported. Please install a newer version."); |
355 | } else if (remote_minor == 3) { | 355 | } else if (remote_minor == 3) { |
356 | /* note that this disables agent-forwarding */ | 356 | /* note that this disables agent-forwarding */ |
@@ -400,6 +400,9 @@ destroy_sensitive_data(void) | |||
400 | key_free(sensitive_data.dsa_host_key); | 400 | key_free(sensitive_data.dsa_host_key); |
401 | } | 401 | } |
402 | 402 | ||
403 | int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */ | ||
404 | int startup_pipe; /* in child */ | ||
405 | |||
403 | /* | 406 | /* |
404 | * Main program for the daemon. | 407 | * Main program for the daemon. |
405 | */ | 408 | */ |
@@ -408,7 +411,7 @@ main(int ac, char **av) | |||
408 | { | 411 | { |
409 | extern char *optarg; | 412 | extern char *optarg; |
410 | extern int optind; | 413 | extern int optind; |
411 | int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, on = 1; | 414 | int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1; |
412 | pid_t pid; | 415 | pid_t pid; |
413 | socklen_t fromlen; | 416 | socklen_t fromlen; |
414 | int silent = 0; | 417 | int silent = 0; |
@@ -421,6 +424,8 @@ main(int ac, char **av) | |||
421 | struct addrinfo *ai; | 424 | struct addrinfo *ai; |
422 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 425 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
423 | int listen_sock, maxfd; | 426 | int listen_sock, maxfd; |
427 | int startup_p[2]; | ||
428 | int startups = 0; | ||
424 | 429 | ||
425 | init_rng(); | 430 | init_rng(); |
426 | 431 | ||
@@ -746,6 +751,7 @@ main(int ac, char **av) | |||
746 | 751 | ||
747 | /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ | 752 | /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ |
748 | signal(SIGHUP, sighup_handler); | 753 | signal(SIGHUP, sighup_handler); |
754 | |||
749 | signal(SIGTERM, sigterm_handler); | 755 | signal(SIGTERM, sigterm_handler); |
750 | signal(SIGQUIT, sigterm_handler); | 756 | signal(SIGQUIT, sigterm_handler); |
751 | 757 | ||
@@ -753,12 +759,15 @@ main(int ac, char **av) | |||
753 | signal(SIGCHLD, main_sigchld_handler); | 759 | signal(SIGCHLD, main_sigchld_handler); |
754 | 760 | ||
755 | /* setup fd set for listen */ | 761 | /* setup fd set for listen */ |
762 | fdset = NULL; | ||
756 | maxfd = 0; | 763 | maxfd = 0; |
757 | for (i = 0; i < num_listen_socks; i++) | 764 | for (i = 0; i < num_listen_socks; i++) |
758 | if (listen_socks[i] > maxfd) | 765 | if (listen_socks[i] > maxfd) |
759 | maxfd = listen_socks[i]; | 766 | maxfd = listen_socks[i]; |
760 | fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask); | 767 | /* pipes connected to unauthenticated childs */ |
761 | fdset = (fd_set *)xmalloc(fdsetsz); | 768 | startup_pipes = xmalloc(options.max_startups * sizeof(int)); |
769 | for (i = 0; i < options.max_startups; i++) | ||
770 | startup_pipes[i] = -1; | ||
762 | 771 | ||
763 | /* | 772 | /* |
764 | * Stay listening for connections until the system crashes or | 773 | * Stay listening for connections until the system crashes or |
@@ -767,80 +776,128 @@ main(int ac, char **av) | |||
767 | for (;;) { | 776 | for (;;) { |
768 | if (received_sighup) | 777 | if (received_sighup) |
769 | sighup_restart(); | 778 | sighup_restart(); |
770 | /* Wait in select until there is a connection. */ | 779 | if (fdset != NULL) |
780 | xfree(fdset); | ||
781 | fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask); | ||
782 | fdset = (fd_set *)xmalloc(fdsetsz); | ||
771 | memset(fdset, 0, fdsetsz); | 783 | memset(fdset, 0, fdsetsz); |
784 | |||
772 | for (i = 0; i < num_listen_socks; i++) | 785 | for (i = 0; i < num_listen_socks; i++) |
773 | FD_SET(listen_socks[i], fdset); | 786 | FD_SET(listen_socks[i], fdset); |
787 | for (i = 0; i < options.max_startups; i++) | ||
788 | if (startup_pipes[i] != -1) | ||
789 | FD_SET(startup_pipes[i], fdset); | ||
790 | |||
791 | /* Wait in select until there is a connection. */ | ||
774 | if (select(maxfd + 1, fdset, NULL, NULL, NULL) < 0) { | 792 | if (select(maxfd + 1, fdset, NULL, NULL, NULL) < 0) { |
775 | if (errno != EINTR) | 793 | if (errno != EINTR) |
776 | error("select: %.100s", strerror(errno)); | 794 | error("select: %.100s", strerror(errno)); |
777 | continue; | 795 | continue; |
778 | } | 796 | } |
797 | for (i = 0; i < options.max_startups; i++) | ||
798 | if (startup_pipes[i] != -1 && | ||
799 | FD_ISSET(startup_pipes[i], fdset)) { | ||
800 | /* | ||
801 | * the read end of the pipe is ready | ||
802 | * if the child has closed the pipe | ||
803 | * after successfull authentication | ||
804 | * or if the child has died | ||
805 | */ | ||
806 | close(startup_pipes[i]); | ||
807 | startup_pipes[i] = -1; | ||
808 | startups--; | ||
809 | } | ||
779 | for (i = 0; i < num_listen_socks; i++) { | 810 | for (i = 0; i < num_listen_socks; i++) { |
780 | if (!FD_ISSET(listen_socks[i], fdset)) | 811 | if (!FD_ISSET(listen_socks[i], fdset)) |
781 | continue; | 812 | continue; |
782 | fromlen = sizeof(from); | 813 | fromlen = sizeof(from); |
783 | newsock = accept(listen_socks[i], (struct sockaddr *)&from, | 814 | newsock = accept(listen_socks[i], (struct sockaddr *)&from, |
784 | &fromlen); | 815 | &fromlen); |
785 | if (newsock < 0) { | 816 | if (newsock < 0) { |
786 | if (errno != EINTR && errno != EWOULDBLOCK) | 817 | if (errno != EINTR && errno != EWOULDBLOCK) |
787 | error("accept: %.100s", strerror(errno)); | 818 | error("accept: %.100s", strerror(errno)); |
788 | continue; | 819 | continue; |
789 | } | 820 | } |
790 | if (fcntl(newsock, F_SETFL, 0) < 0) { | 821 | if (fcntl(newsock, F_SETFL, 0) < 0) { |
791 | error("newsock del O_NONBLOCK: %s", strerror(errno)); | 822 | error("newsock del O_NONBLOCK: %s", strerror(errno)); |
792 | continue; | 823 | continue; |
793 | } | 824 | } |
794 | /* | 825 | if (startups >= options.max_startups) { |
795 | * Got connection. Fork a child to handle it, unless | 826 | close(newsock); |
796 | * we are in debugging mode. | 827 | continue; |
797 | */ | 828 | } |
798 | if (debug_flag) { | 829 | if (pipe(startup_p) == -1) { |
799 | /* | 830 | close(newsock); |
800 | * In debugging mode. Close the listening | 831 | continue; |
801 | * socket, and start processing the | 832 | } |
802 | * connection without forking. | 833 | |
803 | */ | 834 | for (j = 0; j < options.max_startups; j++) |
804 | debug("Server will not fork when running in debugging mode."); | 835 | if (startup_pipes[j] == -1) { |
805 | close_listen_socks(); | 836 | startup_pipes[j] = startup_p[0]; |
806 | sock_in = newsock; | 837 | if (maxfd < startup_p[0]) |
807 | sock_out = newsock; | 838 | maxfd = startup_p[0]; |
808 | pid = getpid(); | 839 | startups++; |
809 | break; | 840 | break; |
810 | } else { | 841 | } |
842 | |||
811 | /* | 843 | /* |
812 | * Normal production daemon. Fork, and have | 844 | * Got connection. Fork a child to handle it, unless |
813 | * the child process the connection. The | 845 | * we are in debugging mode. |
814 | * parent continues listening. | ||
815 | */ | 846 | */ |
816 | if ((pid = fork()) == 0) { | 847 | if (debug_flag) { |
817 | /* | 848 | /* |
818 | * Child. Close the listening socket, and start using the | 849 | * In debugging mode. Close the listening |
819 | * accepted socket. Reinitialize logging (since our pid has | 850 | * socket, and start processing the |
820 | * changed). We break out of the loop to handle the connection. | 851 | * connection without forking. |
821 | */ | 852 | */ |
853 | debug("Server will not fork when running in debugging mode."); | ||
822 | close_listen_socks(); | 854 | close_listen_socks(); |
823 | sock_in = newsock; | 855 | sock_in = newsock; |
824 | sock_out = newsock; | 856 | sock_out = newsock; |
825 | log_init(av0, options.log_level, options.log_facility, log_stderr); | 857 | pid = getpid(); |
826 | break; | 858 | break; |
859 | } else { | ||
860 | /* | ||
861 | * Normal production daemon. Fork, and have | ||
862 | * the child process the connection. The | ||
863 | * parent continues listening. | ||
864 | */ | ||
865 | if ((pid = fork()) == 0) { | ||
866 | /* | ||
867 | * Child. Close the listening and max_startup | ||
868 | * sockets. Start using the accepted socket. | ||
869 | * Reinitialize logging (since our pid has | ||
870 | * changed). We break out of the loop to handle | ||
871 | * the connection. | ||
872 | */ | ||
873 | startup_pipe = startup_p[1]; | ||
874 | for (j = 0; j < options.max_startups; j++) | ||
875 | if (startup_pipes[j] != -1) | ||
876 | close(startup_pipes[j]); | ||
877 | close_listen_socks(); | ||
878 | sock_in = newsock; | ||
879 | sock_out = newsock; | ||
880 | log_init(av0, options.log_level, options.log_facility, log_stderr); | ||
881 | break; | ||
882 | } | ||
827 | } | 883 | } |
828 | } | ||
829 | 884 | ||
830 | /* Parent. Stay in the loop. */ | 885 | /* Parent. Stay in the loop. */ |
831 | if (pid < 0) | 886 | if (pid < 0) |
832 | error("fork: %.100s", strerror(errno)); | 887 | error("fork: %.100s", strerror(errno)); |
833 | else | 888 | else |
834 | debug("Forked child %d.", pid); | 889 | debug("Forked child %d.", pid); |
835 | 890 | ||
836 | /* Mark that the key has been used (it was "given" to the child). */ | 891 | close(startup_p[1]); |
837 | key_used = 1; | ||
838 | 892 | ||
839 | arc4random_stir(); | 893 | /* Mark that the key has been used (it was "given" to the child). */ |
894 | key_used = 1; | ||
840 | 895 | ||
841 | /* Close the new socket (the child is now taking care of it). */ | 896 | arc4random_stir(); |
842 | close(newsock); | 897 | |
843 | } /* for (i = 0; i < num_listen_socks; i++) */ | 898 | /* Close the new socket (the child is now taking care of it). */ |
899 | close(newsock); | ||
900 | } | ||
844 | /* child process check (or debug mode) */ | 901 | /* child process check (or debug mode) */ |
845 | if (num_listen_socks < 0) | 902 | if (num_listen_socks < 0) |
846 | break; | 903 | break; |