summaryrefslogtreecommitdiff
path: root/servconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'servconf.c')
-rw-r--r--servconf.c137
1 files changed, 73 insertions, 64 deletions
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"
15RCSID("$OpenBSD: servconf.c,v 1.45 2000/06/20 01:39:44 markus Exp $"); 15RCSID("$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
81void 82void
@@ -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;
345parse_int: 349parse_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;
377parse_filename: 381parse_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;
423parse_flag: 427parse_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 }