diff --git a/include/tscore/IpMapConf.h b/include/tscore/IpMapConf.h deleted file mode 100644 index 7d229adf15d..00000000000 --- a/include/tscore/IpMapConf.h +++ /dev/null @@ -1,35 +0,0 @@ -/** @file - - Loading @c IpMap from a configuration file. - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -// Copied from IPRange.cc for backwards compatibility. - -#pragma once - -class IpMap; // declare in name only. - -// Returns 0 if successful, error string otherwise -int read_addr(char *line, int n, int *i, sockaddr *addr, char *err); -// Returns 0 if successful, error string otherwise -char *Load_IpMap_From_File(IpMap *map, int fd, char const *key_str); -// Returns 0 if successful, error string otherwise -char *Load_IpMap_From_File(IpMap *map, FILE *f, char const *key_str); diff --git a/iocore/net/P_Socks.h b/iocore/net/P_Socks.h index 2f875c1e4e3..d924796af59 100644 --- a/iocore/net/P_Socks.h +++ b/iocore/net/P_Socks.h @@ -22,12 +22,16 @@ */ #pragma once + +#include "swoc/TextView.h" +#include "swoc/swoc_ip.h" + #include "P_EventSystem.h" #include "I_Socks.h" +#include "tscpp/util/ts_errata.h" #ifdef SOCKS_WITH_TS #include "ParentSelection.h" -#include "tscore/IpMap.h" #endif enum { @@ -43,8 +47,7 @@ struct socks_conf_struct { int server_connect_timeout = 0; int socks_timeout = 100; unsigned char default_version = 5; - char *user_name_n_passwd = nullptr; - int user_name_n_passwd_len = 0; + std::string user_name_n_passwd; int per_server_connection_attempts = 1; int connection_attempts = 0; @@ -55,7 +58,7 @@ struct socks_conf_struct { unsigned short http_port = 1080; #ifdef SOCKS_WITH_TS - IpMap ip_map; + swoc::IPRangeSet ip_addrs; #endif #ifndef SOCKS_WITH_TS @@ -75,7 +78,9 @@ extern struct socks_conf_struct *g_socks_conf_stuff; void start_SocksProxy(int port); -int loadSocksAuthInfo(int fd, socks_conf_struct *socks_stuff); +int loadSocksAuthInfo(swoc::TextView content, socks_conf_struct *socks_stuff); + +swoc::Errata loadSocksIPAddrs(swoc::TextView content, socks_conf_struct *socks_stuff); // umm.. the following typedef should take _its own_ type as one of the args // not possible with C diff --git a/iocore/net/Socks.cc b/iocore/net/Socks.cc index aceddf700ea..ecb282d573c 100644 --- a/iocore/net/Socks.cc +++ b/iocore/net/Socks.cc @@ -30,11 +30,16 @@ duplicated in UnixNet.cc and NTNetProcessor.cc */ +#include "swoc/swoc_file.h" +#include "swoc/bwf_std.h" +#include "swoc/bwf_ex.h" + #include "P_Net.h" #include "tscore/I_Layout.h" #include "tscore/ink_sock.h" #include "tscore/InkErrno.h" -#include "tscore/IpMapConf.h" + +using namespace swoc::literals; socks_conf_struct *g_socks_conf_stuff = nullptr; @@ -460,8 +465,10 @@ loadSocksConfiguration(socks_conf_struct *socks_conf_stuff) int socks_config_fd = -1; ats_scoped_str config_pathname; #ifdef SOCKS_WITH_TS - char *tmp; + swoc::Errata errata; #endif + std::error_code ec; + std::string config_text; socks_conf_stuff->accept_enabled = 0; // initialize it INKqa08593 socks_conf_stuff->socks_needed = REC_ConfigReadInteger("proxy.config.socks.socks_needed"); @@ -506,28 +513,28 @@ loadSocksConfiguration(socks_conf_struct *socks_conf_stuff) goto error; } - socks_config_fd = ::open(config_pathname, O_RDONLY); - - if (socks_config_fd < 0) { - Error("SOCKS Config: could not open config file '%s'. SOCKS Turned off", (const char *)config_pathname); + config_text = swoc::file::load(swoc::file::path(config_pathname), ec); + if (ec) { + swoc::bwprint(config_text, "SOCK Config: Disabled, could not open config file \"{}\" {}", config_pathname, ec); + Error("%s", config_text.c_str()); goto error; } + #ifdef SOCKS_WITH_TS - tmp = Load_IpMap_From_File(&socks_conf_stuff->ip_map, socks_config_fd, "no_socks"); + errata = loadSocksIPAddrs(config_text, socks_conf_stuff); - if (tmp) { - Error("SOCKS Config: Error while reading ip_range: %s.", tmp); - ats_free(tmp); + if (!errata.is_ok()) { + swoc::bwprint(config_text, "SOCK Config: Error\n{}", errata); + Error("%s", config_text.c_str()); goto error; } #endif - if (loadSocksAuthInfo(socks_config_fd, socks_conf_stuff) != 0) { + if (loadSocksAuthInfo(config_text, socks_conf_stuff) != 0) { Error("SOCKS Config: Error while reading Socks auth info"); goto error; } Debug("Socks", "Socks Turned on"); - ::close(socks_config_fd); return; error: @@ -540,60 +547,58 @@ loadSocksConfiguration(socks_conf_struct *socks_conf_stuff) } int -loadSocksAuthInfo(int fd, socks_conf_struct *socks_stuff) +loadSocksAuthInfo(swoc::TextView content, socks_conf_struct *socks_stuff) { - char c = '\0'; - char line[256] = {0}; // initialize all chars to nil - char user_name[256] = {0}; - char passwd[256] = {0}; - - if (lseek(fd, 0, SEEK_SET) < 0) { - Warning("Can not seek on Socks configuration file\n"); - return -1; - } - - bool end_of_file = false; - do { - int n = 0, rc; - while (((rc = read(fd, &c, 1)) == 1) && (c != '\n') && (n < 254)) { - line[n++] = c; - } - if (rc <= 0) { - end_of_file = true; - } - line[n] = '\0'; - - // coverity[secure_coding] - rc = sscanf(line, " auth u %255s %255s ", user_name, passwd); - if (rc >= 2) { - int len1 = strlen(user_name); - int len2 = strlen(passwd); - - Debug("Socks", "Read user_name(%s) and passwd(%s) from config file", user_name, passwd); - - socks_stuff->user_name_n_passwd_len = len1 + len2 + 2; + static constexpr swoc::TextView PREFIX = "auth u "; + std::string text; - char *ptr = static_cast(ats_malloc(socks_stuff->user_name_n_passwd_len)); - ptr[0] = len1; - memcpy(&ptr[1], user_name, len1); - ptr[len1 + 1] = len2; - memcpy(&ptr[len1 + 2], passwd, len2); + while (content.ltrim_if(&isspace)) { + auto line = content.take_prefix_at('\n'); - socks_stuff->user_name_n_passwd = ptr; + if (line.starts_with(PREFIX)) { + line.remove_prefix(PREFIX.size()).ltrim_if(&isspace); + auto user_name = line.take_prefix_if(&isspace); + auto password = line.take_prefix_if(&isspace); - return 0; + if (!user_name.empty() && !password.empty()) { + Debug("Socks", "%s", swoc::bwprint(text, "Read auth credentials \"{}\" : \"{}\"", user_name, password).c_str()); + swoc::bwprint(socks_stuff->user_name_n_passwd, "{}{}{}{}", char(user_name.size()), user_name, char(password.size()), + password); + } } - } while (!end_of_file); - + } return 0; } +swoc::Errata +loadSocksIPAddrs(swoc::TextView content, socks_conf_struct *socks_stuff) +{ + static constexpr swoc::TextView PREFIX = "no_socks "; + std::string text; + + while (content.ltrim_if(&isspace)) { + auto line = content.take_prefix_at('\n'); + if (line.starts_with(PREFIX)) { + line.remove_prefix(PREFIX.size()); + while (line.ltrim_if(&isspace)) { + auto token = line.take_prefix_at(','); + if (swoc::IPRange r; r.load(token)) { + socks_stuff->ip_addrs.mark(r); + } else { + return swoc::Errata(ERRATA_ERROR, "Invalid IP address range \"{}\"", token); + } + } + } + } + return {}; +} + int socks5BasicAuthHandler(int event, unsigned char *p, void (**h_ptr)(void)) { // for more info on Socks5 see RFC 1928 int ret = 0; - char *pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd; + char *pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd.data(); switch (event) { case SOCKS_AUTH_OPEN: @@ -672,8 +677,8 @@ socks5PasswdAuthHandler(int event, unsigned char *p, void (**h_ptr)(void)) switch (event) { case SOCKS_AUTH_OPEN: - pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd; - pass_len = netProcessor.socks_conf_stuff->user_name_n_passwd_len; + pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd.data(); + pass_len = netProcessor.socks_conf_stuff->user_name_n_passwd.length(); ink_assert(pass_phrase); p[0] = 1; // version diff --git a/iocore/net/UnixNetProcessor.cc b/iocore/net/UnixNetProcessor.cc index 35fae59f0ee..8ee1b65e7fc 100644 --- a/iocore/net/UnixNetProcessor.cc +++ b/iocore/net/UnixNetProcessor.cc @@ -200,7 +200,7 @@ UnixNetProcessor::connect_re_internal(Continuation *cont, sockaddr const *target * we need to connect using socks server even * if this ip is in no_socks list. */ - !socks_conf_stuff->ip_map.contains(target)) + !socks_conf_stuff->ip_addrs.contains(swoc::IPAddr(target))) #endif ); SocksEntry *socksEntry = nullptr; diff --git a/src/tscore/IpMapConf.cc b/src/tscore/IpMapConf.cc deleted file mode 100644 index 51bcc5ea0a5..00000000000 --- a/src/tscore/IpMapConf.cc +++ /dev/null @@ -1,187 +0,0 @@ -/** @file - - Loading @c IpMap from a configuration file. - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -// Copied from IPRange.cc for backwards compatibility. - -#include "tscore/IpMap.h" -#include "tscore/IpMapConf.h" -#include "tscore/ink_memory.h" - -static size_t const ERR_STRING_LEN = 256; -static size_t const MAX_LINE_SIZE = 2048; - -// Returns 0 if successful, 1 if failed -// line Input text (source line). -// n Amount of data in @a line. -// i [in,out] Offset in line. -// addr [out] Destination for address. -// err Buffer for error string (must be ERR_STRING_LEN big). -int -read_addr(char *line, int n, int *i, sockaddr *addr, char *err) -{ - int k; - char dst[INET6_ADDRSTRLEN]; - char *src = line + *i; - bool bracketed_p = false; - - // Allow enclosing brackets to be more consistent but - // don't bother passing it to @c ntop. - if ((*i < n) && ('[' == *src)) { - ++*i, ++src, bracketed_p = true; - } - - for (k = 0; k < INET6_ADDRSTRLEN && *i < n && (isxdigit(*src) || '.' == *src || ':' == *src); ++k, ++*i, ++src) { - dst[k] = *src; - } - - if (bracketed_p && (!(*i < n) || (']' != *src))) { - snprintf(err, ERR_STRING_LEN, "Unclosed brackets"); - return EINVAL; - } - - if (k == sizeof(dst)) { - snprintf(err, ERR_STRING_LEN, "IP address too long"); - return EINVAL; - } - - dst[k] = '\0'; - if (0 != ats_ip_pton(dst, addr)) { - snprintf(err, ERR_STRING_LEN, "IP address '%s' improperly formatted", dst); - return EINVAL; - } - return 0; -} - -char * -Load_IpMap_From_File(IpMap *map, int fd, const char *key_str) -{ - char *zret = nullptr; - int fd2 = dup(fd); // dup to avoid closing the original file. - FILE *f = nullptr; - - if (fd2 >= 0) { - f = fdopen(fd2, "r"); - } - - if (f != nullptr) { - zret = Load_IpMap_From_File(map, f, key_str); - fclose(f); - } else { - zret = static_cast(ats_malloc(ERR_STRING_LEN)); - snprintf(zret, ERR_STRING_LEN, "Unable to reopen file descriptor as stream %d:%s", errno, strerror(errno)); - } - return zret; -} - -// Skip space in line, returning true if more data is available -// (not end of line). -// -// line Source line. -// n Line length. -// offset Current offset -static inline bool -skip_space(char *line, int n, int &offset) -{ - while (offset < n && isspace(line[offset])) { - ++offset; - } - return offset < n; -} - -// Returns 0 if successful, error string otherwise -char * -Load_IpMap_From_File(IpMap *map, FILE *f, const char *key_str) -{ - int i, n, line_no; - int key_len = strlen(key_str); - IpEndpoint laddr, raddr; - char line[MAX_LINE_SIZE]; - char err_buff[ERR_STRING_LEN]; - - // First hardcode 127.0.0.1 into the table - map->mark(INADDR_LOOPBACK); - - line_no = 0; - while (fgets(line, MAX_LINE_SIZE, f)) { - ++line_no; - n = strlen(line); - // Find first white space which terminates the line key. - for (i = 0; i < n && !isspace(line[i]); ++i) { - ; - } - if (i != key_len || 0 != strncmp(line, key_str, key_len)) { - continue; - } - // Now look for IP address - while (true) { - if (!skip_space(line, n, i)) { - break; - } - - if (0 != read_addr(line, n, &i, &laddr.sa, err_buff)) { - char *error_str = static_cast(ats_malloc(ERR_STRING_LEN)); - snprintf(error_str, ERR_STRING_LEN, "Invalid input configuration (%s) at line %d offset %d - '%s'", err_buff, line_no, i, - line); - return error_str; - } - - if (!skip_space(line, n, i) || line[i] == ',') { - // You have read an IP address. Enter it in the table - map->mark(&laddr); - if (i == n) { - break; - } else { - ++i; - } - } else if (line[i] == '-') { - // What you have just read is the start of the range, - // Now, read the end of the IP range - ++i; - if (!skip_space(line, n, i)) { - char *error_str = static_cast(ats_malloc(ERR_STRING_LEN)); - snprintf(error_str, ERR_STRING_LEN, "Invalid input (unterminated range) at line %d offset %d - '%s'", line_no, i, line); - return error_str; - } else if (0 != read_addr(line, n, &i, &raddr.sa, err_buff)) { - char *error_str = static_cast(ats_malloc(ERR_STRING_LEN)); - snprintf(error_str, ERR_STRING_LEN, "Invalid input (%s) at line %d offset %d - '%s'", err_buff, line_no, i, line); - return error_str; - } - map->mark(&laddr.sa, &raddr.sa); - if (!skip_space(line, n, i)) { - break; - } - if (line[i] != ',') { - char *error_str = static_cast(ats_malloc(ERR_STRING_LEN)); - snprintf(error_str, ERR_STRING_LEN, "Invalid input (expecting comma) at line %d offset %d - '%s'", line_no, i, line); - return error_str; - } - ++i; - } else { - char *error_str = static_cast(ats_malloc(ERR_STRING_LEN)); - snprintf(error_str, ERR_STRING_LEN, "Invalid input (expecting dash or comma) at line %d offset %d", line_no, i); - return error_str; - } - } - } - return nullptr; -} diff --git a/src/tscore/Makefile.am b/src/tscore/Makefile.am index 941a3625d9b..4cd1fa6d2ab 100644 --- a/src/tscore/Makefile.am +++ b/src/tscore/Makefile.am @@ -105,7 +105,6 @@ libtscore_la_SOURCES = \ ink_time.cc \ ink_uuid.cc \ IpMap.cc \ - IpMapConf.cc \ JeMiAllocator.cc \ Layout.cc \ llqueue.cc \