summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-10-15 12:14:12 +1100
committerDamien Miller <djm@mindrot.org>2013-10-15 12:14:12 +1100
commite9fc72edd6c313b670558cd5219601c38a949b67 (patch)
tree32ed93978e93622d5829a55cbc0479e00b1161bf /readconf.c
parent194fd904d8597a274b93e075b2047afdf5a175d4 (diff)
- djm@cvs.openbsd.org 2013/10/14 23:28:23
[canohost.c misc.c misc.h readconf.c sftp-server.c ssh.c] refactor client config code a little: add multistate option partsing to readconf.c, similar to servconf.c's existing code. move checking of options that accept "none" as an argument to readconf.c add a lowercase() function and use it instead of explicit tolower() in loops part of a larger diff that was ok markus@
Diffstat (limited to 'readconf.c')
-rw-r--r--readconf.c199
1 files changed, 95 insertions, 104 deletions
diff --git a/readconf.c b/readconf.c
index f7b912ef6..9340effd0 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.206 2013/10/14 22:22:02 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.207 2013/10/14 23:28:23 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -555,6 +555,61 @@ parse_token(const char *cp, const char *filename, int linenum,
555 return oBadOption; 555 return oBadOption;
556} 556}
557 557
558/* Multistate option parsing */
559struct multistate {
560 char *key;
561 int value;
562};
563static const struct multistate multistate_flag[] = {
564 { "true", 1 },
565 { "false", 0 },
566 { "yes", 1 },
567 { "no", 0 },
568 { NULL, -1 }
569};
570static const struct multistate multistate_yesnoask[] = {
571 { "true", 1 },
572 { "false", 0 },
573 { "yes", 1 },
574 { "no", 0 },
575 { "ask", 2 },
576 { NULL, -1 }
577};
578static const struct multistate multistate_addressfamily[] = {
579 { "inet", AF_INET },
580 { "inet6", AF_INET6 },
581 { "any", AF_UNSPEC },
582 { NULL, -1 }
583};
584static const struct multistate multistate_controlmaster[] = {
585 { "true", SSHCTL_MASTER_YES },
586 { "yes", SSHCTL_MASTER_YES },
587 { "false", SSHCTL_MASTER_NO },
588 { "no", SSHCTL_MASTER_NO },
589 { "auto", SSHCTL_MASTER_AUTO },
590 { "ask", SSHCTL_MASTER_ASK },
591 { "autoask", SSHCTL_MASTER_AUTO_ASK },
592 { NULL, -1 }
593};
594static const struct multistate multistate_tunnel[] = {
595 { "ethernet", SSH_TUNMODE_ETHERNET },
596 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
597 { "true", SSH_TUNMODE_DEFAULT },
598 { "yes", SSH_TUNMODE_DEFAULT },
599 { "false", SSH_TUNMODE_NO },
600 { "no", SSH_TUNMODE_NO },
601 { NULL, -1 }
602};
603static const struct multistate multistate_requesttty[] = {
604 { "true", REQUEST_TTY_YES },
605 { "yes", REQUEST_TTY_YES },
606 { "false", REQUEST_TTY_NO },
607 { "no", REQUEST_TTY_NO },
608 { "force", REQUEST_TTY_FORCE },
609 { "auto", REQUEST_TTY_AUTO },
610 { NULL, -1 }
611};
612
558/* 613/*
559 * Processes a single option line as used in the configuration files. This 614 * Processes a single option line as used in the configuration files. This
560 * only sets those values that have not already been set. 615 * only sets those values that have not already been set.
@@ -572,6 +627,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
572 long long val64; 627 long long val64;
573 size_t len; 628 size_t len;
574 Forward fwd; 629 Forward fwd;
630 const struct multistate *multistate_ptr;
575 631
576 if (activep == NULL) { /* We are processing a command line directive */ 632 if (activep == NULL) { /* We are processing a command line directive */
577 cmdline = 1; 633 cmdline = 1;
@@ -595,8 +651,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
595 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 651 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
596 return 0; 652 return 0;
597 /* Match lowercase keyword */ 653 /* Match lowercase keyword */
598 for (i = 0; i < strlen(keyword); i++) 654 lowercase(keyword);
599 keyword[i] = tolower(keyword[i]);
600 655
601 opcode = parse_token(keyword, filename, linenum, 656 opcode = parse_token(keyword, filename, linenum,
602 options->ignored_unknown); 657 options->ignored_unknown);
@@ -626,17 +681,23 @@ parse_time:
626 681
627 case oForwardAgent: 682 case oForwardAgent:
628 intptr = &options->forward_agent; 683 intptr = &options->forward_agent;
629parse_flag: 684 parse_flag:
685 multistate_ptr = multistate_flag;
686 parse_multistate:
630 arg = strdelim(&s); 687 arg = strdelim(&s);
631 if (!arg || *arg == '\0') 688 if (!arg || *arg == '\0')
632 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 689 fatal("%s line %d: missing argument.",
633 value = 0; /* To avoid compiler warning... */ 690 filename, linenum);
634 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 691 value = -1;
635 value = 1; 692 for (i = 0; multistate_ptr[i].key != NULL; i++) {
636 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 693 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
637 value = 0; 694 value = multistate_ptr[i].value;
638 else 695 break;
639 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 696 }
697 }
698 if (value == -1)
699 fatal("%s line %d: unsupported option \"%s\".",
700 filename, linenum, arg);
640 if (*activep && *intptr == -1) 701 if (*activep && *intptr == -1)
641 *intptr = value; 702 *intptr = value;
642 break; 703 break;
@@ -719,27 +780,13 @@ parse_flag:
719 780
720 case oVerifyHostKeyDNS: 781 case oVerifyHostKeyDNS:
721 intptr = &options->verify_host_key_dns; 782 intptr = &options->verify_host_key_dns;
722 goto parse_yesnoask; 783 multistate_ptr = multistate_yesnoask;
784 goto parse_multistate;
723 785
724 case oStrictHostKeyChecking: 786 case oStrictHostKeyChecking:
725 intptr = &options->strict_host_key_checking; 787 intptr = &options->strict_host_key_checking;
726parse_yesnoask: 788 multistate_ptr = multistate_yesnoask;
727 arg = strdelim(&s); 789 goto parse_multistate;
728 if (!arg || *arg == '\0')
729 fatal("%.200s line %d: Missing yes/no/ask argument.",
730 filename, linenum);
731 value = 0; /* To avoid compiler warning... */
732 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
733 value = 1;
734 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
735 value = 0;
736 else if (strcmp(arg, "ask") == 0)
737 value = 2;
738 else
739 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
740 if (*activep && *intptr == -1)
741 *intptr = value;
742 break;
743 790
744 case oCompression: 791 case oCompression:
745 intptr = &options->compression; 792 intptr = &options->compression;
@@ -1080,22 +1127,9 @@ parse_int:
1080 break; 1127 break;
1081 1128
1082 case oAddressFamily: 1129 case oAddressFamily:
1083 arg = strdelim(&s);
1084 if (!arg || *arg == '\0')
1085 fatal("%s line %d: missing address family.",
1086 filename, linenum);
1087 intptr = &options->address_family; 1130 intptr = &options->address_family;
1088 if (strcasecmp(arg, "inet") == 0) 1131 multistate_ptr = multistate_addressfamily;
1089 value = AF_INET; 1132 goto parse_multistate;
1090 else if (strcasecmp(arg, "inet6") == 0)
1091 value = AF_INET6;
1092 else if (strcasecmp(arg, "any") == 0)
1093 value = AF_UNSPEC;
1094 else
1095 fatal("Unsupported AddressFamily \"%s\"", arg);
1096 if (*activep && *intptr == -1)
1097 *intptr = value;
1098 break;
1099 1133
1100 case oEnableSSHKeysign: 1134 case oEnableSSHKeysign:
1101 intptr = &options->enable_ssh_keysign; 1135 intptr = &options->enable_ssh_keysign;
@@ -1134,27 +1168,8 @@ parse_int:
1134 1168
1135 case oControlMaster: 1169 case oControlMaster:
1136 intptr = &options->control_master; 1170 intptr = &options->control_master;
1137 arg = strdelim(&s); 1171 multistate_ptr = multistate_controlmaster;
1138 if (!arg || *arg == '\0') 1172 goto parse_multistate;
1139 fatal("%.200s line %d: Missing ControlMaster argument.",
1140 filename, linenum);
1141 value = 0; /* To avoid compiler warning... */
1142 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1143 value = SSHCTL_MASTER_YES;
1144 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1145 value = SSHCTL_MASTER_NO;
1146 else if (strcmp(arg, "auto") == 0)
1147 value = SSHCTL_MASTER_AUTO;
1148 else if (strcmp(arg, "ask") == 0)
1149 value = SSHCTL_MASTER_ASK;
1150 else if (strcmp(arg, "autoask") == 0)
1151 value = SSHCTL_MASTER_AUTO_ASK;
1152 else
1153 fatal("%.200s line %d: Bad ControlMaster argument.",
1154 filename, linenum);
1155 if (*activep && *intptr == -1)
1156 *intptr = value;
1157 break;
1158 1173
1159 case oControlPersist: 1174 case oControlPersist:
1160 /* no/false/yes/true, or a time spec */ 1175 /* no/false/yes/true, or a time spec */
@@ -1186,25 +1201,8 @@ parse_int:
1186 1201
1187 case oTunnel: 1202 case oTunnel:
1188 intptr = &options->tun_open; 1203 intptr = &options->tun_open;
1189 arg = strdelim(&s); 1204 multistate_ptr = multistate_tunnel;
1190 if (!arg || *arg == '\0') 1205 goto parse_multistate;
1191 fatal("%s line %d: Missing yes/point-to-point/"
1192 "ethernet/no argument.", filename, linenum);
1193 value = 0; /* silence compiler */
1194 if (strcasecmp(arg, "ethernet") == 0)
1195 value = SSH_TUNMODE_ETHERNET;
1196 else if (strcasecmp(arg, "point-to-point") == 0)
1197 value = SSH_TUNMODE_POINTOPOINT;
1198 else if (strcasecmp(arg, "yes") == 0)
1199 value = SSH_TUNMODE_DEFAULT;
1200 else if (strcasecmp(arg, "no") == 0)
1201 value = SSH_TUNMODE_NO;
1202 else
1203 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1204 "no argument: %s", filename, linenum, arg);
1205 if (*activep)
1206 *intptr = value;
1207 break;
1208 1206
1209 case oTunnelDevice: 1207 case oTunnelDevice:
1210 arg = strdelim(&s); 1208 arg = strdelim(&s);
@@ -1253,24 +1251,9 @@ parse_int:
1253 goto parse_flag; 1251 goto parse_flag;
1254 1252
1255 case oRequestTTY: 1253 case oRequestTTY:
1256 arg = strdelim(&s);
1257 if (!arg || *arg == '\0')
1258 fatal("%s line %d: missing argument.",
1259 filename, linenum);
1260 intptr = &options->request_tty; 1254 intptr = &options->request_tty;
1261 if (strcasecmp(arg, "yes") == 0) 1255 multistate_ptr = multistate_requesttty;
1262 value = REQUEST_TTY_YES; 1256 goto parse_multistate;
1263 else if (strcasecmp(arg, "no") == 0)
1264 value = REQUEST_TTY_NO;
1265 else if (strcasecmp(arg, "force") == 0)
1266 value = REQUEST_TTY_FORCE;
1267 else if (strcasecmp(arg, "auto") == 0)
1268 value = REQUEST_TTY_AUTO;
1269 else
1270 fatal("Unsupported RequestTTY \"%s\"", arg);
1271 if (*activep && *intptr == -1)
1272 *intptr = value;
1273 break;
1274 1257
1275 case oIgnoreUnknown: 1258 case oIgnoreUnknown:
1276 charptr = &options->ignored_unknown; 1259 charptr = &options->ignored_unknown;
@@ -1596,8 +1579,16 @@ fill_default_options(Options * options)
1596 options->request_tty = REQUEST_TTY_AUTO; 1579 options->request_tty = REQUEST_TTY_AUTO;
1597 if (options->proxy_use_fdpass == -1) 1580 if (options->proxy_use_fdpass == -1)
1598 options->proxy_use_fdpass = 0; 1581 options->proxy_use_fdpass = 0;
1599 /* options->local_command should not be set by default */ 1582#define CLEAR_ON_NONE(v) \
1600 /* options->proxy_command should not be set by default */ 1583 do { \
1584 if (v != NULL && strcasecmp(v, "none") == 0) { \
1585 free(v); \
1586 v = NULL; \
1587 } \
1588 } while(0)
1589 CLEAR_ON_NONE(options->local_command);
1590 CLEAR_ON_NONE(options->proxy_command);
1591 CLEAR_ON_NONE(options->control_path);
1601 /* options->user will be set in the main program if appropriate */ 1592 /* options->user will be set in the main program if appropriate */
1602 /* options->hostname will be set in the main program if appropriate */ 1593 /* options->hostname will be set in the main program if appropriate */
1603 /* options->host_key_alias should not be set by default */ 1594 /* options->host_key_alias should not be set by default */