|
@@ -45,7 +45,7 @@ static tls_domains_cfg_t* cfg = NULL;
|
|
|
static tls_domain_t* domain = NULL;
|
|
|
|
|
|
static int parse_ipv6(struct ip_addr* ip, cfg_token_t* token,
|
|
|
- cfg_parser_t* st)
|
|
|
+ cfg_parser_t* st)
|
|
|
{
|
|
|
int ret;
|
|
|
cfg_token_t t;
|
|
@@ -66,15 +66,15 @@ static int parse_ipv6(struct ip_addr* ip, cfg_token_t* token,
|
|
|
*ip = *ipv6;
|
|
|
return 0;
|
|
|
|
|
|
- err:
|
|
|
+err:
|
|
|
ERR("%s:%d:%d: Invalid IPv6 address\n",
|
|
|
- st->file, token->start.line, token->start.col);
|
|
|
+ st->file, token->start.line, token->start.col);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
static int parse_ipv4(struct ip_addr* ip, cfg_token_t* token,
|
|
|
- cfg_parser_t* st)
|
|
|
+ cfg_parser_t* st)
|
|
|
{
|
|
|
int ret, i;
|
|
|
cfg_token_t t;
|
|
@@ -92,7 +92,7 @@ static int parse_ipv4(struct ip_addr* ip, cfg_token_t* token,
|
|
|
ret = cfg_get_token(&t, st, 0);
|
|
|
if (ret < 0) return -1;
|
|
|
if (ret > 0 || t.type != '.') goto err;
|
|
|
-
|
|
|
+
|
|
|
ret = cfg_get_token(&t, st, 0);
|
|
|
if (ret < 0) return -1;
|
|
|
if (ret > 0 || t.type != CFG_TOKEN_ALPHA) goto err;
|
|
@@ -102,9 +102,9 @@ static int parse_ipv4(struct ip_addr* ip, cfg_token_t* token,
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
- err:
|
|
|
+err:
|
|
|
ERR("%s:%d:%d: Invalid IPv4 address\n",
|
|
|
- st->file, token->start.line, token->start.col);
|
|
|
+ st->file, token->start.line, token->start.col);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
@@ -182,17 +182,17 @@ static void update_opt_variables(void)
|
|
|
|
|
|
|
|
|
static int parse_hostport(int* type, struct ip_addr* ip, unsigned int* port,
|
|
|
- cfg_token_t* token, cfg_parser_t* st)
|
|
|
+ cfg_token_t* token, cfg_parser_t* st)
|
|
|
{
|
|
|
int ret;
|
|
|
cfg_token_t t;
|
|
|
- cfg_option_t* opt;
|
|
|
+ cfg_option_t* opt;
|
|
|
|
|
|
ret = cfg_get_token(&t, st, 0);
|
|
|
if (ret < 0) return -1;
|
|
|
if (ret > 0) {
|
|
|
ERR("%s:%d:%d: Missing IP address\n", st->file,
|
|
|
- token->start.line, token->start.col);
|
|
|
+ token->start.line, token->start.col);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
@@ -202,44 +202,44 @@ static int parse_hostport(int* type, struct ip_addr* ip, unsigned int* port,
|
|
|
opt = cfg_lookup_token(token_default, &t.val);
|
|
|
if (opt) {
|
|
|
*type = TLS_DOMAIN_DEF;
|
|
|
- /* Default domain */
|
|
|
+ /* Default domain */
|
|
|
return 0;
|
|
|
} else {
|
|
|
if (parse_ipv4(ip, &t, st) < 0) return -1;
|
|
|
}
|
|
|
} else {
|
|
|
ERR("%s:%d:%d: Syntax error, IP address expected\n",
|
|
|
- st->file, t.start.line, t.start.col);
|
|
|
+ st->file, t.start.line, t.start.col);
|
|
|
return -1;
|
|
|
}
|
|
|
*type = 0;
|
|
|
|
|
|
- /* Parse port */
|
|
|
+ /* Parse port */
|
|
|
ret = cfg_get_token(&t, st, 0);
|
|
|
if (ret < 0) return -1;
|
|
|
if (ret > 0) {
|
|
|
ERR("%s:%d:%d: Syntax error, ':' expected\n", st->file, st->line,
|
|
|
- st->col);
|
|
|
+ st->col);
|
|
|
return -1;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (t.type != ':') {
|
|
|
ERR("%s:%d:%d: Syntax error, ':' expected\n",
|
|
|
- st->file, t.start.line, t.start.col);
|
|
|
+ st->file, t.start.line, t.start.col);
|
|
|
return -1;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
ret = cfg_get_token(&t, st, 0);
|
|
|
if (ret < 0) return -1;
|
|
|
if (ret > 0) {
|
|
|
ERR("%s:%d:%d: Premature end of file, port number missing\n",
|
|
|
- st->file, t.start.line, t.start.col);
|
|
|
+ st->file, t.start.line, t.start.col);
|
|
|
return -1;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (t.type != CFG_TOKEN_ALPHA || (str2int(&t.val, port) < 0)) {
|
|
|
ERR("%s:%d:%d: Invalid port number '%.*s'\n",
|
|
|
- st->file, t.start.line, t.start.col, STR_FMT(&t.val));
|
|
|
+ st->file, t.start.line, t.start.col, STR_FMT(&t.val));
|
|
|
return -1;
|
|
|
}
|
|
|
return 0;
|
|
@@ -262,27 +262,27 @@ static int parse_domain(void* param, cfg_parser_t* st, unsigned int flags)
|
|
|
if (ret < 0) return -1;
|
|
|
if (ret > 0) {
|
|
|
ERR("%s:%d:%d: TLS domain type missing\n",
|
|
|
- st->file, st->line, st->col);
|
|
|
+ st->file, st->line, st->col);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if (t.type != CFG_TOKEN_ALPHA ||
|
|
|
- ((opt = cfg_lookup_token(domain_types, &t.val)) == NULL)) {
|
|
|
+ ((opt = cfg_lookup_token(domain_types, &t.val)) == NULL)) {
|
|
|
ERR("%s:%d:%d: Invalid TLS domain type %d:'%.*s'\n",
|
|
|
- st->file, t.start.line, t.start.col, t.type, STR_FMT(&t.val));
|
|
|
+ st->file, t.start.line, t.start.col, t.type, STR_FMT(&t.val));
|
|
|
return -1;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
ret = cfg_get_token(&t, st, 0);
|
|
|
if (ret < 0) return -1;
|
|
|
if (ret > 0) {
|
|
|
ERR("%s:%d:%d: TLS domain IP address missing\n",
|
|
|
- st->file, st->line, st->col);
|
|
|
+ st->file, st->line, st->col);
|
|
|
return -1;
|
|
|
}
|
|
|
if (t.type != ':') {
|
|
|
ERR("%s:%d:%d: Syntax error, ':' expected\n",
|
|
|
- st->file, t.start.line, t.start.col);
|
|
|
+ st->file, t.start.line, t.start.col);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
@@ -293,12 +293,12 @@ static int parse_domain(void* param, cfg_parser_t* st, unsigned int flags)
|
|
|
if (ret < 0) return -1;
|
|
|
if (ret > 0) {
|
|
|
ERR("%s:%d:%d: Closing ']' missing\n",
|
|
|
- st->file, st->line, st->col);
|
|
|
+ st->file, st->line, st->col);
|
|
|
return -1;
|
|
|
}
|
|
|
if (t.type != ']') {
|
|
|
ERR("%s:%d:%d: Syntax error, ']' expected\n",
|
|
|
- st->file, t.start.line, t.start.col);
|
|
|
+ st->file, t.start.line, t.start.col);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
@@ -312,16 +312,16 @@ static int parse_domain(void* param, cfg_parser_t* st, unsigned int flags)
|
|
|
ret = tls_add_domain(cfg, domain);
|
|
|
if (ret < 0) {
|
|
|
ERR("%s:%d: Error while creating TLS domain structure\n", st->file,
|
|
|
- st->line);
|
|
|
+ st->line);
|
|
|
tls_free_domain(domain);
|
|
|
return -1;
|
|
|
} else if (ret == 1) {
|
|
|
ERR("%s:%d: Duplicate TLS domain (appears earlier in the config file)\n",
|
|
|
- st->file, st->line);
|
|
|
+ st->file, st->line);
|
|
|
tls_free_domain(domain);
|
|
|
return -1;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
update_opt_variables();
|
|
|
cfg_set_options(st, options);
|
|
|
return 0;
|
|
@@ -333,106 +333,108 @@ static int parse_domain(void* param, cfg_parser_t* st, unsigned int flags)
|
|
|
*/
|
|
|
tls_domains_cfg_t* tls_load_config(str* filename)
|
|
|
{
|
|
|
- cfg_parser_t* parser;
|
|
|
- str empty;
|
|
|
- struct stat file_status;
|
|
|
- char tmp_name[13] = "configXXXXXX";
|
|
|
- str filename_str;
|
|
|
- DIR *dir;
|
|
|
- struct dirent *ent;
|
|
|
- int out_fd, in_fd, filename_is_directory;
|
|
|
- char *file_path, ch;
|
|
|
-
|
|
|
- parser = NULL;
|
|
|
- memset(&file_status, 0, sizeof(struct stat));
|
|
|
- dir = (DIR *)NULL;
|
|
|
- in_fd = out_fd = filename_is_directory = 0;
|
|
|
- file_path = (char *)0;
|
|
|
-
|
|
|
- if ((cfg = tls_new_cfg()) == NULL) goto error;
|
|
|
-
|
|
|
- if (stat(filename->s, &file_status) != 0) {
|
|
|
- LOG(L_ERR, "cannot stat config file %s\n", filename->s);
|
|
|
- goto error;
|
|
|
- }
|
|
|
- if (S_ISDIR(file_status.st_mode)) {
|
|
|
- filename_is_directory = 1;
|
|
|
- dir = opendir(filename->s);
|
|
|
- if (dir == NULL) {
|
|
|
- LOG(L_ERR, "cannot open directory file %s\n", filename->s);
|
|
|
- goto error;
|
|
|
- }
|
|
|
- out_fd = mkstemp(&(tmp_name[0]));
|
|
|
- if (out_fd == -1) {
|
|
|
- LOG(L_ERR, "cannot make tmp file %s\n", &(tmp_name[0]));
|
|
|
- goto error;
|
|
|
- }
|
|
|
- while ((ent = readdir(dir)) != NULL) {
|
|
|
- file_path = pkg_malloc(filename->len + 1 + 256);
|
|
|
- memcpy(file_path, filename->s, filename->len);
|
|
|
- file_path[filename->len] = '/';
|
|
|
- strcpy(file_path + filename->len + 1, ent->d_name);
|
|
|
- if (stat(file_path, &file_status) != 0) {
|
|
|
- LOG(L_ERR, "cannot get status of config file %s\n",
|
|
|
- file_path);
|
|
|
+ cfg_parser_t* parser;
|
|
|
+ str empty;
|
|
|
+ struct stat file_status;
|
|
|
+ char tmp_name[13] = "configXXXXXX";
|
|
|
+ str filename_str;
|
|
|
+ DIR *dir;
|
|
|
+ struct dirent *ent;
|
|
|
+ int out_fd, in_fd, filename_is_directory;
|
|
|
+ char *file_path, ch;
|
|
|
+
|
|
|
+ parser = NULL;
|
|
|
+ memset(&file_status, 0, sizeof(struct stat));
|
|
|
+ dir = (DIR *)NULL;
|
|
|
+ in_fd = out_fd = filename_is_directory = 0;
|
|
|
+ file_path = (char *)0;
|
|
|
+
|
|
|
+ if ((cfg = tls_new_cfg()) == NULL) goto error;
|
|
|
+
|
|
|
+ if (stat(filename->s, &file_status) != 0) {
|
|
|
+ LOG(L_ERR, "cannot stat config file %s\n", filename->s);
|
|
|
goto error;
|
|
|
- }
|
|
|
- if (S_ISREG(file_status.st_mode)) {
|
|
|
- in_fd = open(file_path, O_RDONLY);
|
|
|
- if (in_fd == -1) {
|
|
|
- LOG(L_ERR, "cannot open config file %s\n",
|
|
|
- file_path);
|
|
|
- goto error;
|
|
|
+ }
|
|
|
+ if (S_ISDIR(file_status.st_mode)) {
|
|
|
+ filename_is_directory = 1;
|
|
|
+ dir = opendir(filename->s);
|
|
|
+ if (dir == NULL) {
|
|
|
+ LOG(L_ERR, "cannot open directory file %s\n", filename->s);
|
|
|
+ goto error;
|
|
|
}
|
|
|
- pkg_free(file_path);
|
|
|
- while (read(in_fd, &ch, 1)) {
|
|
|
- write(out_fd, &ch, 1);
|
|
|
+ out_fd = mkstemp(&(tmp_name[0]));
|
|
|
+ if (out_fd == -1) {
|
|
|
+ LOG(L_ERR, "cannot make tmp file %s\n", &(tmp_name[0]));
|
|
|
+ goto error;
|
|
|
}
|
|
|
- close(in_fd);
|
|
|
- in_fd = 0;
|
|
|
- ch = '\n';
|
|
|
- write(out_fd, &ch, 1);
|
|
|
- }
|
|
|
+ while ((ent = readdir(dir)) != NULL) {
|
|
|
+ if(file_path) pkg_free(file_path);
|
|
|
+ file_path = pkg_malloc(filename->len + 1 + 256);
|
|
|
+ memcpy(file_path, filename->s, filename->len);
|
|
|
+ file_path[filename->len] = '/';
|
|
|
+ strcpy(file_path + filename->len + 1, ent->d_name);
|
|
|
+ if (stat(file_path, &file_status) != 0) {
|
|
|
+ LOG(L_ERR, "cannot get status of config file %s\n",
|
|
|
+ file_path);
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ if (S_ISREG(file_status.st_mode)) {
|
|
|
+ in_fd = open(file_path, O_RDONLY);
|
|
|
+ if (in_fd == -1) {
|
|
|
+ LOG(L_ERR, "cannot open config file %s\n",
|
|
|
+ file_path);
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ pkg_free(file_path);
|
|
|
+ file_path = NULL;
|
|
|
+ while (read(in_fd, &ch, 1)) {
|
|
|
+ write(out_fd, &ch, 1);
|
|
|
+ }
|
|
|
+ close(in_fd);
|
|
|
+ in_fd = 0;
|
|
|
+ ch = '\n';
|
|
|
+ write(out_fd, &ch, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ closedir(dir);
|
|
|
+ close(out_fd);
|
|
|
+ dir = (DIR *)NULL;
|
|
|
+ out_fd = 0;
|
|
|
}
|
|
|
- closedir(dir);
|
|
|
- close(out_fd);
|
|
|
- dir = (DIR *)NULL;
|
|
|
- out_fd = 0;
|
|
|
- }
|
|
|
-
|
|
|
- empty.s = 0;
|
|
|
- empty.len = 0;
|
|
|
- if (filename_is_directory) {
|
|
|
- filename_str.s = &(tmp_name[0]);
|
|
|
- filename_str.len = strlen(&(tmp_name[0]));
|
|
|
- if ((parser = cfg_parser_init(&empty, &filename_str)) == NULL) {
|
|
|
- ERR("tls: Error while initializing configuration file parser.\n");
|
|
|
- unlink(&(tmp_name[0]));
|
|
|
- goto error;
|
|
|
+
|
|
|
+ empty.s = 0;
|
|
|
+ empty.len = 0;
|
|
|
+ if (filename_is_directory) {
|
|
|
+ filename_str.s = &(tmp_name[0]);
|
|
|
+ filename_str.len = strlen(&(tmp_name[0]));
|
|
|
+ if ((parser = cfg_parser_init(&empty, &filename_str)) == NULL) {
|
|
|
+ ERR("tls: Error while initializing configuration file parser.\n");
|
|
|
+ unlink(&(tmp_name[0]));
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ unlink(&(tmp_name[0]));
|
|
|
+ } else {
|
|
|
+ if ((parser = cfg_parser_init(&empty, filename)) == NULL) {
|
|
|
+ ERR("tls: Error while initializing configuration file parser.\n");
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
}
|
|
|
- unlink(&(tmp_name[0]));
|
|
|
- } else {
|
|
|
- if ((parser = cfg_parser_init(&empty, filename)) == NULL) {
|
|
|
- ERR("tls: Error while initializing configuration file parser.\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- cfg_section_parser(parser, parse_domain, NULL);
|
|
|
- if (sr_cfg_parse(parser)) goto error;
|
|
|
- cfg_parser_close(parser);
|
|
|
- return cfg;
|
|
|
-
|
|
|
- error:
|
|
|
- if (dir) closedir(dir);
|
|
|
- if (out_fd > 0) {
|
|
|
- close(out_fd);
|
|
|
- unlink(&(tmp_name[0]));
|
|
|
- }
|
|
|
- if (file_path) pkg_free(file_path);
|
|
|
- if (parser) cfg_parser_close(parser);
|
|
|
- if (cfg) tls_free_cfg(cfg);
|
|
|
- return 0;
|
|
|
+
|
|
|
+ cfg_section_parser(parser, parse_domain, NULL);
|
|
|
+ if (sr_cfg_parse(parser)) goto error;
|
|
|
+ cfg_parser_close(parser);
|
|
|
+ return cfg;
|
|
|
+
|
|
|
+error:
|
|
|
+ if (dir) closedir(dir);
|
|
|
+ if (out_fd > 0) {
|
|
|
+ close(out_fd);
|
|
|
+ unlink(&(tmp_name[0]));
|
|
|
+ }
|
|
|
+ if (file_path) pkg_free(file_path);
|
|
|
+ if (parser) cfg_parser_close(parser);
|
|
|
+ if (cfg) tls_free_cfg(cfg);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -441,15 +443,15 @@ tls_domains_cfg_t* tls_load_config(str* filename)
|
|
|
*/
|
|
|
int tls_parse_method(str* method)
|
|
|
{
|
|
|
- cfg_option_t* opt;
|
|
|
+ cfg_option_t* opt;
|
|
|
|
|
|
- if (!method) {
|
|
|
- BUG("Invalid parameter value\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ if (!method) {
|
|
|
+ BUG("Invalid parameter value\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
|
|
|
- opt = cfg_lookup_token(methods, method);
|
|
|
- if (!opt) return -1;
|
|
|
+ opt = cfg_lookup_token(methods, method);
|
|
|
+ if (!opt) return -1;
|
|
|
|
|
|
#if OPENSSL_VERSION_NUMBER < 0x1000100fL
|
|
|
if(opt->val == TLS_USE_TLSv1_1) {
|
|
@@ -466,5 +468,5 @@ int tls_parse_method(str* method)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
- return opt->val;
|
|
|
+ return opt->val;
|
|
|
}
|