View | Details | Raw Unified | Return to bug 3288 | Differences between
and this patch

Collapse All | Expand All

(-)a/auth2-pubkey.c (-2 / +3 lines)
Lines 472-478 match_principals_command(struct ssh *ssh, struct passwd *user_pw, Link Here
472
	}
472
	}
473
473
474
	/* Turn the command into an argument vector */
474
	/* Turn the command into an argument vector */
475
	if (argv_split(options.authorized_principals_command, &ac, &av) != 0) {
475
	if (argv_split(options.authorized_principals_command,
476
	    &ac, &av, 0) != 0) {
476
		error("AuthorizedPrincipalsCommand \"%s\" contains "
477
		error("AuthorizedPrincipalsCommand \"%s\" contains "
477
		    "invalid quotes", options.authorized_principals_command);
478
		    "invalid quotes", options.authorized_principals_command);
478
		goto out;
479
		goto out;
Lines 923-929 user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw, Link Here
923
	}
924
	}
924
925
925
	/* Turn the command into an argument vector */
926
	/* Turn the command into an argument vector */
926
	if (argv_split(options.authorized_keys_command, &ac, &av) != 0) {
927
	if (argv_split(options.authorized_keys_command, &ac, &av, 0) != 0) {
927
		error("AuthorizedKeysCommand \"%s\" contains invalid quotes",
928
		error("AuthorizedKeysCommand \"%s\" contains invalid quotes",
928
		    options.authorized_keys_command);
929
		    options.authorized_keys_command);
929
		goto out;
930
		goto out;
(-)a/misc.c (-4 / +5 lines)
Lines 1823-1836 daemonized(void) Link Here
1823
	return 1;
1823
	return 1;
1824
}
1824
}
1825
1825
1826
1827
/*
1826
/*
1828
 * Splits 's' into an argument vector. Handles quoted string and basic
1827
 * Splits 's' into an argument vector. Handles quoted string and basic
1829
 * escape characters (\\, \", \'). Caller must free the argument vector
1828
 * escape characters (\\, \", \'). Caller must free the argument vector
1830
 * and its members.
1829
 * and its members.
1831
 */
1830
 */
1832
int
1831
int
1833
argv_split(const char *s, int *argcp, char ***argvp)
1832
argv_split(const char *s, int *argcp, char ***argvp, int terminate_on_comment)
1834
{
1833
{
1835
	int r = SSH_ERR_INTERNAL_ERROR;
1834
	int r = SSH_ERR_INTERNAL_ERROR;
1836
	int argc = 0, quote, i, j;
1835
	int argc = 0, quote, i, j;
Lines 1843-1849 argv_split(const char *s, int *argcp, char ***argvp) Link Here
1843
		/* Skip leading whitespace */
1842
		/* Skip leading whitespace */
1844
		if (s[i] == ' ' || s[i] == '\t')
1843
		if (s[i] == ' ' || s[i] == '\t')
1845
			continue;
1844
			continue;
1846
1845
		if (terminate_on_comment && s[i] == '#')
1846
			break;
1847
		/* Start of a token */
1847
		/* Start of a token */
1848
		quote = 0;
1848
		quote = 0;
1849
1849
Lines 1856-1862 argv_split(const char *s, int *argcp, char ***argvp) Link Here
1856
			if (s[i] == '\\') {
1856
			if (s[i] == '\\') {
1857
				if (s[i + 1] == '\'' ||
1857
				if (s[i + 1] == '\'' ||
1858
				    s[i + 1] == '\"' ||
1858
				    s[i + 1] == '\"' ||
1859
				    s[i + 1] == '\\') {
1859
				    s[i + 1] == '\\' ||
1860
				    (quote == 0 && s[i + 1] == ' ')) {
1860
					i++; /* Skip '\' */
1861
					i++; /* Skip '\' */
1861
					arg[j++] = s[i];
1862
					arg[j++] = s[i];
1862
				} else {
1863
				} else {
(-)a/misc.h (-1 / +1 lines)
Lines 174-180 void mktemp_proto(char *, size_t); Link Here
174
void	 child_set_env(char ***envp, u_int *envsizep, const char *name,
174
void	 child_set_env(char ***envp, u_int *envsizep, const char *name,
175
	    const char *value);
175
	    const char *value);
176
176
177
int	 argv_split(const char *, int *, char ***);
177
int	 argv_split(const char *, int *, char ***, int);
178
char	*argv_assemble(int, char **argv);
178
char	*argv_assemble(int, char **argv);
179
int	 exited_cleanly(pid_t, const char *, const char *, int);
179
int	 exited_cleanly(pid_t, const char *, const char *, int);
180
180
(-)a/readconf.c (-142 / +251 lines)
Lines 882-887 parse_multistate_value(const char *arg, const char *filename, int linenum, Link Here
882
	return -1;
882
	return -1;
883
}
883
}
884
884
885
static char *
886
next_arg(int *argcp, char ***argvp)
887
{
888
	char *ret = (*argvp)[0];
889
890
	if (*argcp > 0 && ret != NULL) {
891
		(*argcp)--;
892
		(*argvp)++;
893
	}
894
	return ret;
895
}
896
897
static void
898
consume_args(int *argcp)
899
{
900
	*argcp = 0;
901
}
902
885
/*
903
/*
886
 * Processes a single option line as used in the configuration files. This
904
 * Processes a single option line as used in the configuration files. This
887
 * only sets those values that have not already been set.
905
 * only sets those values that have not already been set.
Lines 901-907 process_config_line_depth(Options *options, struct passwd *pw, const char *host, Link Here
901
    const char *original_host, char *line, const char *filename,
919
    const char *original_host, char *line, const char *filename,
902
    int linenum, int *activep, int flags, int *want_final_pass, int depth)
920
    int linenum, int *activep, int flags, int *want_final_pass, int depth)
903
{
921
{
904
	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch;
922
	char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch;
905
	char **cpptr, ***cppptr, fwdarg[256];
923
	char **cpptr, ***cppptr, fwdarg[256];
906
	u_int i, *uintptr, uvalue, max_entries = 0;
924
	u_int i, *uintptr, uvalue, max_entries = 0;
907
	int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
925
	int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
Lines 915-920 process_config_line_depth(Options *options, struct passwd *pw, const char *host, Link Here
915
	struct allowed_cname *cname;
933
	struct allowed_cname *cname;
916
	glob_t gl;
934
	glob_t gl;
917
	const char *errstr;
935
	const char *errstr;
936
	char **oav = NULL, **av;
937
	int oac = 0, ac;
938
	int ret = -1;
918
939
919
	if (activep == NULL) { /* We are processing a command line directive */
940
	if (activep == NULL) { /* We are processing a command line directive */
920
		cmdline = 1;
941
		cmdline = 1;
Lines 930-975 process_config_line_depth(Options *options, struct passwd *pw, const char *host, Link Here
930
		line[len] = '\0';
951
		line[len] = '\0';
931
	}
952
	}
932
953
933
	s = line;
954
	str = line;
934
	/* Get the keyword. (Each line is supposed to begin with a keyword). */
955
	/* Get the keyword. (Each line is supposed to begin with a keyword). */
935
	if ((keyword = strdelim(&s)) == NULL)
956
	if ((keyword = strdelim(&str)) == NULL)
936
		return 0;
957
		return 0;
937
	/* Ignore leading whitespace. */
958
	/* Ignore leading whitespace. */
938
	if (*keyword == '\0')
959
	if (*keyword == '\0')
939
		keyword = strdelim(&s);
960
		keyword = strdelim(&str);
940
	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
961
	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
941
		return 0;
962
		return 0;
942
	/* Match lowercase keyword */
963
	/* Match lowercase keyword */
943
	lowercase(keyword);
964
	lowercase(keyword);
944
965
966
	/* Prepare to parse remainder of line */
967
	if (str != NULL)
968
		str += strspn(str, WHITESPACE);
969
	if (str == NULL || *str == '\0') {
970
		error("%s line %d: no argument after keyword \"%s\"",
971
		    filename, linenum, keyword);
972
		return -1;
973
	}
945
	opcode = parse_token(keyword, filename, linenum,
974
	opcode = parse_token(keyword, filename, linenum,
946
	    options->ignored_unknown);
975
	    options->ignored_unknown);
976
	if (argv_split(str, &oac, &oav, 1) != 0) {
977
		error("%s line %d: invalid quotes", filename, linenum);
978
		return -1;
979
	}
980
	ac = oac;
981
	av = oav;
947
982
948
	switch (opcode) {
983
	switch (opcode) {
949
	case oBadOption:
984
	case oBadOption:
950
		/* don't panic, but count bad options */
985
		/* don't panic, but count bad options */
951
		return -1;
986
		goto out;
952
	case oIgnore:
987
	case oIgnore:
953
		return 0;
988
		consume_args(&ac);
989
		break;
954
	case oIgnoredUnknownOption:
990
	case oIgnoredUnknownOption:
955
		debug("%s line %d: Ignored unknown option \"%s\"",
991
		debug("%s line %d: Ignored unknown option \"%s\"",
956
		    filename, linenum, keyword);
992
		    filename, linenum, keyword);
957
		return 0;
993
		consume_args(&ac);
994
		break;
958
	case oConnectTimeout:
995
	case oConnectTimeout:
959
		intptr = &options->connection_timeout;
996
		intptr = &options->connection_timeout;
960
parse_time:
997
parse_time:
961
		arg = strdelim(&s);
998
		arg = next_arg(&ac, &av);
962
		if (!arg || *arg == '\0') {
999
		if (!arg || *arg == '\0') {
963
			error("%s line %d: missing time value.",
1000
			error("%s line %d: missing time value.",
964
			    filename, linenum);
1001
			    filename, linenum);
965
			return -1;
1002
			goto out;
966
		}
1003
		}
967
		if (strcmp(arg, "none") == 0)
1004
		if (strcmp(arg, "none") == 0)
968
			value = -1;
1005
			value = -1;
969
		else if ((value = convtime(arg)) == -1) {
1006
		else if ((value = convtime(arg)) == -1) {
970
			error("%s line %d: invalid time value.",
1007
			error("%s line %d: invalid time value.",
971
			    filename, linenum);
1008
			    filename, linenum);
972
			return -1;
1009
			goto out;
973
		}
1010
		}
974
		if (*activep && *intptr == -1)
1011
		if (*activep && *intptr == -1)
975
			*intptr = value;
1012
			*intptr = value;
Lines 978-988 parse_time: Link Here
978
	case oForwardAgent:
1015
	case oForwardAgent:
979
		intptr = &options->forward_agent;
1016
		intptr = &options->forward_agent;
980
1017
981
		arg = strdelim(&s);
1018
		arg = next_arg(&ac, &av);
982
		if (!arg || *arg == '\0') {
1019
		if (!arg || *arg == '\0') {
983
			error("%s line %d: missing argument.",
1020
			error("%s line %d: missing argument.",
984
			    filename, linenum);
1021
			    filename, linenum);
985
			return -1;
1022
			goto out;
986
		}
1023
		}
987
1024
988
		value = -1;
1025
		value = -1;
Lines 1010-1021 parse_time: Link Here
1010
 parse_flag:
1047
 parse_flag:
1011
		multistate_ptr = multistate_flag;
1048
		multistate_ptr = multistate_flag;
1012
 parse_multistate:
1049
 parse_multistate:
1013
		arg = strdelim(&s);
1050
		arg = next_arg(&ac, &av);
1014
		if ((value = parse_multistate_value(arg, filename, linenum,
1051
		if ((value = parse_multistate_value(arg, filename, linenum,
1015
		    multistate_ptr)) == -1) {
1052
		    multistate_ptr)) == -1) {
1016
			error("%s line %d: unsupported option \"%s\".",
1053
			error("%s line %d: unsupported option \"%s\".",
1017
			    filename, linenum, arg);
1054
			    filename, linenum, arg);
1018
			return -1;
1055
			goto out;
1019
		}
1056
		}
1020
		if (*activep && *intptr == -1)
1057
		if (*activep && *intptr == -1)
1021
			*intptr = value;
1058
			*intptr = value;
Lines 1105-1115 parse_time: Link Here
1105
		goto parse_int;
1142
		goto parse_int;
1106
1143
1107
	case oRekeyLimit:
1144
	case oRekeyLimit:
1108
		arg = strdelim(&s);
1145
		arg = next_arg(&ac, &av);
1109
		if (!arg || *arg == '\0') {
1146
		if (!arg || *arg == '\0') {
1110
			error("%.200s line %d: Missing argument.", filename,
1147
			error("%.200s line %d: Missing argument.", filename,
1111
			    linenum);
1148
			    linenum);
1112
			return -1;
1149
			goto out;
1113
		}
1150
		}
1114
		if (strcmp(arg, "default") == 0) {
1151
		if (strcmp(arg, "default") == 0) {
1115
			val64 = 0;
1152
			val64 = 0;
Lines 1117-1135 parse_time: Link Here
1117
			if (scan_scaled(arg, &val64) == -1) {
1154
			if (scan_scaled(arg, &val64) == -1) {
1118
				error("%.200s line %d: Bad number '%s': %s",
1155
				error("%.200s line %d: Bad number '%s': %s",
1119
				    filename, linenum, arg, strerror(errno));
1156
				    filename, linenum, arg, strerror(errno));
1120
				return -1;
1157
				goto out;
1121
			}
1158
			}
1122
			if (val64 != 0 && val64 < 16) {
1159
			if (val64 != 0 && val64 < 16) {
1123
				error("%.200s line %d: RekeyLimit too small",
1160
				error("%.200s line %d: RekeyLimit too small",
1124
				    filename, linenum);
1161
				    filename, linenum);
1125
				return -1;
1162
				goto out;
1126
			}
1163
			}
1127
		}
1164
		}
1128
		if (*activep && options->rekey_limit == -1)
1165
		if (*activep && options->rekey_limit == -1)
1129
			options->rekey_limit = val64;
1166
			options->rekey_limit = val64;
1130
		if (s != NULL) { /* optional rekey interval present */
1167
		if (ac != 0) { /* optional rekey interval present */
1131
			if (strcmp(s, "none") == 0) {
1168
			if (strcmp(av[0], "none") == 0) {
1132
				(void)strdelim(&s);	/* discard */
1169
				(void)next_arg(&ac, &av);	/* discard */
1133
				break;
1170
				break;
1134
			}
1171
			}
1135
			intptr = &options->rekey_interval;
1172
			intptr = &options->rekey_interval;
Lines 1138-1148 parse_time: Link Here
1138
		break;
1175
		break;
1139
1176
1140
	case oIdentityFile:
1177
	case oIdentityFile:
1141
		arg = strdelim(&s);
1178
		arg = next_arg(&ac, &av);
1142
		if (!arg || *arg == '\0') {
1179
		if (!arg || *arg == '\0') {
1143
			error("%.200s line %d: Missing argument.",
1180
			error("%.200s line %d: Missing argument.",
1144
			    filename, linenum);
1181
			    filename, linenum);
1145
			return -1;
1182
			goto out;
1146
		}
1183
		}
1147
		if (*activep) {
1184
		if (*activep) {
1148
			intptr = &options->num_identity_files;
1185
			intptr = &options->num_identity_files;
Lines 1150-1156 parse_time: Link Here
1150
				error("%.200s line %d: Too many identity files "
1187
				error("%.200s line %d: Too many identity files "
1151
				    "specified (max %d).", filename, linenum,
1188
				    "specified (max %d).", filename, linenum,
1152
				    SSH_MAX_IDENTITY_FILES);
1189
				    SSH_MAX_IDENTITY_FILES);
1153
				return -1;
1190
				goto out;
1154
			}
1191
			}
1155
			add_identity_file(options, NULL,
1192
			add_identity_file(options, NULL,
1156
			    arg, flags & SSHCONF_USERCONF);
1193
			    arg, flags & SSHCONF_USERCONF);
Lines 1158-1168 parse_time: Link Here
1158
		break;
1195
		break;
1159
1196
1160
	case oCertificateFile:
1197
	case oCertificateFile:
1161
		arg = strdelim(&s);
1198
		arg = next_arg(&ac, &av);
1162
		if (!arg || *arg == '\0') {
1199
		if (!arg || *arg == '\0') {
1163
			error("%.200s line %d: Missing argument.",
1200
			error("%.200s line %d: Missing argument.",
1164
			    filename, linenum);
1201
			    filename, linenum);
1165
			return -1;
1202
			goto out;
1166
		}
1203
		}
1167
		if (*activep) {
1204
		if (*activep) {
1168
			intptr = &options->num_certificate_files;
1205
			intptr = &options->num_certificate_files;
Lines 1171-1177 parse_time: Link Here
1171
				    "files specified (max %d).",
1208
				    "files specified (max %d).",
1172
				    filename, linenum,
1209
				    filename, linenum,
1173
				    SSH_MAX_CERTIFICATE_FILES);
1210
				    SSH_MAX_CERTIFICATE_FILES);
1174
				return -1;
1211
				goto out;
1175
			}
1212
			}
1176
			add_certificate_file(options, arg,
1213
			add_certificate_file(options, arg,
1177
			    flags & SSHCONF_USERCONF);
1214
			    flags & SSHCONF_USERCONF);
Lines 1185-1195 parse_time: Link Here
1185
	case oUser:
1222
	case oUser:
1186
		charptr = &options->user;
1223
		charptr = &options->user;
1187
parse_string:
1224
parse_string:
1188
		arg = strdelim(&s);
1225
		arg = next_arg(&ac, &av);
1189
		if (!arg || *arg == '\0') {
1226
		if (!arg || *arg == '\0') {
1190
			error("%.200s line %d: Missing argument.",
1227
			error("%.200s line %d: Missing argument.",
1191
			    filename, linenum);
1228
			    filename, linenum);
1192
			return -1;
1229
			goto out;
1193
		}
1230
		}
1194
		if (*activep && *charptr == NULL)
1231
		if (*activep && *charptr == NULL)
1195
			*charptr = xstrdup(arg);
1232
			*charptr = xstrdup(arg);
Lines 1200-1216 parse_string: Link Here
1200
		uintptr = &options->num_system_hostfiles;
1237
		uintptr = &options->num_system_hostfiles;
1201
		max_entries = SSH_MAX_HOSTS_FILES;
1238
		max_entries = SSH_MAX_HOSTS_FILES;
1202
parse_char_array:
1239
parse_char_array:
1203
		if (*activep && *uintptr == 0) {
1240
		i = 0;
1204
			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1241
		while ((arg = next_arg(&ac, &av)) != NULL) {
1242
			if (*arg == '\0') {
1243
				error("%s line %d: keyword %s empty argument",
1244
				    filename, linenum, keyword);
1245
				goto out;
1246
			}
1247
			/* Allow "none" only in first position */
1248
			if (strcasecmp(arg, "none") == 0) {
1249
				if (i > 0 || ac > 0) {
1250
					error("%s line %d: keyword %s \"none\" "
1251
					    "argument must appear alone.",
1252
					    filename, linenum, keyword);
1253
					goto out;
1254
				}
1255
			}
1256
			i++;
1257
			if (*activep && *uintptr == 0) {
1205
				if ((*uintptr) >= max_entries) {
1258
				if ((*uintptr) >= max_entries) {
1206
					error("%s line %d: too many known "
1259
					error("%s line %d: too many %s "
1207
					    "hosts files.", filename, linenum);
1260
					    "entries.", filename, linenum,
1208
					return -1;
1261
					    keyword);
1262
					goto out;
1209
				}
1263
				}
1210
				cpptr[(*uintptr)++] = xstrdup(arg);
1264
				cpptr[(*uintptr)++] = xstrdup(arg);
1211
			}
1265
			}
1212
		}
1266
		}
1213
		return 0;
1267
		break;
1214
1268
1215
	case oUserKnownHostsFile:
1269
	case oUserKnownHostsFile:
1216
		cpptr = (char **)&options->user_hostfiles;
1270
		cpptr = (char **)&options->user_hostfiles;
Lines 1256-1297 parse_char_array: Link Here
1256
		if (options->jump_host != NULL)
1310
		if (options->jump_host != NULL)
1257
			charptr = &options->jump_host; /* Skip below */
1311
			charptr = &options->jump_host; /* Skip below */
1258
parse_command:
1312
parse_command:
1259
		if (s == NULL) {
1313
		if (str == NULL) {
1260
			error("%.200s line %d: Missing argument.",
1314
			error("%.200s line %d: Missing argument.",
1261
			    filename, linenum);
1315
			    filename, linenum);
1262
			return -1;
1316
			goto out;
1263
		}
1317
		}
1264
		len = strspn(s, WHITESPACE "=");
1318
		len = strspn(str, WHITESPACE "=");
1265
		if (*activep && *charptr == NULL)
1319
		if (*activep && *charptr == NULL)
1266
			*charptr = xstrdup(s + len);
1320
			*charptr = xstrdup(str + len);
1267
		return 0;
1321
		consume_args(&ac);
1322
		break;
1268
1323
1269
	case oProxyJump:
1324
	case oProxyJump:
1270
		if (s == NULL) {
1325
		if (str == NULL) {
1271
			error("%.200s line %d: Missing argument.",
1326
			error("%.200s line %d: Missing argument.",
1272
			    filename, linenum);
1327
			    filename, linenum);
1273
			return -1;
1328
			goto out;
1274
		}
1329
		}
1275
		len = strspn(s, WHITESPACE "=");
1330
		len = strspn(str, WHITESPACE "=");
1276
		if (parse_jump(s + len, options, *activep) == -1) {
1331
		/* XXX use argv? */
1332
		if (parse_jump(str + len, options, *activep) == -1) {
1277
			error("%.200s line %d: Invalid ProxyJump \"%s\"",
1333
			error("%.200s line %d: Invalid ProxyJump \"%s\"",
1278
			    filename, linenum, s + len);
1334
			    filename, linenum, str + len);
1279
			return -1;
1335
			goto out;
1280
		}
1336
		}
1281
		return 0;
1337
		consume_args(&ac);
1338
		break;
1282
1339
1283
	case oPort:
1340
	case oPort:
1284
		arg = strdelim(&s);
1341
		arg = next_arg(&ac, &av);
1285
		if (!arg || *arg == '\0') {
1342
		if (!arg || *arg == '\0') {
1286
			error("%.200s line %d: Missing argument.",
1343
			error("%.200s line %d: Missing argument.",
1287
			    filename, linenum);
1344
			    filename, linenum);
1288
			return -1;
1345
			goto out;
1289
		}
1346
		}
1290
		value = a2port(arg);
1347
		value = a2port(arg);
1291
		if (value <= 0) {
1348
		if (value <= 0) {
1292
			error("%.200s line %d: Bad port '%s'.",
1349
			error("%.200s line %d: Bad port '%s'.",
1293
			    filename, linenum, arg);
1350
			    filename, linenum, arg);
1294
			return -1;
1351
			goto out;
1295
		}
1352
		}
1296
		if (*activep && options->port == -1)
1353
		if (*activep && options->port == -1)
1297
			options->port = value;
1354
			options->port = value;
Lines 1300-1362 parse_command: Link Here
1300
	case oConnectionAttempts:
1357
	case oConnectionAttempts:
1301
		intptr = &options->connection_attempts;
1358
		intptr = &options->connection_attempts;
1302
parse_int:
1359
parse_int:
1303
		arg = strdelim(&s);
1360
		arg = next_arg(&ac, &av);
1304
		if ((errstr = atoi_err(arg, &value)) != NULL) {
1361
		if ((errstr = atoi_err(arg, &value)) != NULL) {
1305
			error("%s line %d: integer value %s.",
1362
			error("%s line %d: integer value %s.",
1306
			    filename, linenum, errstr);
1363
			    filename, linenum, errstr);
1307
			return -1;
1364
			goto out;
1308
		}
1365
		}
1309
		if (*activep && *intptr == -1)
1366
		if (*activep && *intptr == -1)
1310
			*intptr = value;
1367
			*intptr = value;
1311
		break;
1368
		break;
1312
1369
1313
	case oCiphers:
1370
	case oCiphers:
1314
		arg = strdelim(&s);
1371
		arg = next_arg(&ac, &av);
1315
		if (!arg || *arg == '\0') {
1372
		if (!arg || *arg == '\0') {
1316
			error("%.200s line %d: Missing argument.",
1373
			error("%.200s line %d: Missing argument.",
1317
			    filename, linenum);
1374
			    filename, linenum);
1318
			return -1;
1375
			goto out;
1319
		}
1376
		}
1320
		if (*arg != '-' &&
1377
		if (*arg != '-' &&
1321
		    !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)){
1378
		    !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)){
1322
			error("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1379
			error("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1323
			    filename, linenum, arg ? arg : "<NONE>");
1380
			    filename, linenum, arg ? arg : "<NONE>");
1324
			return -1;
1381
			goto out;
1325
		}
1382
		}
1326
		if (*activep && options->ciphers == NULL)
1383
		if (*activep && options->ciphers == NULL)
1327
			options->ciphers = xstrdup(arg);
1384
			options->ciphers = xstrdup(arg);
1328
		break;
1385
		break;
1329
1386
1330
	case oMacs:
1387
	case oMacs:
1331
		arg = strdelim(&s);
1388
		arg = next_arg(&ac, &av);
1332
		if (!arg || *arg == '\0') {
1389
		if (!arg || *arg == '\0') {
1333
			error("%.200s line %d: Missing argument.",
1390
			error("%.200s line %d: Missing argument.",
1334
			    filename, linenum);
1391
			    filename, linenum);
1335
			return -1;
1392
			goto out;
1336
		}
1393
		}
1337
		if (*arg != '-' &&
1394
		if (*arg != '-' &&
1338
		    !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) {
1395
		    !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) {
1339
			error("%.200s line %d: Bad SSH2 MAC spec '%s'.",
1396
			error("%.200s line %d: Bad SSH2 MAC spec '%s'.",
1340
			    filename, linenum, arg ? arg : "<NONE>");
1397
			    filename, linenum, arg ? arg : "<NONE>");
1341
			return -1;
1398
			goto out;
1342
		}
1399
		}
1343
		if (*activep && options->macs == NULL)
1400
		if (*activep && options->macs == NULL)
1344
			options->macs = xstrdup(arg);
1401
			options->macs = xstrdup(arg);
1345
		break;
1402
		break;
1346
1403
1347
	case oKexAlgorithms:
1404
	case oKexAlgorithms:
1348
		arg = strdelim(&s);
1405
		arg = next_arg(&ac, &av);
1349
		if (!arg || *arg == '\0') {
1406
		if (!arg || *arg == '\0') {
1350
			error("%.200s line %d: Missing argument.",
1407
			error("%.200s line %d: Missing argument.",
1351
			    filename, linenum);
1408
			    filename, linenum);
1352
			return -1;
1409
			goto out;
1353
		}
1410
		}
1354
		if (*arg != '-' &&
1411
		if (*arg != '-' &&
1355
		    !kex_names_valid(*arg == '+' || *arg == '^' ?
1412
		    !kex_names_valid(*arg == '+' || *arg == '^' ?
1356
		    arg + 1 : arg)) {
1413
		    arg + 1 : arg)) {
1357
			error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1414
			error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1358
			    filename, linenum, arg ? arg : "<NONE>");
1415
			    filename, linenum, arg ? arg : "<NONE>");
1359
			return -1;
1416
			goto out;
1360
		}
1417
		}
1361
		if (*activep && options->kex_algorithms == NULL)
1418
		if (*activep && options->kex_algorithms == NULL)
1362
			options->kex_algorithms = xstrdup(arg);
1419
			options->kex_algorithms = xstrdup(arg);
Lines 1365-1382 parse_int: Link Here
1365
	case oHostKeyAlgorithms:
1422
	case oHostKeyAlgorithms:
1366
		charptr = &options->hostkeyalgorithms;
1423
		charptr = &options->hostkeyalgorithms;
1367
parse_pubkey_algos:
1424
parse_pubkey_algos:
1368
		arg = strdelim(&s);
1425
		arg = next_arg(&ac, &av);
1369
		if (!arg || *arg == '\0') {
1426
		if (!arg || *arg == '\0') {
1370
			error("%.200s line %d: Missing argument.",
1427
			error("%.200s line %d: Missing argument.",
1371
			    filename, linenum);
1428
			    filename, linenum);
1372
			return -1;
1429
			goto out;
1373
		}
1430
		}
1374
		if (*arg != '-' &&
1431
		if (*arg != '-' &&
1375
		    !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1432
		    !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1376
		    arg + 1 : arg, 1)) {
1433
		    arg + 1 : arg, 1)) {
1377
			error("%s line %d: Bad key types '%s'.",
1434
			error("%s line %d: Bad key types '%s'.",
1378
			    filename, linenum, arg ? arg : "<NONE>");
1435
			    filename, linenum, arg ? arg : "<NONE>");
1379
			return -1;
1436
			goto out;
1380
		}
1437
		}
1381
		if (*activep && *charptr == NULL)
1438
		if (*activep && *charptr == NULL)
1382
			*charptr = xstrdup(arg);
1439
			*charptr = xstrdup(arg);
Lines 1388-1399 parse_pubkey_algos: Link Here
1388
1445
1389
	case oLogLevel:
1446
	case oLogLevel:
1390
		log_level_ptr = &options->log_level;
1447
		log_level_ptr = &options->log_level;
1391
		arg = strdelim(&s);
1448
		arg = next_arg(&ac, &av);
1392
		value = log_level_number(arg);
1449
		value = log_level_number(arg);
1393
		if (value == SYSLOG_LEVEL_NOT_SET) {
1450
		if (value == SYSLOG_LEVEL_NOT_SET) {
1394
			error("%.200s line %d: unsupported log level '%s'",
1451
			error("%.200s line %d: unsupported log level '%s'",
1395
			    filename, linenum, arg ? arg : "<NONE>");
1452
			    filename, linenum, arg ? arg : "<NONE>");
1396
			return -1;
1453
			goto out;
1397
		}
1454
		}
1398
		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1455
		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1399
			*log_level_ptr = (LogLevel) value;
1456
			*log_level_ptr = (LogLevel) value;
Lines 1401-1412 parse_pubkey_algos: Link Here
1401
1458
1402
	case oLogFacility:
1459
	case oLogFacility:
1403
		log_facility_ptr = &options->log_facility;
1460
		log_facility_ptr = &options->log_facility;
1404
		arg = strdelim(&s);
1461
		arg = next_arg(&ac, &av);
1405
		value = log_facility_number(arg);
1462
		value = log_facility_number(arg);
1406
		if (value == SYSLOG_FACILITY_NOT_SET) {
1463
		if (value == SYSLOG_FACILITY_NOT_SET) {
1407
			error("%.200s line %d: unsupported log facility '%s'",
1464
			error("%.200s line %d: unsupported log facility '%s'",
1408
			    filename, linenum, arg ? arg : "<NONE>");
1465
			    filename, linenum, arg ? arg : "<NONE>");
1409
			return -1;
1466
			goto out;
1410
		}
1467
		}
1411
		if (*log_facility_ptr == -1)
1468
		if (*log_facility_ptr == -1)
1412
			*log_facility_ptr = (SyslogFacility) value;
1469
			*log_facility_ptr = (SyslogFacility) value;
Lines 1415-1451 parse_pubkey_algos: Link Here
1415
	case oLogVerbose:
1472
	case oLogVerbose:
1416
		cppptr = &options->log_verbose;
1473
		cppptr = &options->log_verbose;
1417
		uintptr = &options->num_log_verbose;
1474
		uintptr = &options->num_log_verbose;
1418
		if (*activep && *uintptr == 0) {
1475
		i = 0;
1419
			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1476
		while ((arg = next_arg(&ac, &av)) != NULL) {
1477
			if (*arg == '\0') {
1478
				error("%s line %d: keyword %s empty argument",
1479
				    filename, linenum, keyword);
1480
				goto out;
1481
			}
1482
			/* Allow "none" only in first position */
1483
			if (strcasecmp(arg, "none") == 0) {
1484
				if (i > 0 || ac > 0) {
1485
					error("%s line %d: keyword %s \"none\" "
1486
					    "argument must appear alone.",
1487
					    filename, linenum, keyword);
1488
					goto out;
1489
				}
1490
			}
1491
			i++;
1492
			if (*activep && *uintptr == 0) {
1420
				*cppptr = xrecallocarray(*cppptr, *uintptr,
1493
				*cppptr = xrecallocarray(*cppptr, *uintptr,
1421
				    *uintptr + 1, sizeof(**cppptr));
1494
				    *uintptr + 1, sizeof(**cppptr));
1422
				(*cppptr)[(*uintptr)++] = xstrdup(arg);
1495
				(*cppptr)[(*uintptr)++] = xstrdup(arg);
1423
			}
1496
			}
1424
		}
1497
		}
1425
		return 0;
1498
		break;
1426
1499
1427
	case oLocalForward:
1500
	case oLocalForward:
1428
	case oRemoteForward:
1501
	case oRemoteForward:
1429
	case oDynamicForward:
1502
	case oDynamicForward:
1430
		arg = strdelim(&s);
1503
		arg = next_arg(&ac, &av);
1431
		if (!arg || *arg == '\0') {
1504
		if (!arg || *arg == '\0') {
1432
			error("%.200s line %d: Missing argument.",
1505
			error("%.200s line %d: Missing argument.",
1433
			    filename, linenum);
1506
			    filename, linenum);
1434
			return -1;
1507
			goto out;
1435
		}
1508
		}
1436
1509
1437
		remotefwd = (opcode == oRemoteForward);
1510
		remotefwd = (opcode == oRemoteForward);
1438
		dynamicfwd = (opcode == oDynamicForward);
1511
		dynamicfwd = (opcode == oDynamicForward);
1439
1512
1440
		if (!dynamicfwd) {
1513
		if (!dynamicfwd) {
1441
			arg2 = strdelim(&s);
1514
			arg2 = next_arg(&ac, &av);
1442
			if (arg2 == NULL || *arg2 == '\0') {
1515
			if (arg2 == NULL || *arg2 == '\0') {
1443
				if (remotefwd)
1516
				if (remotefwd)
1444
					dynamicfwd = 1;
1517
					dynamicfwd = 1;
1445
				else {
1518
				else {
1446
					error("%.200s line %d: Missing target "
1519
					error("%.200s line %d: Missing target "
1447
					    "argument.", filename, linenum);
1520
					    "argument.", filename, linenum);
1448
					return -1;
1521
					goto out;
1449
				}
1522
				}
1450
			} else {
1523
			} else {
1451
				/* construct a string for parse_forward */
1524
				/* construct a string for parse_forward */
Lines 1459-1465 parse_pubkey_algos: Link Here
1459
		if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) {
1532
		if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) {
1460
			error("%.200s line %d: Bad forwarding specification.",
1533
			error("%.200s line %d: Bad forwarding specification.",
1461
			    filename, linenum);
1534
			    filename, linenum);
1462
			return -1;
1535
			goto out;
1463
		}
1536
		}
1464
1537
1465
		if (*activep) {
1538
		if (*activep) {
Lines 1474-1480 parse_pubkey_algos: Link Here
1474
	case oPermitRemoteOpen:
1547
	case oPermitRemoteOpen:
1475
		uintptr = &options->num_permitted_remote_opens;
1548
		uintptr = &options->num_permitted_remote_opens;
1476
		cppptr = &options->permitted_remote_opens;
1549
		cppptr = &options->permitted_remote_opens;
1477
		arg = strdelim(&s);
1550
		arg = next_arg(&ac, &av);
1478
		if (!arg || *arg == '\0')
1551
		if (!arg || *arg == '\0')
1479
			fatal("%s line %d: missing %s specification",
1552
			fatal("%s line %d: missing %s specification",
1480
			    filename, linenum, lookup_opcode_name(opcode));
1553
			    filename, linenum, lookup_opcode_name(opcode));
Lines 1487-1493 parse_pubkey_algos: Link Here
1487
			}
1560
			}
1488
			break;
1561
			break;
1489
		}
1562
		}
1490
		for (; arg != NULL && *arg != '\0'; arg = strdelim(&s)) {
1563
		while ((arg = next_arg(&ac, &av)) != NULL) {
1491
			arg2 = xstrdup(arg);
1564
			arg2 = xstrdup(arg);
1492
			ch = '\0';
1565
			ch = '\0';
1493
			p = hpdelim2(&arg, &ch);
1566
			p = hpdelim2(&arg, &ch);
Lines 1524-1534 parse_pubkey_algos: Link Here
1524
		if (cmdline) {
1597
		if (cmdline) {
1525
			error("Host directive not supported as a command-line "
1598
			error("Host directive not supported as a command-line "
1526
			    "option");
1599
			    "option");
1527
			return -1;
1600
			goto out;
1528
		}
1601
		}
1529
		*activep = 0;
1602
		*activep = 0;
1530
		arg2 = NULL;
1603
		arg2 = NULL;
1531
		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1604
		while ((arg = next_arg(&ac, &av)) != NULL) {
1605
			if (*arg == '\0') {
1606
				error("%s line %d: keyword %s empty argument",
1607
				    filename, linenum, keyword);
1608
				goto out;
1609
			}
1532
			if ((flags & SSHCONF_NEVERMATCH) != 0)
1610
			if ((flags & SSHCONF_NEVERMATCH) != 0)
1533
				break;
1611
				break;
1534
			negated = *arg == '!';
1612
			negated = *arg == '!';
Lines 1551-1583 parse_pubkey_algos: Link Here
1551
		if (*activep)
1629
		if (*activep)
1552
			debug("%.200s line %d: Applying options for %.100s",
1630
			debug("%.200s line %d: Applying options for %.100s",
1553
			    filename, linenum, arg2);
1631
			    filename, linenum, arg2);
1554
		/* Avoid garbage check below, as strdelim is done. */
1632
		break;
1555
		return 0;
1556
1633
1557
	case oMatch:
1634
	case oMatch:
1558
		if (cmdline) {
1635
		if (cmdline) {
1559
			error("Host directive not supported as a command-line "
1636
			error("Host directive not supported as a command-line "
1560
			    "option");
1637
			    "option");
1561
			return -1;
1638
			goto out;
1562
		}
1639
		}
1563
		value = match_cfg_line(options, &s, pw, host, original_host,
1640
		value = match_cfg_line(options, &str, pw, host, original_host,
1564
		    flags & SSHCONF_FINAL, want_final_pass,
1641
		    flags & SSHCONF_FINAL, want_final_pass,
1565
		    filename, linenum);
1642
		    filename, linenum);
1566
		if (value < 0) {
1643
		if (value < 0) {
1567
			error("%.200s line %d: Bad Match condition", filename,
1644
			error("%.200s line %d: Bad Match condition", filename,
1568
			    linenum);
1645
			    linenum);
1569
			return -1;
1646
			goto out;
1570
		}
1647
		}
1571
		*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1648
		*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1649
		consume_args(&ac);
1572
		break;
1650
		break;
1573
1651
1574
	case oEscapeChar:
1652
	case oEscapeChar:
1575
		intptr = &options->escape_char;
1653
		intptr = &options->escape_char;
1576
		arg = strdelim(&s);
1654
		arg = next_arg(&ac, &av);
1577
		if (!arg || *arg == '\0') {
1655
		if (!arg || *arg == '\0') {
1578
			error("%.200s line %d: Missing argument.",
1656
			error("%.200s line %d: Missing argument.",
1579
			    filename, linenum);
1657
			    filename, linenum);
1580
			return -1;
1658
			goto out;
1581
		}
1659
		}
1582
		if (strcmp(arg, "none") == 0)
1660
		if (strcmp(arg, "none") == 0)
1583
			value = SSH_ESCAPECHAR_NONE;
1661
			value = SSH_ESCAPECHAR_NONE;
Lines 1589-1595 parse_pubkey_algos: Link Here
1589
		else {
1667
		else {
1590
			error("%.200s line %d: Bad escape character.",
1668
			error("%.200s line %d: Bad escape character.",
1591
			    filename, linenum);
1669
			    filename, linenum);
1592
			return -1;
1670
			goto out;
1593
		}
1671
		}
1594
		if (*activep && *intptr == -1)
1672
		if (*activep && *intptr == -1)
1595
			*intptr = value;
1673
			*intptr = value;
Lines 1617-1627 parse_pubkey_algos: Link Here
1617
		goto parse_int;
1695
		goto parse_int;
1618
1696
1619
	case oSendEnv:
1697
	case oSendEnv:
1620
		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1698
		while ((arg = next_arg(&ac, &av)) != NULL) {
1621
			if (strchr(arg, '=') != NULL) {
1699
			if (*arg == '\0' || strchr(arg, '=') != NULL) {
1622
				error("%s line %d: Invalid environment name.",
1700
				error("%s line %d: Invalid environment name.",
1623
				    filename, linenum);
1701
				    filename, linenum);
1624
				return -1;
1702
				goto out;
1625
			}
1703
			}
1626
			if (!*activep)
1704
			if (!*activep)
1627
				continue;
1705
				continue;
Lines 1634-1640 parse_pubkey_algos: Link Here
1634
				if (options->num_send_env >= INT_MAX) {
1712
				if (options->num_send_env >= INT_MAX) {
1635
					error("%s line %d: too many send env.",
1713
					error("%s line %d: too many send env.",
1636
					    filename, linenum);
1714
					    filename, linenum);
1637
					return -1;
1715
					goto out;
1638
				}
1716
				}
1639
				options->send_env = xrecallocarray(
1717
				options->send_env = xrecallocarray(
1640
				    options->send_env, options->num_send_env,
1718
				    options->send_env, options->num_send_env,
Lines 1648-1658 parse_pubkey_algos: Link Here
1648
1726
1649
	case oSetEnv:
1727
	case oSetEnv:
1650
		value = options->num_setenv;
1728
		value = options->num_setenv;
1651
		while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
1729
		while ((arg = next_arg(&ac, &av)) != NULL) {
1652
			if (strchr(arg, '=') == NULL) {
1730
			if (strchr(arg, '=') == NULL) {
1653
				error("%s line %d: Invalid SetEnv.",
1731
				error("%s line %d: Invalid SetEnv.",
1654
				    filename, linenum);
1732
				    filename, linenum);
1655
				return -1;
1733
				goto out;
1656
			}
1734
			}
1657
			if (!*activep || value != 0)
1735
			if (!*activep || value != 0)
1658
				continue;
1736
				continue;
Lines 1660-1666 parse_pubkey_algos: Link Here
1660
			if (options->num_setenv >= INT_MAX) {
1738
			if (options->num_setenv >= INT_MAX) {
1661
				error("%s line %d: too many SetEnv.",
1739
				error("%s line %d: too many SetEnv.",
1662
				    filename, linenum);
1740
				    filename, linenum);
1663
				return -1;
1741
				goto out;
1664
			}
1742
			}
1665
			options->setenv = xrecallocarray(
1743
			options->setenv = xrecallocarray(
1666
			    options->setenv, options->num_setenv,
1744
			    options->setenv, options->num_setenv,
Lines 1681-1691 parse_pubkey_algos: Link Here
1681
	case oControlPersist:
1759
	case oControlPersist:
1682
		/* no/false/yes/true, or a time spec */
1760
		/* no/false/yes/true, or a time spec */
1683
		intptr = &options->control_persist;
1761
		intptr = &options->control_persist;
1684
		arg = strdelim(&s);
1762
		arg = next_arg(&ac, &av);
1685
		if (!arg || *arg == '\0') {
1763
		if (!arg || *arg == '\0') {
1686
			error("%.200s line %d: Missing ControlPersist"
1764
			error("%.200s line %d: Missing ControlPersist"
1687
			    " argument.", filename, linenum);
1765
			    " argument.", filename, linenum);
1688
			return -1;
1766
			goto out;
1689
		}
1767
		}
1690
		value = 0;
1768
		value = 0;
1691
		value2 = 0;	/* timeout */
1769
		value2 = 0;	/* timeout */
Lines 1698-1704 parse_pubkey_algos: Link Here
1698
		else {
1776
		else {
1699
			error("%.200s line %d: Bad ControlPersist argument.",
1777
			error("%.200s line %d: Bad ControlPersist argument.",
1700
			    filename, linenum);
1778
			    filename, linenum);
1701
			return -1;
1779
			goto out;
1702
		}
1780
		}
1703
		if (*activep && *intptr == -1) {
1781
		if (*activep && *intptr == -1) {
1704
			*intptr = value;
1782
			*intptr = value;
Lines 1716-1732 parse_pubkey_algos: Link Here
1716
		goto parse_multistate;
1794
		goto parse_multistate;
1717
1795
1718
	case oTunnelDevice:
1796
	case oTunnelDevice:
1719
		arg = strdelim(&s);
1797
		arg = next_arg(&ac, &av);
1720
		if (!arg || *arg == '\0') {
1798
		if (!arg || *arg == '\0') {
1721
			error("%.200s line %d: Missing argument.",
1799
			error("%.200s line %d: Missing argument.",
1722
			    filename, linenum);
1800
			    filename, linenum);
1723
			return -1;
1801
			goto out;
1724
		}
1802
		}
1725
		value = a2tun(arg, &value2);
1803
		value = a2tun(arg, &value2);
1726
		if (value == SSH_TUNID_ERR) {
1804
		if (value == SSH_TUNID_ERR) {
1727
			error("%.200s line %d: Bad tun device.",
1805
			error("%.200s line %d: Bad tun device.",
1728
			    filename, linenum);
1806
			    filename, linenum);
1729
			return -1;
1807
			goto out;
1730
		}
1808
		}
1731
		if (*activep) {
1809
		if (*activep) {
1732
			options->tun_local = value;
1810
			options->tun_local = value;
Lines 1754-1763 parse_pubkey_algos: Link Here
1754
		if (cmdline) {
1832
		if (cmdline) {
1755
			error("Include directive not supported as a "
1833
			error("Include directive not supported as a "
1756
			    "command-line option");
1834
			    "command-line option");
1757
			return -1;
1835
			goto out;
1758
		}
1836
		}
1759
		value = 0;
1837
		value = 0;
1760
		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1838
		while ((arg = next_arg(&ac, &av)) != NULL) {
1839
			if (*arg == '\0') {
1840
				error("%s line %d: keyword %s empty argument",
1841
				    filename, linenum, keyword);
1842
				goto out;
1843
			}
1761
			/*
1844
			/*
1762
			 * Ensure all paths are anchored. User configuration
1845
			 * Ensure all paths are anchored. User configuration
1763
			 * files may begin with '~/' but system configurations
1846
			 * files may begin with '~/' but system configurations
Lines 1768-1774 parse_pubkey_algos: Link Here
1768
			if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) {
1851
			if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) {
1769
				error("%.200s line %d: bad include path %s.",
1852
				error("%.200s line %d: bad include path %s.",
1770
				    filename, linenum, arg);
1853
				    filename, linenum, arg);
1771
				return -1;
1854
				goto out;
1772
			}
1855
			}
1773
			if (!path_absolute(arg) && *arg != '~') {
1856
			if (!path_absolute(arg) && *arg != '~') {
1774
				xasprintf(&arg2, "%s/%s",
1857
				xasprintf(&arg2, "%s/%s",
Lines 1786-1792 parse_pubkey_algos: Link Here
1786
			} else if (r != 0) {
1869
			} else if (r != 0) {
1787
				error("%.200s line %d: glob failed for %s.",
1870
				error("%.200s line %d: glob failed for %s.",
1788
				    filename, linenum, arg2);
1871
				    filename, linenum, arg2);
1789
				return -1;
1872
				goto out;
1790
			}
1873
			}
1791
			free(arg2);
1874
			free(arg2);
1792
			oactive = *activep;
1875
			oactive = *activep;
Lines 1805-1811 parse_pubkey_algos: Link Here
1805
					    "%.100s: %.100s", gl.gl_pathv[i],
1888
					    "%.100s: %.100s", gl.gl_pathv[i],
1806
					    strerror(errno));
1889
					    strerror(errno));
1807
					globfree(&gl);
1890
					globfree(&gl);
1808
					return -1;
1891
					goto out;
1809
				}
1892
				}
1810
				/*
1893
				/*
1811
				 * don't let Match in includes clobber the
1894
				 * don't let Match in includes clobber the
Lines 1818-1840 parse_pubkey_algos: Link Here
1818
			globfree(&gl);
1901
			globfree(&gl);
1819
		}
1902
		}
1820
		if (value != 0)
1903
		if (value != 0)
1821
			return value;
1904
			ret = value;
1822
		break;
1905
		break;
1823
1906
1824
	case oIPQoS:
1907
	case oIPQoS:
1825
		arg = strdelim(&s);
1908
		arg = next_arg(&ac, &av);
1826
		if ((value = parse_ipqos(arg)) == -1) {
1909
		if ((value = parse_ipqos(arg)) == -1) {
1827
			error("%s line %d: Bad IPQoS value: %s",
1910
			error("%s line %d: Bad IPQoS value: %s",
1828
			    filename, linenum, arg);
1911
			    filename, linenum, arg);
1829
			return -1;
1912
			goto out;
1830
		}
1913
		}
1831
		arg = strdelim(&s);
1914
		arg = next_arg(&ac, &av);
1832
		if (arg == NULL)
1915
		if (arg == NULL)
1833
			value2 = value;
1916
			value2 = value;
1834
		else if ((value2 = parse_ipqos(arg)) == -1) {
1917
		else if ((value2 = parse_ipqos(arg)) == -1) {
1835
			error("%s line %d: Bad IPQoS value: %s",
1918
			error("%s line %d: Bad IPQoS value: %s",
1836
			    filename, linenum, arg);
1919
			    filename, linenum, arg);
1837
			return -1;
1920
			goto out;
1838
		}
1921
		}
1839
		if (*activep) {
1922
		if (*activep) {
1840
			options->ip_qos_interactive = value;
1923
			options->ip_qos_interactive = value;
Lines 1857-1867 parse_pubkey_algos: Link Here
1857
1940
1858
	case oCanonicalDomains:
1941
	case oCanonicalDomains:
1859
		value = options->num_canonical_domains != 0;
1942
		value = options->num_canonical_domains != 0;
1860
		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1943
		i = 0;
1944
		while ((arg = next_arg(&ac, &av)) != NULL) {
1945
			if (*arg == '\0') {
1946
				error("%s line %d: keyword %s empty argument",
1947
				    filename, linenum, keyword);
1948
				goto out;
1949
			}
1950
			/* Allow "none" only in first position */
1951
			if (strcasecmp(arg, "none") == 0) {
1952
				if (i > 0 || ac > 0) {
1953
					error("%s line %d: keyword %s \"none\" "
1954
					    "argument must appear alone.",
1955
					    filename, linenum, keyword);
1956
					goto out;
1957
				}
1958
			}
1959
			i++;
1861
			if (!valid_domain(arg, 1, &errstr)) {
1960
			if (!valid_domain(arg, 1, &errstr)) {
1862
				error("%s line %d: %s", filename, linenum,
1961
				error("%s line %d: %s", filename, linenum,
1863
				    errstr);
1962
				    errstr);
1864
				return -1;
1963
				goto out;
1865
			}
1964
			}
1866
			if (!*activep || value)
1965
			if (!*activep || value)
1867
				continue;
1966
				continue;
Lines 1869-1875 parse_pubkey_algos: Link Here
1869
			    MAX_CANON_DOMAINS) {
1968
			    MAX_CANON_DOMAINS) {
1870
				error("%s line %d: too many hostname suffixes.",
1969
				error("%s line %d: too many hostname suffixes.",
1871
				    filename, linenum);
1970
				    filename, linenum);
1872
				return -1;
1971
				goto out;
1873
			}
1972
			}
1874
			options->canonical_domains[
1973
			options->canonical_domains[
1875
			    options->num_canonical_domains++] = xstrdup(arg);
1974
			    options->num_canonical_domains++] = xstrdup(arg);
Lines 1878-1884 parse_pubkey_algos: Link Here
1878
1977
1879
	case oCanonicalizePermittedCNAMEs:
1978
	case oCanonicalizePermittedCNAMEs:
1880
		value = options->num_permitted_cnames != 0;
1979
		value = options->num_permitted_cnames != 0;
1881
		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1980
		while ((arg = next_arg(&ac, &av)) != NULL) {
1882
			/* Either '*' for everything or 'list:list' */
1981
			/* Either '*' for everything or 'list:list' */
1883
			if (strcmp(arg, "*") == 0)
1982
			if (strcmp(arg, "*") == 0)
1884
				arg2 = arg;
1983
				arg2 = arg;
Lines 1889-1895 parse_pubkey_algos: Link Here
1889
					error("%s line %d: "
1988
					error("%s line %d: "
1890
					    "Invalid permitted CNAME \"%s\"",
1989
					    "Invalid permitted CNAME \"%s\"",
1891
					    filename, linenum, arg);
1990
					    filename, linenum, arg);
1892
					return -1;
1991
					goto out;
1893
				}
1992
				}
1894
				*arg2 = '\0';
1993
				*arg2 = '\0';
1895
				arg2++;
1994
				arg2++;
Lines 1900-1906 parse_pubkey_algos: Link Here
1900
			    MAX_CANON_DOMAINS) {
1999
			    MAX_CANON_DOMAINS) {
1901
				error("%s line %d: too many permitted CNAMEs.",
2000
				error("%s line %d: too many permitted CNAMEs.",
1902
				    filename, linenum);
2001
				    filename, linenum);
1903
				return -1;
2002
				goto out;
1904
			}
2003
			}
1905
			cname = options->permitted_cnames +
2004
			cname = options->permitted_cnames +
1906
			    options->num_permitted_cnames++;
2005
			    options->num_permitted_cnames++;
Lines 1923-1939 parse_pubkey_algos: Link Here
1923
		goto parse_flag;
2022
		goto parse_flag;
1924
2023
1925
	case oStreamLocalBindMask:
2024
	case oStreamLocalBindMask:
1926
		arg = strdelim(&s);
2025
		arg = next_arg(&ac, &av);
1927
		if (!arg || *arg == '\0') {
2026
		if (!arg || *arg == '\0') {
1928
			error("%.200s line %d: Missing StreamLocalBindMask "
2027
			error("%.200s line %d: Missing StreamLocalBindMask "
1929
			    "argument.", filename, linenum);
2028
			    "argument.", filename, linenum);
1930
			return -1;
2029
			goto out;
1931
		}
2030
		}
1932
		/* Parse mode in octal format */
2031
		/* Parse mode in octal format */
1933
		value = strtol(arg, &endofnumber, 8);
2032
		value = strtol(arg, &endofnumber, 8);
1934
		if (arg == endofnumber || value < 0 || value > 0777) {
2033
		if (arg == endofnumber || value < 0 || value > 0777) {
1935
			error("%.200s line %d: Bad mask.", filename, linenum);
2034
			error("%.200s line %d: Bad mask.", filename, linenum);
1936
			return -1;
2035
			goto out;
1937
		}
2036
		}
1938
		options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2037
		options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1939
		break;
2038
		break;
Lines 1948-1963 parse_pubkey_algos: Link Here
1948
2047
1949
	case oFingerprintHash:
2048
	case oFingerprintHash:
1950
		intptr = &options->fingerprint_hash;
2049
		intptr = &options->fingerprint_hash;
1951
		arg = strdelim(&s);
2050
		arg = next_arg(&ac, &av);
1952
		if (!arg || *arg == '\0') {
2051
		if (!arg || *arg == '\0') {
1953
			error("%.200s line %d: Missing argument.",
2052
			error("%.200s line %d: Missing argument.",
1954
			    filename, linenum);
2053
			    filename, linenum);
1955
			return -1;
2054
			goto out;
1956
		}
2055
		}
1957
		if ((value = ssh_digest_alg_by_name(arg)) == -1) {
2056
		if ((value = ssh_digest_alg_by_name(arg)) == -1) {
1958
			error("%.200s line %d: Invalid hash algorithm \"%s\".",
2057
			error("%.200s line %d: Invalid hash algorithm \"%s\".",
1959
			    filename, linenum, arg);
2058
			    filename, linenum, arg);
1960
			return -1;
2059
			goto out;
1961
		}
2060
		}
1962
		if (*activep && *intptr == -1)
2061
		if (*activep && *intptr == -1)
1963
			*intptr = value;
2062
			*intptr = value;
Lines 1977-1984 parse_pubkey_algos: Link Here
1977
		goto parse_pubkey_algos;
2076
		goto parse_pubkey_algos;
1978
2077
1979
	case oAddKeysToAgent:
2078
	case oAddKeysToAgent:
1980
		arg = strdelim(&s);
2079
		arg = next_arg(&ac, &av);
1981
		arg2 = strdelim(&s);
2080
		arg2 = next_arg(&ac, &av);
1982
		value = parse_multistate_value(arg, filename, linenum,
2081
		value = parse_multistate_value(arg, filename, linenum,
1983
		    multistate_yesnoaskconfirm);
2082
		    multistate_yesnoaskconfirm);
1984
		value2 = 0; /* unlimited lifespan by default */
2083
		value2 = 0; /* unlimited lifespan by default */
Lines 1988-2007 parse_pubkey_algos: Link Here
1988
			    value2 > INT_MAX) {
2087
			    value2 > INT_MAX) {
1989
				error("%s line %d: invalid time value.",
2088
				error("%s line %d: invalid time value.",
1990
				    filename, linenum);
2089
				    filename, linenum);
1991
				return -1;
2090
				goto out;
1992
			}
2091
			}
1993
		} else if (value == -1 && arg2 == NULL) {
2092
		} else if (value == -1 && arg2 == NULL) {
1994
			if ((value2 = convtime(arg)) == -1 ||
2093
			if ((value2 = convtime(arg)) == -1 ||
1995
			    value2 > INT_MAX) {
2094
			    value2 > INT_MAX) {
1996
				error("%s line %d: unsupported option",
2095
				error("%s line %d: unsupported option",
1997
				    filename, linenum);
2096
				    filename, linenum);
1998
				return -1;
2097
				goto out;
1999
			}
2098
			}
2000
			value = 1; /* yes */
2099
			value = 1; /* yes */
2001
		} else if (value == -1 || arg2 != NULL) {
2100
		} else if (value == -1 || arg2 != NULL) {
2002
			error("%s line %d: unsupported option",
2101
			error("%s line %d: unsupported option",
2003
			    filename, linenum);
2102
			    filename, linenum);
2004
			return -1;
2103
			goto out;
2005
		}
2104
		}
2006
		if (*activep && options->add_keys_to_agent == -1) {
2105
		if (*activep && options->add_keys_to_agent == -1) {
2007
			options->add_keys_to_agent = value;
2106
			options->add_keys_to_agent = value;
Lines 2011-2028 parse_pubkey_algos: Link Here
2011
2110
2012
	case oIdentityAgent:
2111
	case oIdentityAgent:
2013
		charptr = &options->identity_agent;
2112
		charptr = &options->identity_agent;
2014
		arg = strdelim(&s);
2113
		arg = next_arg(&ac, &av);
2015
		if (!arg || *arg == '\0') {
2114
		if (!arg || *arg == '\0') {
2016
			error("%.200s line %d: Missing argument.",
2115
			error("%.200s line %d: Missing argument.",
2017
			    filename, linenum);
2116
			    filename, linenum);
2018
			return -1;
2117
			goto out;
2019
		}
2118
		}
2020
  parse_agent_path:
2119
  parse_agent_path:
2021
		/* Extra validation if the string represents an env var. */
2120
		/* Extra validation if the string represents an env var. */
2022
		if ((arg2 = dollar_expand(&r, arg)) == NULL || r) {
2121
		if ((arg2 = dollar_expand(&r, arg)) == NULL || r) {
2023
			error("%.200s line %d: Invalid environment expansion "
2122
			error("%.200s line %d: Invalid environment expansion "
2024
			    "%s.", filename, linenum, arg);
2123
			    "%s.", filename, linenum, arg);
2025
			return -1;
2124
			goto out;
2026
		}
2125
		}
2027
		free(arg2);
2126
		free(arg2);
2028
		/* check for legacy environment format */
2127
		/* check for legacy environment format */
Lines 2030-2036 parse_pubkey_algos: Link Here
2030
		    !valid_env_name(arg + 1)) {
2129
		    !valid_env_name(arg + 1)) {
2031
			error("%.200s line %d: Invalid environment name %s.",
2130
			error("%.200s line %d: Invalid environment name %s.",
2032
			    filename, linenum, arg);
2131
			    filename, linenum, arg);
2033
			return -1;
2132
			goto out;
2034
		}
2133
		}
2035
		if (*activep && *charptr == NULL)
2134
		if (*activep && *charptr == NULL)
2036
			*charptr = xstrdup(arg);
2135
			*charptr = xstrdup(arg);
Lines 2039-2063 parse_pubkey_algos: Link Here
2039
	case oDeprecated:
2138
	case oDeprecated:
2040
		debug("%s line %d: Deprecated option \"%s\"",
2139
		debug("%s line %d: Deprecated option \"%s\"",
2041
		    filename, linenum, keyword);
2140
		    filename, linenum, keyword);
2042
		return 0;
2141
		consume_args(&ac);
2142
		break;
2043
2143
2044
	case oUnsupported:
2144
	case oUnsupported:
2045
		error("%s line %d: Unsupported option \"%s\"",
2145
		error("%s line %d: Unsupported option \"%s\"",
2046
		    filename, linenum, keyword);
2146
		    filename, linenum, keyword);
2047
		return 0;
2147
		consume_args(&ac);
2148
		break;
2048
2149
2049
	default:
2150
	default:
2050
		error("%s line %d: Unimplemented opcode %d",
2151
		error("%s line %d: Unimplemented opcode %d",
2051
		    filename, linenum, opcode);
2152
		    filename, linenum, opcode);
2153
		goto out;
2052
	}
2154
	}
2053
2155
2054
	/* Check that there is no garbage at end of line. */
2156
	/* Check that there is no garbage at end of line. */
2055
	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
2157
	if (ac > 0) {
2056
		error("%.200s line %d: garbage at end of line; \"%.200s\".",
2158
		error("%.200s line %d: keyword %s extra arguments "
2057
		    filename, linenum, arg);
2159
		    "at end of line", filename, linenum, keyword);
2058
		return -1;
2160
		goto out;
2059
	}
2161
	}
2060
	return 0;
2162
2163
	/* success */
2164
	ret = 0;
2165
 out:
2166
	for (ac = 0; ac < oac; ac++)
2167
		free(oav[ac]);
2168
	free(oav);
2169
	return ret;
2061
}
2170
}
2062
2171
2063
/*
2172
/*
Lines 2083-2089 read_config_file_depth(const char *filename, struct passwd *pw, Link Here
2083
    int flags, int *activep, int *want_final_pass, int depth)
2192
    int flags, int *activep, int *want_final_pass, int depth)
2084
{
2193
{
2085
	FILE *f;
2194
	FILE *f;
2086
	char *cp, *line = NULL;
2195
	char *line = NULL;
2087
	size_t linesize = 0;
2196
	size_t linesize = 0;
2088
	int linenum;
2197
	int linenum;
2089
	int bad_options = 0;
2198
	int bad_options = 0;
Lines 2119-2126 read_config_file_depth(const char *filename, struct passwd *pw, Link Here
2119
		 * NB - preserve newlines, they are needed to reproduce
2228
		 * NB - preserve newlines, they are needed to reproduce
2120
		 * line numbers later for error messages.
2229
		 * line numbers later for error messages.
2121
		 */
2230
		 */
2122
		if ((cp = strchr(line, '#')) != NULL)
2123
			*cp = '\0';
2124
		if (process_config_line_depth(options, pw, host, original_host,
2231
		if (process_config_line_depth(options, pw, host, original_host,
2125
		    line, filename, linenum, activep, flags, want_final_pass,
2232
		    line, filename, linenum, activep, flags, want_final_pass,
2126
		    depth) != 0)
2233
		    depth) != 0)
Lines 2998-3003 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) Link Here
2998
	u_int i;
3105
	u_int i;
2999
3106
3000
	printf("%s", lookup_opcode_name(code));
3107
	printf("%s", lookup_opcode_name(code));
3108
	if (count == 0)
3109
		printf(" none");
3001
	for (i = 0; i < count; i++)
3110
	for (i = 0; i < count; i++)
3002
		printf(" %s",  vals[i]);
3111
		printf(" %s",  vals[i]);
3003
	printf("\n");
3112
	printf("\n");
(-)a/servconf.c (-164 / +213 lines)
Lines 1197-1209 static const struct multistate multistate_tcpfwd[] = { Link Here
1197
	{ NULL, -1 }
1197
	{ NULL, -1 }
1198
};
1198
};
1199
1199
1200
static char *
1201
next_arg(int *argcp, char ***argvp)
1202
{
1203
	char *ret = (*argvp)[0];
1204
1205
	if (*argcp > 0 && ret != NULL) {
1206
		(*argcp)--;
1207
		(*argvp)++;
1208
	}
1209
	return ret;
1210
}
1211
1212
static void
1213
consume_args(int *argcp)
1214
{
1215
	*argcp = 0;
1216
}
1217
1200
static int
1218
static int
1201
process_server_config_line_depth(ServerOptions *options, char *line,
1219
process_server_config_line_depth(ServerOptions *options, char *line,
1202
    const char *filename, int linenum, int *activep,
1220
    const char *filename, int linenum, int *activep,
1203
    struct connection_info *connectinfo, int *inc_flags, int depth,
1221
    struct connection_info *connectinfo, int *inc_flags, int depth,
1204
    struct include_list *includes)
1222
    struct include_list *includes)
1205
{
1223
{
1206
	char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
1224
	char ch, *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
1207
	int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
1225
	int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
1208
	SyslogFacility *log_facility_ptr;
1226
	SyslogFacility *log_facility_ptr;
1209
	LogLevel *log_level_ptr;
1227
	LogLevel *log_level_ptr;
Lines 1215-1220 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1215
	const char *errstr;
1233
	const char *errstr;
1216
	struct include_item *item;
1234
	struct include_item *item;
1217
	glob_t gbuf;
1235
	glob_t gbuf;
1236
	char **oav = NULL, **av;
1237
	int oac = 0, ac;
1238
	int ret = -1;
1218
1239
1219
	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1240
	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1220
	if ((len = strlen(line)) == 0)
1241
	if ((len = strlen(line)) == 0)
Lines 1225-1270 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1225
		line[len] = '\0';
1246
		line[len] = '\0';
1226
	}
1247
	}
1227
1248
1228
	cp = line;
1249
	str = line;
1229
	if ((arg = strdelim(&cp)) == NULL)
1250
	if ((keyword = strdelim(&str)) == NULL)
1230
		return 0;
1251
		return 0;
1231
	/* Ignore leading whitespace */
1252
	/* Ignore leading whitespace */
1232
	if (*arg == '\0')
1253
	if (*keyword == '\0')
1233
		arg = strdelim(&cp);
1254
		keyword = strdelim(&str);
1234
	if (!arg || !*arg || *arg == '#')
1255
	if (!keyword || !*keyword || *keyword == '#')
1235
		return 0;
1256
		return 0;
1257
	if (str == NULL || *str == '\0') {
1258
		error("%s line %d: no argument after keyword \"%s\"",
1259
		    filename, linenum, keyword);
1260
		return -1;
1261
	}
1236
	intptr = NULL;
1262
	intptr = NULL;
1237
	charptr = NULL;
1263
	charptr = NULL;
1238
	opcode = parse_token(arg, filename, linenum, &flags);
1264
	opcode = parse_token(keyword, filename, linenum, &flags);
1265
1266
	if (argv_split(str, &oac, &oav, 1) != 0) {
1267
		error("%s line %d: invalid quotes", filename, linenum);
1268
		return -1;
1269
	}
1270
	ac = oac;
1271
	av = oav;
1239
1272
1240
	if (activep == NULL) { /* We are processing a command line directive */
1273
	if (activep == NULL) { /* We are processing a command line directive */
1241
		cmdline = 1;
1274
		cmdline = 1;
1242
		activep = &cmdline;
1275
		activep = &cmdline;
1243
	}
1276
	}
1244
	if (*activep && opcode != sMatch && opcode != sInclude)
1277
	if (*activep && opcode != sMatch && opcode != sInclude)
1245
		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
1278
		debug3("%s:%d setting %s %s", filename, linenum, keyword, str);
1246
	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1279
	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1247
		if (connectinfo == NULL) {
1280
		if (connectinfo == NULL) {
1248
			fatal("%s line %d: Directive '%s' is not allowed "
1281
			fatal("%s line %d: Directive '%s' is not allowed "
1249
			    "within a Match block", filename, linenum, arg);
1282
			    "within a Match block", filename, linenum, keyword);
1250
		} else { /* this is a directive we have already processed */
1283
		} else { /* this is a directive we have already processed */
1251
			while (arg)
1284
			ret = 0;
1252
				arg = strdelim(&cp);
1285
			goto out;
1253
			return 0;
1254
		}
1286
		}
1255
	}
1287
	}
1256
1288
1257
	switch (opcode) {
1289
	switch (opcode) {
1258
	case sBadOption:
1290
	case sBadOption:
1259
		return -1;
1291
		goto out;
1260
	case sPort:
1292
	case sPort:
1261
		/* ignore ports from configfile if cmdline specifies ports */
1293
		/* ignore ports from configfile if cmdline specifies ports */
1262
		if (options->ports_from_cmdline)
1294
		if (options->ports_from_cmdline) {
1263
			return 0;
1295
			consume_args(&ac);
1296
			break;
1297
		}
1264
		if (options->num_ports >= MAX_PORTS)
1298
		if (options->num_ports >= MAX_PORTS)
1265
			fatal("%s line %d: too many ports.",
1299
			fatal("%s line %d: too many ports.",
1266
			    filename, linenum);
1300
			    filename, linenum);
1267
		arg = strdelim(&cp);
1301
		arg = next_arg(&ac, &av);
1268
		if (!arg || *arg == '\0')
1302
		if (!arg || *arg == '\0')
1269
			fatal("%s line %d: missing port number.",
1303
			fatal("%s line %d: missing port number.",
1270
			    filename, linenum);
1304
			    filename, linenum);
Lines 1277-1283 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1277
	case sLoginGraceTime:
1311
	case sLoginGraceTime:
1278
		intptr = &options->login_grace_time;
1312
		intptr = &options->login_grace_time;
1279
 parse_time:
1313
 parse_time:
1280
		arg = strdelim(&cp);
1314
		arg = next_arg(&ac, &av);
1281
		if (!arg || *arg == '\0')
1315
		if (!arg || *arg == '\0')
1282
			fatal("%s line %d: missing time value.",
1316
			fatal("%s line %d: missing time value.",
1283
			    filename, linenum);
1317
			    filename, linenum);
Lines 1289-1295 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1289
		break;
1323
		break;
1290
1324
1291
	case sListenAddress:
1325
	case sListenAddress:
1292
		arg = strdelim(&cp);
1326
		arg = next_arg(&ac, &av);
1293
		if (arg == NULL || *arg == '\0')
1327
		if (arg == NULL || *arg == '\0')
1294
			fatal("%s line %d: missing address",
1328
			fatal("%s line %d: missing address",
1295
			    filename, linenum);
1329
			    filename, linenum);
Lines 1314-1322 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1314
		}
1348
		}
1315
		/* Optional routing table */
1349
		/* Optional routing table */
1316
		arg2 = NULL;
1350
		arg2 = NULL;
1317
		if ((arg = strdelim(&cp)) != NULL) {
1351
		if ((arg = next_arg(&ac, &av)) != NULL) {
1318
			if (strcmp(arg, "rdomain") != 0 ||
1352
			if (strcmp(arg, "rdomain") != 0 ||
1319
			    (arg2 = strdelim(&cp)) == NULL)
1353
			    (arg2 = next_arg(&ac, &av)) == NULL)
1320
				fatal("%s line %d: bad ListenAddress syntax",
1354
				fatal("%s line %d: bad ListenAddress syntax",
1321
				    filename, linenum);
1355
				    filename, linenum);
1322
			if (!valid_rdomain(arg2))
1356
			if (!valid_rdomain(arg2))
Lines 1332-1338 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1332
		intptr = &options->address_family;
1366
		intptr = &options->address_family;
1333
		multistate_ptr = multistate_addressfamily;
1367
		multistate_ptr = multistate_addressfamily;
1334
 parse_multistate:
1368
 parse_multistate:
1335
		arg = strdelim(&cp);
1369
		arg = next_arg(&ac, &av);
1336
		if (!arg || *arg == '\0')
1370
		if (!arg || *arg == '\0')
1337
			fatal("%s line %d: missing argument.",
1371
			fatal("%s line %d: missing argument.",
1338
			    filename, linenum);
1372
			    filename, linenum);
Lines 1351-1357 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1351
		break;
1385
		break;
1352
1386
1353
	case sHostKeyFile:
1387
	case sHostKeyFile:
1354
		arg = strdelim(&cp);
1388
		arg = next_arg(&ac, &av);
1355
		if (!arg || *arg == '\0')
1389
		if (!arg || *arg == '\0')
1356
			fatal("%s line %d: missing file name.",
1390
			fatal("%s line %d: missing file name.",
1357
			    filename, linenum);
1391
			    filename, linenum);
Lines 1363-1369 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1363
1397
1364
	case sHostKeyAgent:
1398
	case sHostKeyAgent:
1365
		charptr = &options->host_key_agent;
1399
		charptr = &options->host_key_agent;
1366
		arg = strdelim(&cp);
1400
		arg = next_arg(&ac, &av);
1367
		if (!arg || *arg == '\0')
1401
		if (!arg || *arg == '\0')
1368
			fatal("%s line %d: missing socket name.",
1402
			fatal("%s line %d: missing socket name.",
1369
			    filename, linenum);
1403
			    filename, linenum);
Lines 1373-1379 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1373
		break;
1407
		break;
1374
1408
1375
	case sHostCertificate:
1409
	case sHostCertificate:
1376
		arg = strdelim(&cp);
1410
		arg = next_arg(&ac, &av);
1377
		if (!arg || *arg == '\0')
1411
		if (!arg || *arg == '\0')
1378
			fatal("%s line %d: missing file name.",
1412
			fatal("%s line %d: missing file name.",
1379
			    filename, linenum);
1413
			    filename, linenum);
Lines 1384-1390 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1384
	case sPidFile:
1418
	case sPidFile:
1385
		charptr = &options->pid_file;
1419
		charptr = &options->pid_file;
1386
 parse_filename:
1420
 parse_filename:
1387
		arg = strdelim(&cp);
1421
		arg = next_arg(&ac, &av);
1388
		if (!arg || *arg == '\0')
1422
		if (!arg || *arg == '\0')
1389
			fatal("%s line %d: missing file name.",
1423
			fatal("%s line %d: missing file name.",
1390
			    filename, linenum);
1424
			    filename, linenum);
Lines 1427-1433 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1427
	case sHostbasedAcceptedAlgorithms:
1461
	case sHostbasedAcceptedAlgorithms:
1428
		charptr = &options->hostbased_accepted_algos;
1462
		charptr = &options->hostbased_accepted_algos;
1429
 parse_pubkey_algos:
1463
 parse_pubkey_algos:
1430
		arg = strdelim(&cp);
1464
		arg = next_arg(&ac, &av);
1431
		if (!arg || *arg == '\0')
1465
		if (!arg || *arg == '\0')
1432
			fatal("%s line %d: Missing argument.",
1466
			fatal("%s line %d: Missing argument.",
1433
			    filename, linenum);
1467
			    filename, linenum);
Lines 1459-1465 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1459
	case sPubkeyAuthOptions:
1493
	case sPubkeyAuthOptions:
1460
		intptr = &options->pubkey_auth_options;
1494
		intptr = &options->pubkey_auth_options;
1461
		value = 0;
1495
		value = 0;
1462
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1496
		while ((arg = next_arg(&ac, &av)) != NULL) {
1463
			if (strcasecmp(arg, "none") == 0)
1497
			if (strcasecmp(arg, "none") == 0)
1464
				continue;
1498
				continue;
1465
			if (strcasecmp(arg, "touch-required") == 0)
1499
			if (strcasecmp(arg, "touch-required") == 0)
Lines 1467-1475 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1467
			else if (strcasecmp(arg, "verify-required") == 0)
1501
			else if (strcasecmp(arg, "verify-required") == 0)
1468
				value |= PUBKEYAUTH_VERIFY_REQUIRED;
1502
				value |= PUBKEYAUTH_VERIFY_REQUIRED;
1469
			else {
1503
			else {
1470
				fatal("%s line %d: unsupported "
1504
				error("%s line %d: unsupported "
1471
				    "PubkeyAuthOptions option %s",
1505
				    "PubkeyAuthOptions option %s",
1472
				    filename, linenum, arg);
1506
				    filename, linenum, arg);
1507
				goto out;
1473
			}
1508
			}
1474
		}
1509
		}
1475
		if (*activep && *intptr == -1)
1510
		if (*activep && *intptr == -1)
Lines 1531-1537 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1531
	case sX11DisplayOffset:
1566
	case sX11DisplayOffset:
1532
		intptr = &options->x11_display_offset;
1567
		intptr = &options->x11_display_offset;
1533
 parse_int:
1568
 parse_int:
1534
		arg = strdelim(&cp);
1569
		arg = next_arg(&ac, &av);
1535
		if ((errstr = atoi_err(arg, &value)) != NULL)
1570
		if ((errstr = atoi_err(arg, &value)) != NULL)
1536
			fatal("%s line %d: integer value %s.",
1571
			fatal("%s line %d: integer value %s.",
1537
			    filename, linenum, errstr);
1572
			    filename, linenum, errstr);
Lines 1570-1576 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1570
	case sPermitUserEnvironment:
1605
	case sPermitUserEnvironment:
1571
		intptr = &options->permit_user_env;
1606
		intptr = &options->permit_user_env;
1572
		charptr = &options->permit_user_env_allowlist;
1607
		charptr = &options->permit_user_env_allowlist;
1573
		arg = strdelim(&cp);
1608
		arg = next_arg(&ac, &av);
1574
		if (!arg || *arg == '\0')
1609
		if (!arg || *arg == '\0')
1575
			fatal("%s line %d: missing argument.",
1610
			fatal("%s line %d: missing argument.",
1576
			    filename, linenum);
1611
			    filename, linenum);
Lines 1599-1605 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1599
		goto parse_multistate;
1634
		goto parse_multistate;
1600
1635
1601
	case sRekeyLimit:
1636
	case sRekeyLimit:
1602
		arg = strdelim(&cp);
1637
		arg = next_arg(&ac, &av);
1603
		if (!arg || *arg == '\0')
1638
		if (!arg || *arg == '\0')
1604
			fatal("%.200s line %d: Missing argument.", filename,
1639
			fatal("%.200s line %d: Missing argument.", filename,
1605
			    linenum);
1640
			    linenum);
Lines 1615-1623 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1615
		}
1650
		}
1616
		if (*activep && options->rekey_limit == -1)
1651
		if (*activep && options->rekey_limit == -1)
1617
			options->rekey_limit = val64;
1652
			options->rekey_limit = val64;
1618
		if (cp != NULL) { /* optional rekey interval present */
1653
		if (ac != 0) { /* optional rekey interval present */
1619
			if (strcmp(cp, "none") == 0) {
1654
			if (strcmp(av[0], "none") == 0) {
1620
				(void)strdelim(&cp);	/* discard */
1655
				(void)next_arg(&ac, &av);	/* discard */
1621
				break;
1656
				break;
1622
			}
1657
			}
1623
			intptr = &options->rekey_interval;
1658
			intptr = &options->rekey_interval;
Lines 1636-1642 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1636
1671
1637
	case sLogFacility:
1672
	case sLogFacility:
1638
		log_facility_ptr = &options->log_facility;
1673
		log_facility_ptr = &options->log_facility;
1639
		arg = strdelim(&cp);
1674
		arg = next_arg(&ac, &av);
1640
		value = log_facility_number(arg);
1675
		value = log_facility_number(arg);
1641
		if (value == SYSLOG_FACILITY_NOT_SET)
1676
		if (value == SYSLOG_FACILITY_NOT_SET)
1642
			fatal("%.200s line %d: unsupported log facility '%s'",
1677
			fatal("%.200s line %d: unsupported log facility '%s'",
Lines 1647-1653 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1647
1682
1648
	case sLogLevel:
1683
	case sLogLevel:
1649
		log_level_ptr = &options->log_level;
1684
		log_level_ptr = &options->log_level;
1650
		arg = strdelim(&cp);
1685
		arg = next_arg(&ac, &av);
1651
		value = log_level_number(arg);
1686
		value = log_level_number(arg);
1652
		if (value == SYSLOG_LEVEL_NOT_SET)
1687
		if (value == SYSLOG_LEVEL_NOT_SET)
1653
			fatal("%.200s line %d: unsupported log level '%s'",
1688
			fatal("%.200s line %d: unsupported log level '%s'",
Lines 1657-1663 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1657
		break;
1692
		break;
1658
1693
1659
	case sLogVerbose:
1694
	case sLogVerbose:
1660
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1695
		i = 0;
1696
		while ((arg = next_arg(&ac, &av)) != NULL) {
1697
			if (*arg == '\0') {
1698
				error("%s line %d: keyword %s empty argument",
1699
				    filename, linenum, keyword);
1700
				goto out;
1701
			}
1702
			/* Allow "none" only in first position */
1703
			if (strcasecmp(arg, "none") == 0) {
1704
				if (i > 0 || ac > 0) {
1705
					error("%s line %d: keyword %s \"none\" "
1706
					    "argument must appear alone.",
1707
					    filename, linenum, keyword);
1708
					goto out;
1709
				}
1710
			}
1711
			i++;
1661
			if (!*activep)
1712
			if (!*activep)
1662
				continue;
1713
				continue;
1663
			opt_array_append(filename, linenum, "oLogVerbose",
1714
			opt_array_append(filename, linenum, "oLogVerbose",
Lines 1685-1737 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1685
		goto parse_flag;
1736
		goto parse_flag;
1686
1737
1687
	case sAllowUsers:
1738
	case sAllowUsers:
1688
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1739
		chararrayptr = &options->allow_users;
1689
			if (match_user(NULL, NULL, NULL, arg) == -1)
1740
		uintptr = &options->num_allow_users;
1690
				fatal("%s line %d: invalid AllowUsers pattern: "
1741
 parse_allowdenyusers:
1691
				    "\"%.100s\"", filename, linenum, arg);
1742
		while ((arg = next_arg(&ac, &av)) != NULL) {
1743
			if (*arg == '\0' ||
1744
			    match_user(NULL, NULL, NULL, arg) == -1)
1745
				fatal("%s line %d: invalid %s pattern: \"%s\"",
1746
				    filename, linenum, keyword, arg);
1692
			if (!*activep)
1747
			if (!*activep)
1693
				continue;
1748
				continue;
1694
			opt_array_append(filename, linenum, "AllowUsers",
1749
			opt_array_append(filename, linenum, keyword,
1695
			    &options->allow_users, &options->num_allow_users,
1750
			    chararrayptr, uintptr, arg);
1696
			    arg);
1697
		}
1751
		}
1698
		break;
1752
		break;
1699
1753
1700
	case sDenyUsers:
1754
	case sDenyUsers:
1701
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1755
		chararrayptr = &options->deny_users;
1702
			if (match_user(NULL, NULL, NULL, arg) == -1)
1756
		uintptr = &options->num_deny_users;
1703
				fatal("%s line %d: invalid DenyUsers pattern: "
1757
		goto parse_allowdenyusers;
1704
				    "\"%.100s\"", filename, linenum, arg);
1705
			if (!*activep)
1706
				continue;
1707
			opt_array_append(filename, linenum, "DenyUsers",
1708
			    &options->deny_users, &options->num_deny_users,
1709
			    arg);
1710
		}
1711
		break;
1712
1758
1713
	case sAllowGroups:
1759
	case sAllowGroups:
1714
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1760
		chararrayptr = &options->allow_groups;
1761
		uintptr = &options->num_allow_groups;
1762
 parse_allowdenygroups:
1763
		while ((arg = next_arg(&ac, &av)) != NULL) {
1764
			if (*arg == '\0')
1765
				fatal("%s line %d: empty %s pattern",
1766
				    filename, linenum, keyword);
1715
			if (!*activep)
1767
			if (!*activep)
1716
				continue;
1768
				continue;
1717
			opt_array_append(filename, linenum, "AllowGroups",
1769
			opt_array_append(filename, linenum, keyword,
1718
			    &options->allow_groups, &options->num_allow_groups,
1770
			    chararrayptr, uintptr, arg);
1719
			    arg);
1720
		}
1771
		}
1721
		break;
1772
		break;
1722
1773
1723
	case sDenyGroups:
1774
	case sDenyGroups:
1724
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1775
		chararrayptr = &options->deny_groups;
1725
			if (!*activep)
1776
		uintptr = &options->num_deny_groups;
1726
				continue;
1777
		goto parse_allowdenygroups;
1727
			opt_array_append(filename, linenum, "DenyGroups",
1728
			    &options->deny_groups, &options->num_deny_groups,
1729
			    arg);
1730
		}
1731
		break;
1732
1778
1733
	case sCiphers:
1779
	case sCiphers:
1734
		arg = strdelim(&cp);
1780
		arg = next_arg(&ac, &av);
1735
		if (!arg || *arg == '\0')
1781
		if (!arg || *arg == '\0')
1736
			fatal("%s line %d: Missing argument.", filename, linenum);
1782
			fatal("%s line %d: Missing argument.", filename, linenum);
1737
		if (*arg != '-' &&
1783
		if (*arg != '-' &&
Lines 1743-1749 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1743
		break;
1789
		break;
1744
1790
1745
	case sMacs:
1791
	case sMacs:
1746
		arg = strdelim(&cp);
1792
		arg = next_arg(&ac, &av);
1747
		if (!arg || *arg == '\0')
1793
		if (!arg || *arg == '\0')
1748
			fatal("%s line %d: Missing argument.", filename, linenum);
1794
			fatal("%s line %d: Missing argument.", filename, linenum);
1749
		if (*arg != '-' &&
1795
		if (*arg != '-' &&
Lines 1755-1761 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1755
		break;
1801
		break;
1756
1802
1757
	case sKexAlgorithms:
1803
	case sKexAlgorithms:
1758
		arg = strdelim(&cp);
1804
		arg = next_arg(&ac, &av);
1759
		if (!arg || *arg == '\0')
1805
		if (!arg || *arg == '\0')
1760
			fatal("%s line %d: Missing argument.",
1806
			fatal("%s line %d: Missing argument.",
1761
			    filename, linenum);
1807
			    filename, linenum);
Lines 1773-1784 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1773
			fatal("%s line %d: too many subsystems defined.",
1819
			fatal("%s line %d: too many subsystems defined.",
1774
			    filename, linenum);
1820
			    filename, linenum);
1775
		}
1821
		}
1776
		arg = strdelim(&cp);
1822
		arg = next_arg(&ac, &av);
1777
		if (!arg || *arg == '\0')
1823
		if (!arg || *arg == '\0')
1778
			fatal("%s line %d: Missing subsystem name.",
1824
			fatal("%s line %d: Missing subsystem name.",
1779
			    filename, linenum);
1825
			    filename, linenum);
1780
		if (!*activep) {
1826
		if (!*activep) {
1781
			arg = strdelim(&cp);
1827
			arg = next_arg(&ac, &av);
1782
			break;
1828
			break;
1783
		}
1829
		}
1784
		for (i = 0; i < options->num_subsystems; i++)
1830
		for (i = 0; i < options->num_subsystems; i++)
Lines 1786-1792 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1786
				fatal("%s line %d: Subsystem '%s' already defined.",
1832
				fatal("%s line %d: Subsystem '%s' already defined.",
1787
				    filename, linenum, arg);
1833
				    filename, linenum, arg);
1788
		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1834
		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1789
		arg = strdelim(&cp);
1835
		arg = next_arg(&ac, &av);
1790
		if (!arg || *arg == '\0')
1836
		if (!arg || *arg == '\0')
1791
			fatal("%s line %d: Missing subsystem command.",
1837
			fatal("%s line %d: Missing subsystem command.",
1792
			    filename, linenum);
1838
			    filename, linenum);
Lines 1795-1801 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1795
		/* Collect arguments (separate to executable) */
1841
		/* Collect arguments (separate to executable) */
1796
		p = xstrdup(arg);
1842
		p = xstrdup(arg);
1797
		len = strlen(p) + 1;
1843
		len = strlen(p) + 1;
1798
		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1844
		while ((arg = next_arg(&ac, &av)) != NULL) {
1799
			len += 1 + strlen(arg);
1845
			len += 1 + strlen(arg);
1800
			p = xreallocarray(p, 1, len);
1846
			p = xreallocarray(p, 1, len);
1801
			strlcat(p, " ", len);
1847
			strlcat(p, " ", len);
Lines 1806-1812 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1806
		break;
1852
		break;
1807
1853
1808
	case sMaxStartups:
1854
	case sMaxStartups:
1809
		arg = strdelim(&cp);
1855
		arg = next_arg(&ac, &av);
1810
		if (!arg || *arg == '\0')
1856
		if (!arg || *arg == '\0')
1811
			fatal("%s line %d: Missing MaxStartups spec.",
1857
			fatal("%s line %d: Missing MaxStartups spec.",
1812
			    filename, linenum);
1858
			    filename, linenum);
Lines 1828-1834 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1828
		break;
1874
		break;
1829
1875
1830
	case sPerSourceNetBlockSize:
1876
	case sPerSourceNetBlockSize:
1831
		arg = strdelim(&cp);
1877
		arg = next_arg(&ac, &av);
1832
		if (!arg || *arg == '\0')
1878
		if (!arg || *arg == '\0')
1833
			fatal("%s line %d: Missing PerSourceNetBlockSize spec.",
1879
			fatal("%s line %d: Missing PerSourceNetBlockSize spec.",
1834
			    filename, linenum);
1880
			    filename, linenum);
Lines 1851-1857 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1851
		break;
1897
		break;
1852
1898
1853
	case sPerSourceMaxStartups:
1899
	case sPerSourceMaxStartups:
1854
		arg = strdelim(&cp);
1900
		arg = next_arg(&ac, &av);
1855
		if (!arg || *arg == '\0')
1901
		if (!arg || *arg == '\0')
1856
			fatal("%s line %d: Missing PerSourceMaxStartups spec.",
1902
			fatal("%s line %d: Missing PerSourceMaxStartups spec.",
1857
			    filename, linenum);
1903
			    filename, linenum);
Lines 1885-1905 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1885
	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1931
	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1886
	 */
1932
	 */
1887
	case sAuthorizedKeysFile:
1933
	case sAuthorizedKeysFile:
1888
		if (*activep && options->num_authkeys_files == 0) {
1934
		uvalue = options->num_authkeys_files;
1889
			while ((arg = strdelim(&cp)) && *arg != '\0') {
1935
		while ((arg = next_arg(&ac, &av)) != NULL) {
1890
				arg = tilde_expand_filename(arg, getuid());
1936
			if (*arg == '\0') {
1937
				error("%s line %d: keyword %s empty argument",
1938
				    filename, linenum, keyword);
1939
				goto out;
1940
			}
1941
			arg2 = tilde_expand_filename(arg, getuid());
1942
			if (*activep && uvalue == 0) {
1891
				opt_array_append(filename, linenum,
1943
				opt_array_append(filename, linenum,
1892
				    "AuthorizedKeysFile",
1944
				    "AuthorizedKeysFile",
1893
				    &options->authorized_keys_files,
1945
				    &options->authorized_keys_files,
1894
				    &options->num_authkeys_files, arg);
1946
				    &options->num_authkeys_files, arg2);
1895
				free(arg);
1896
			}
1947
			}
1948
			free(arg2);
1897
		}
1949
		}
1898
		return 0;
1950
		break;
1899
1951
1900
	case sAuthorizedPrincipalsFile:
1952
	case sAuthorizedPrincipalsFile:
1901
		charptr = &options->authorized_principals_file;
1953
		charptr = &options->authorized_principals_file;
1902
		arg = strdelim(&cp);
1954
		arg = next_arg(&ac, &av);
1903
		if (!arg || *arg == '\0')
1955
		if (!arg || *arg == '\0')
1904
			fatal("%s line %d: missing file name.",
1956
			fatal("%s line %d: missing file name.",
1905
			    filename, linenum);
1957
			    filename, linenum);
Lines 1920-1927 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1920
		goto parse_int;
1972
		goto parse_int;
1921
1973
1922
	case sAcceptEnv:
1974
	case sAcceptEnv:
1923
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1975
		while ((arg = next_arg(&ac, &av)) != NULL) {
1924
			if (strchr(arg, '=') != NULL)
1976
			if (*arg == '\0' || strchr(arg, '=') != NULL)
1925
				fatal("%s line %d: Invalid environment name.",
1977
				fatal("%s line %d: Invalid environment name.",
1926
				    filename, linenum);
1978
				    filename, linenum);
1927
			if (!*activep)
1979
			if (!*activep)
Lines 1934-1941 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1934
1986
1935
	case sSetEnv:
1987
	case sSetEnv:
1936
		uvalue = options->num_setenv;
1988
		uvalue = options->num_setenv;
1937
		while ((arg = strdelimw(&cp)) && *arg != '\0') {
1989
		while ((arg = next_arg(&ac, &av)) != NULL) {
1938
			if (strchr(arg, '=') == NULL)
1990
			if (*arg == '\0' || strchr(arg, '=') == NULL)
1939
				fatal("%s line %d: Invalid environment.",
1991
				fatal("%s line %d: Invalid environment.",
1940
				    filename, linenum);
1992
				    filename, linenum);
1941
			if (!*activep || uvalue != 0)
1993
			if (!*activep || uvalue != 0)
Lines 1947-1953 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1947
1999
1948
	case sPermitTunnel:
2000
	case sPermitTunnel:
1949
		intptr = &options->permit_tun;
2001
		intptr = &options->permit_tun;
1950
		arg = strdelim(&cp);
2002
		arg = next_arg(&ac, &av);
1951
		if (!arg || *arg == '\0')
2003
		if (!arg || *arg == '\0')
1952
			fatal("%s line %d: Missing yes/point-to-point/"
2004
			fatal("%s line %d: Missing yes/point-to-point/"
1953
			    "ethernet/no argument.", filename, linenum);
2005
			    "ethernet/no argument.", filename, linenum);
Lines 1970-1976 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
1970
			    "command-line option");
2022
			    "command-line option");
1971
		}
2023
		}
1972
		value = 0;
2024
		value = 0;
1973
		while ((arg2 = strdelim(&cp)) != NULL && *arg2 != '\0') {
2025
		while ((arg2 = next_arg(&ac, &av)) != NULL) {
2026
			if (*arg2 == '\0') {
2027
				error("%s line %d: keyword %s empty argument",
2028
				    filename, linenum, keyword);
2029
				goto out;
2030
			}
1974
			value++;
2031
			value++;
1975
			found = 0;
2032
			found = 0;
1976
			if (*arg2 != '/' && *arg2 != '~') {
2033
			if (*arg2 != '/' && *arg2 != '~') {
Lines 2060-2066 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2060
		if (cmdline)
2117
		if (cmdline)
2061
			fatal("Match directive not supported as a command-line "
2118
			fatal("Match directive not supported as a command-line "
2062
			    "option");
2119
			    "option");
2063
		value = match_cfg_line(&cp, linenum,
2120
		value = match_cfg_line(&str, linenum,
2064
		    (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
2121
		    (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
2065
		if (value < 0)
2122
		if (value < 0)
2066
			fatal("%s line %d: Bad Match condition", filename,
2123
			fatal("%s line %d: Bad Match condition", filename,
Lines 2068-2073 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2068
		*activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
2125
		*activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
2069
		/* The MATCH_ONLY is applicable only until the first match block */
2126
		/* The MATCH_ONLY is applicable only until the first match block */
2070
		*inc_flags &= ~SSHCFG_MATCH_ONLY;
2127
		*inc_flags &= ~SSHCFG_MATCH_ONLY;
2128
		consume_args(&ac);
2071
		break;
2129
		break;
2072
2130
2073
	case sPermitListen:
2131
	case sPermitListen:
Lines 2079-2085 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2079
			uintptr = &options->num_permitted_opens;
2137
			uintptr = &options->num_permitted_opens;
2080
			chararrayptr = &options->permitted_opens;
2138
			chararrayptr = &options->permitted_opens;
2081
		}
2139
		}
2082
		arg = strdelim(&cp);
2140
		arg = next_arg(&ac, &av);
2083
		if (!arg || *arg == '\0')
2141
		if (!arg || *arg == '\0')
2084
			fatal("%s line %d: missing %s specification",
2142
			fatal("%s line %d: missing %s specification",
2085
			    filename, linenum, lookup_opcode_name(opcode));
2143
			    filename, linenum, lookup_opcode_name(opcode));
Lines 2093-2099 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2093
			}
2151
			}
2094
			break;
2152
			break;
2095
		}
2153
		}
2096
		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
2154
		for (; arg != NULL && *arg != '\0'; arg = next_arg(&ac, &av)) {
2097
			if (opcode == sPermitListen &&
2155
			if (opcode == sPermitListen &&
2098
			    strchr(arg, ':') == NULL) {
2156
			    strchr(arg, ':') == NULL) {
2099
				/*
2157
				/*
Lines 2128-2145 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2128
		break;
2186
		break;
2129
2187
2130
	case sForceCommand:
2188
	case sForceCommand:
2131
		if (cp == NULL || *cp == '\0')
2189
		if (str == NULL || *str == '\0')
2132
			fatal("%.200s line %d: Missing argument.", filename,
2190
			fatal("%.200s line %d: Missing argument.", filename,
2133
			    linenum);
2191
			    linenum);
2134
		len = strspn(cp, WHITESPACE);
2192
		len = strspn(str, WHITESPACE);
2135
		if (*activep && options->adm_forced_command == NULL)
2193
		if (*activep && options->adm_forced_command == NULL)
2136
			options->adm_forced_command = xstrdup(cp + len);
2194
			options->adm_forced_command = xstrdup(str + len);
2137
		return 0;
2195
		consume_args(&ac);
2196
		break;
2138
2197
2139
	case sChrootDirectory:
2198
	case sChrootDirectory:
2140
		charptr = &options->chroot_directory;
2199
		charptr = &options->chroot_directory;
2141
2200
2142
		arg = strdelim(&cp);
2201
		arg = next_arg(&ac, &av);
2143
		if (!arg || *arg == '\0')
2202
		if (!arg || *arg == '\0')
2144
			fatal("%s line %d: missing file name.",
2203
			fatal("%s line %d: missing file name.",
2145
			    filename, linenum);
2204
			    filename, linenum);
Lines 2157-2163 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2157
2216
2158
	case sSecurityKeyProvider:
2217
	case sSecurityKeyProvider:
2159
		charptr = &options->sk_provider;
2218
		charptr = &options->sk_provider;
2160
		arg = strdelim(&cp);
2219
		arg = next_arg(&ac, &av);
2161
		if (!arg || *arg == '\0')
2220
		if (!arg || *arg == '\0')
2162
			fatal("%s line %d: missing file name.",
2221
			fatal("%s line %d: missing file name.",
2163
			    filename, linenum);
2222
			    filename, linenum);
Lines 2171-2181 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2171
		break;
2230
		break;
2172
2231
2173
	case sIPQoS:
2232
	case sIPQoS:
2174
		arg = strdelim(&cp);
2233
		arg = next_arg(&ac, &av);
2175
		if ((value = parse_ipqos(arg)) == -1)
2234
		if ((value = parse_ipqos(arg)) == -1)
2176
			fatal("%s line %d: Bad IPQoS value: %s",
2235
			fatal("%s line %d: Bad IPQoS value: %s",
2177
			    filename, linenum, arg);
2236
			    filename, linenum, arg);
2178
		arg = strdelim(&cp);
2237
		arg = next_arg(&ac, &av);
2179
		if (arg == NULL)
2238
		if (arg == NULL)
2180
			value2 = value;
2239
			value2 = value;
2181
		else if ((value2 = parse_ipqos(arg)) == -1)
2240
		else if ((value2 = parse_ipqos(arg)) == -1)
Lines 2188-2266 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2188
		break;
2247
		break;
2189
2248
2190
	case sVersionAddendum:
2249
	case sVersionAddendum:
2191
		if (cp == NULL || *cp == '\0')
2250
		if (str == NULL || *str == '\0')
2192
			fatal("%.200s line %d: Missing argument.", filename,
2251
			fatal("%.200s line %d: Missing argument.", filename,
2193
			    linenum);
2252
			    linenum);
2194
		len = strspn(cp, WHITESPACE);
2253
		len = strspn(str, WHITESPACE);
2254
		if (strchr(str + len, '\r') != NULL) {
2255
			fatal("%.200s line %d: Invalid %s argument",
2256
			    filename, linenum, keyword);
2257
		}
2195
		if (*activep && options->version_addendum == NULL) {
2258
		if (*activep && options->version_addendum == NULL) {
2196
			if (strcasecmp(cp + len, "none") == 0)
2259
			if (strcasecmp(str + len, "none") == 0)
2197
				options->version_addendum = xstrdup("");
2260
				options->version_addendum = xstrdup("");
2198
			else if (strchr(cp + len, '\r') != NULL)
2199
				fatal("%.200s line %d: Invalid argument",
2200
				    filename, linenum);
2201
			else
2261
			else
2202
				options->version_addendum = xstrdup(cp + len);
2262
				options->version_addendum = xstrdup(str + len);
2203
		}
2263
		}
2204
		return 0;
2264
		consume_args(&ac);
2265
		break;
2205
2266
2206
	case sAuthorizedKeysCommand:
2267
	case sAuthorizedKeysCommand:
2207
		if (cp == NULL)
2268
		charptr = &options->authorized_keys_command;
2208
			fatal("%.200s line %d: Missing argument.", filename,
2269
 parse_command:
2209
			    linenum);
2270
		len = strspn(str, WHITESPACE);
2210
		len = strspn(cp, WHITESPACE);
2271
		if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
2211
		if (*activep && options->authorized_keys_command == NULL) {
2272
			fatal("%.200s line %d: %s must be an absolute path",
2212
			if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
2273
			    filename, linenum, keyword);
2213
				fatal("%.200s line %d: AuthorizedKeysCommand "
2214
				    "must be an absolute path",
2215
				    filename, linenum);
2216
			options->authorized_keys_command = xstrdup(cp + len);
2217
		}
2274
		}
2218
		return 0;
2275
		if (*activep && options->authorized_keys_command == NULL)
2276
			*charptr = xstrdup(str + len);
2277
		consume_args(&ac);
2278
		break;
2219
2279
2220
	case sAuthorizedKeysCommandUser:
2280
	case sAuthorizedKeysCommandUser:
2221
		charptr = &options->authorized_keys_command_user;
2281
		charptr = &options->authorized_keys_command_user;
2222
2282
 parse_localuser:
2223
		arg = strdelim(&cp);
2283
		arg = next_arg(&ac, &av);
2224
		if (!arg || *arg == '\0')
2284
		if (!arg || *arg == '\0') {
2225
			fatal("%s line %d: missing AuthorizedKeysCommandUser "
2285
			fatal("%s line %d: missing %s argument.",
2226
			    "argument.", filename, linenum);
2286
			    filename, linenum, keyword);
2287
		}
2227
		if (*activep && *charptr == NULL)
2288
		if (*activep && *charptr == NULL)
2228
			*charptr = xstrdup(arg);
2289
			*charptr = xstrdup(arg);
2229
		break;
2290
		break;
2230
2291
2231
	case sAuthorizedPrincipalsCommand:
2292
	case sAuthorizedPrincipalsCommand:
2232
		if (cp == NULL)
2293
		charptr = &options->authorized_principals_command;
2233
			fatal("%.200s line %d: Missing argument.", filename,
2294
		goto parse_command;
2234
			    linenum);
2235
		len = strspn(cp, WHITESPACE);
2236
		if (*activep &&
2237
		    options->authorized_principals_command == NULL) {
2238
			if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
2239
				fatal("%.200s line %d: "
2240
				    "AuthorizedPrincipalsCommand must be "
2241
				    "an absolute path", filename, linenum);
2242
			options->authorized_principals_command =
2243
			    xstrdup(cp + len);
2244
		}
2245
		return 0;
2246
2295
2247
	case sAuthorizedPrincipalsCommandUser:
2296
	case sAuthorizedPrincipalsCommandUser:
2248
		charptr = &options->authorized_principals_command_user;
2297
		charptr = &options->authorized_principals_command_user;
2249
2298
		goto parse_localuser;
2250
		arg = strdelim(&cp);
2251
		if (!arg || *arg == '\0')
2252
			fatal("%s line %d: missing "
2253
			    "AuthorizedPrincipalsCommandUser argument.",
2254
			    filename, linenum);
2255
		if (*activep && *charptr == NULL)
2256
			*charptr = xstrdup(arg);
2257
		break;
2258
2299
2259
	case sAuthenticationMethods:
2300
	case sAuthenticationMethods:
2260
		if (options->num_auth_methods == 0) {
2301
		if (options->num_auth_methods == 0) {
2261
			value = 0; /* seen "any" pseudo-method */
2302
			value = 0; /* seen "any" pseudo-method */
2262
			value2 = 0; /* successfully parsed any method */
2303
			value2 = 0; /* successfully parsed any method */
2263
			while ((arg = strdelim(&cp)) && *arg != '\0') {
2304
			while ((arg = next_arg(&ac, &av)) != NULL) {
2264
				if (strcmp(arg, "any") == 0) {
2305
				if (strcmp(arg, "any") == 0) {
2265
					if (options->num_auth_methods > 0) {
2306
					if (options->num_auth_methods > 0) {
2266
						fatal("%s line %d: \"any\" "
2307
						fatal("%s line %d: \"any\" "
Lines 2291-2300 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2291
				    "specified", filename, linenum);
2332
				    "specified", filename, linenum);
2292
			}
2333
			}
2293
		}
2334
		}
2294
		return 0;
2335
		break;
2295
2336
2296
	case sStreamLocalBindMask:
2337
	case sStreamLocalBindMask:
2297
		arg = strdelim(&cp);
2338
		arg = next_arg(&ac, &av);
2298
		if (!arg || *arg == '\0')
2339
		if (!arg || *arg == '\0')
2299
			fatal("%s line %d: missing StreamLocalBindMask "
2340
			fatal("%s line %d: missing StreamLocalBindMask "
2300
			    "argument.", filename, linenum);
2341
			    "argument.", filename, linenum);
Lines 2311-2317 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2311
		goto parse_flag;
2352
		goto parse_flag;
2312
2353
2313
	case sFingerprintHash:
2354
	case sFingerprintHash:
2314
		arg = strdelim(&cp);
2355
		arg = next_arg(&ac, &av);
2315
		if (!arg || *arg == '\0')
2356
		if (!arg || *arg == '\0')
2316
			fatal("%.200s line %d: Missing argument.",
2357
			fatal("%.200s line %d: Missing argument.",
2317
			    filename, linenum);
2358
			    filename, linenum);
Lines 2328-2334 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2328
2369
2329
	case sRDomain:
2370
	case sRDomain:
2330
		charptr = &options->routing_domain;
2371
		charptr = &options->routing_domain;
2331
		arg = strdelim(&cp);
2372
		arg = next_arg(&ac, &av);
2332
		if (!arg || *arg == '\0')
2373
		if (!arg || *arg == '\0')
2333
			fatal("%.200s line %d: Missing argument.",
2374
			fatal("%.200s line %d: Missing argument.",
2334
			    filename, linenum);
2375
			    filename, linenum);
Lines 2346-2364 process_server_config_line_depth(ServerOptions *options, char *line, Link Here
2346
		do_log2(opcode == sIgnore ?
2387
		do_log2(opcode == sIgnore ?
2347
		    SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2388
		    SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2348
		    "%s line %d: %s option %s", filename, linenum,
2389
		    "%s line %d: %s option %s", filename, linenum,
2349
		    opcode == sUnsupported ? "Unsupported" : "Deprecated", arg);
2390
		    opcode == sUnsupported ? "Unsupported" : "Deprecated",
2350
		while (arg)
2391
		    keyword);
2351
		    arg = strdelim(&cp);
2392
		consume_args(&ac);
2352
		break;
2393
		break;
2353
2394
2354
	default:
2395
	default:
2355
		fatal("%s line %d: Missing handler for opcode %s (%d)",
2396
		fatal("%s line %d: Missing handler for opcode %s (%d)",
2356
		    filename, linenum, arg, opcode);
2397
		    filename, linenum, keyword, opcode);
2357
	}
2398
	}
2358
	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
2399
	/* Check that there is no garbage at end of line. */
2359
		fatal("%s line %d: garbage at end of line; \"%.200s\".",
2400
	if (ac > 0) {
2360
		    filename, linenum, arg);
2401
		error("%.200s line %d: keyword %s extra arguments "
2361
	return 0;
2402
		    "at end of line", filename, linenum, keyword);
2403
		goto out;
2404
	}
2405
2406
	/* success */
2407
	ret = 0;
2408
 out:
2409
	for (ac = 0; ac < oac; ac++)
2410
		free(oav[ac]);
2411
	free(oav);
2412
	return ret;
2362
}
2413
}
2363
2414
2364
int
2415
int
Lines 2397-2408 load_server_config(const char *filename, struct sshbuf *conf) Link Here
2397
	while (getline(&line, &linesize, f) != -1) {
2448
	while (getline(&line, &linesize, f) != -1) {
2398
		lineno++;
2449
		lineno++;
2399
		/*
2450
		/*
2400
		 * Trim out comments and strip whitespace
2451
		 * Strip whitespace
2401
		 * NB - preserve newlines, they are needed to reproduce
2452
		 * NB - preserve newlines, they are needed to reproduce
2402
		 * line numbers later for error messages
2453
		 * line numbers later for error messages
2403
		 */
2454
		 */
2404
		if ((cp = strchr(line, '#')) != NULL)
2405
			memcpy(cp, "\n", 2);
2406
		cp = line + strspn(line, " \t\r");
2455
		cp = line + strspn(line, " \t\r");
2407
		if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2456
		if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2408
			fatal_fr(r, "sshbuf_put");
2457
			fatal_fr(r, "sshbuf_put");
(-)a/ssh.c (-1 / +6 lines)
Lines 488-493 resolve_canonicalize(char **hostp, int port) Link Here
488
	}
488
	}
489
	/* Attempt each supplied suffix */
489
	/* Attempt each supplied suffix */
490
	for (i = 0; i < options.num_canonical_domains; i++) {
490
	for (i = 0; i < options.num_canonical_domains; i++) {
491
		if (strcasecmp(options.canonical_domains[i], "none") == 0)
492
			break;
491
		xasprintf(&fullhost, "%s.%s.", *hostp,
493
		xasprintf(&fullhost, "%s.%s.", *hostp,
492
		    options.canonical_domains[i]);
494
		    options.canonical_domains[i]);
493
		debug3_f("attempting \"%s\" => \"%s\"", *hostp, fullhost);
495
		debug3_f("attempting \"%s\" => \"%s\"", *hostp, fullhost);
Lines 1314-1321 main(int ac, char **av) Link Here
1314
1316
1315
	/* reinit */
1317
	/* reinit */
1316
	log_init(argv0, options.log_level, options.log_facility, !use_syslog);
1318
	log_init(argv0, options.log_level, options.log_facility, !use_syslog);
1317
	for (j = 0; j < options.num_log_verbose; j++)
1319
	for (j = 0; j < options.num_log_verbose; j++) {
1320
		if (strcasecmp(options.log_verbose[j], "none") == 0)
1321
			break;
1318
		log_verbose_add(options.log_verbose[j]);
1322
		log_verbose_add(options.log_verbose[j]);
1323
	}
1319
1324
1320
	if (options.request_tty == REQUEST_TTY_YES ||
1325
	if (options.request_tty == REQUEST_TTY_YES ||
1321
	    options.request_tty == REQUEST_TTY_FORCE)
1326
	    options.request_tty == REQUEST_TTY_FORCE)
(-)a/sshconnect.c (-1 / +1 lines)
Lines 827-833 load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template, Link Here
827
	osigchld = ssh_signal(SIGCHLD, SIG_DFL);
827
	osigchld = ssh_signal(SIGCHLD, SIG_DFL);
828
828
829
	/* Turn the command into an argument vector */
829
	/* Turn the command into an argument vector */
830
	if (argv_split(command_template, &ac, &av) != 0) {
830
	if (argv_split(command_template, &ac, &av, 0) != 0) {
831
		error("%s \"%s\" contains invalid quotes", tag,
831
		error("%s \"%s\" contains invalid quotes", tag,
832
		    command_template);
832
		    command_template);
833
		goto out;
833
		goto out;

Return to bug 3288