diff --git a/src/syncterm/Manual.txt b/src/syncterm/Manual.txt index 88f980aede217fe580c0ac651101fc434fadb7e2..da912fe6db884473b9ace07bdaa7d48123ff70a1 100644 --- a/src/syncterm/Manual.txt +++ b/src/syncterm/Manual.txt @@ -15,19 +15,19 @@ If you need help with SyncTERM, the best places are: Connect to irc.synchro.net and find Deuce in #Synchronet. Ask your question, then idle. I can take hours to respond. Do not give up, this is the quickest way to get a response. -2) E-Mail: +2) SourceForge: + The official SyncTERM project page at + http://www.sf.net/projects/syncterm has a bug tracker and other + features that will email me and provide tracking for issues that + are filed. +3) E-Mail: I am usually fairly responsive to emails sent to me at shurd@sasktel.net. Please describe your issue as clearly as possible. -3) Dove-Net: +4) Dove-Net: I usually read Dove-Net regularly, and many other users can often help with support issues. Ask questions in the Hardware/Software Help sub. If your local BBS does not carry Dove-Net, you can telnet to vert.synchro.net and leave messages there. -4) SourceForge: - The official SyncTERM project page at - http://www.sf.net/projects/syncterm has a bug tracker and other - features that will email me and provide tracking for issues that - are filed. Throughout this document, I will mention things which are not supported. These are things which I don't normally test, and are unlikely to work @@ -69,7 +69,7 @@ build system is used. There are a number of optional dependencies, and a large number of supported compile flags (many of which are shared with Synchronet). -The biggest optional dependency is SDL 1.2 (from http://libsdl.org). +The biggest optional dependency is SDL 2 (from http://libsdl.org). SyncTERM can use SDL for both graphics and sound. X11 can also be used for graphics, and OSS, ALSA, or Portaudio can also provide sound. These use run-time linking, so at compile time, only the headers are needed. diff --git a/src/syncterm/bbslist.c b/src/syncterm/bbslist.c index 39e67b357d6f54d4ac8e37aa2a8186efe8e2e227..cc1995c71c65bb47795f3be9bef9fe635704eb04 100644 --- a/src/syncterm/bbslist.c +++ b/src/syncterm/bbslist.c @@ -2,6 +2,7 @@ #include <dirwrap.h> #include <ini_file.h> +#include <netwrap.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -2956,16 +2957,9 @@ show_bbslist(char *current, int connected) &(list[listcount - 1]->conn_type), NULL, "Connection Type", &(conn_types[1])) >= 0) { list[listcount - 1]->conn_type++; - if ((list[listcount - 1]->conn_type != CONN_TYPE_MODEM) - && (list[listcount - 1]->conn_type - != CONN_TYPE_SERIAL) - && (list[listcount - 1]->conn_type - != CONN_TYPE_SERIAL_NORTS) - && (list[listcount - 1]->conn_type - != CONN_TYPE_SHELL)) { + if (IS_NETWORK_CONN(list[listcount - 1]->conn_type)) { /* Default address to name, if appears to be address */ - if (strchr(list[listcount - 1]->name, ' ') == NULL - && strchr(list[listcount - 1]->name, '.') != NULL) + if (isResolvableHostname(list[listcount - 1]->name)) SAFECOPY(list[listcount - 1]->addr, list[listcount - 1]->name); /* Set the port too */ j = conn_ports[list[listcount - 1]->conn_type]; diff --git a/src/syncterm/conn.h b/src/syncterm/conn.h index 82cb1d9e4e6cdad685e438c5ea017ff69d44aa81..ff39ccd7a4b047a914b8919964a5d9381d007895 100644 --- a/src/syncterm/conn.h +++ b/src/syncterm/conn.h @@ -45,6 +45,16 @@ enum { CONN_TYPE_TERMINATOR }; +#define IS_NETWORK_CONN(x) ( \ + ((x) == CONN_TYPE_RLOGIN) || \ + ((x) == CONN_TYPE_RLOGIN_REVERSED) || \ + ((x) == CONN_TYPE_TELNET) || \ + ((x) == CONN_TYPE_RAW) || \ + ((x) == CONN_TYPE_SSH) || \ + ((x) == CONN_TYPE_SSHNA) || \ + ((x) == CONN_TYPE_MBBS_GHOST) || \ + ((x) == CONN_TYPE_TELNETS)) + struct conn_api { int (*connect)(struct bbslist *bbs); int (*close)(void); diff --git a/src/xpdev/netwrap.c b/src/xpdev/netwrap.c index 40c807ed1878035483f46821dffd025f247897da..3abd399f73c3a3d00596500e070922d386f426da 100644 --- a/src/xpdev/netwrap.c +++ b/src/xpdev/netwrap.c @@ -172,6 +172,125 @@ const char* IPv4AddressToStr(uint32_t addr, char* dest, size_t size) #endif } +/* + * While RFC-952 limits a name to 24 characters, this is never enforced. + * RFC-952 also doesn't allow beginning or ending with a hyphen. + * RFC-952 also bans starting with a digit. + * RFC-1123 explicitly overrode the restriction against starting with a digit. + * RFC-1123 implicitly overrode the length restriction. + * + * The limit of 63 characters for a name comes from DNS, as does the 253 + * (254 with trailing dot) overall limit. If DNS isn't used, it's chaos. + */ +static bool +isValidHostnameString(const char *str) +{ + size_t pos; + size_t seglen = 0; + size_t totallen = 0; + size_t segcount = 0; + bool last_was_hyphen = false; + + while (*str) { + if ((*str >= 'a' && *str <= 'z') + || (*str >= 'A' && *str <= 'Z') + || (*str >= '0' && *str <= '9') + || (*str == '-') + || (*str == '.')) { + if (*str == '.') { + if (last_was_hyphen) { + return false; + } + if (seglen == 0) { + return false; + } + seglen = 0; + } + else { + if (seglen == 0) { + if (*str == '-') { + return false; + } + segcount++; + } + seglen++; + if (seglen > 63) { + return false; + } + } + totallen++; + if (totallen > 253) { + // Allow a trailing dot + if (totallen != 254 || *str != '.') { + return false; + } + } + last_was_hyphen = (*str == '-'); + } + else { + return false; + } + str++; + } + + return true; +} + +bool +isValidAddressString(const char *str) +{ + struct sockaddr_in in; + struct sockaddr_in6 in6; + + /* + * Per RFC-1123, we need to check for valid IP address first + */ + if (xp_inet_pton(AF_INET, str, &in) != -1) + return true; + if (xp_inet_pton(AF_INET6, str, &in6) != -1) + return true; + + return false; +} + +bool +isValidHostname(const char *str) +{ + /* + * Per RFC-1123, we need to check for valid IP address first + */ + if (isValidAddressString(str)) + return true; + + return isValidHostnameString(str); +} + +bool +isResolvableHostname(const char *str) +{ + if (!isValidHostname(str)) { + return false; + } + + struct addrinfo hints = {0}; + struct addrinfo *res = NULL; + const char portnum[2] = "1"; + + hints.ai_flags = PF_UNSPEC; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_NUMERICSERV; +#ifdef AI_ADDRCONFIG + hints.ai_flags |= AI_ADDRCONFIG; +#endif + if (getaddrinfo(str, portnum, &hints, &res) != 0) { + return false; + } + freeaddrinfo(res); + return true; +} + #if NETWRAP_TEST int main(int argc, char** argv) { diff --git a/src/xpdev/netwrap.h b/src/xpdev/netwrap.h index c1dffd8f206222cfce41120bdfb5da75a7af0a5a..2863fe140977b20a375bfbfc2c12fa5c9fe9afad 100644 --- a/src/xpdev/netwrap.h +++ b/src/xpdev/netwrap.h @@ -45,6 +45,9 @@ DLLEXPORT void freeNameServerList(str_list_t); DLLEXPORT const char* IPv4AddressToStr(uint32_t, char* dest, size_t size); DLLEXPORT uint32_t parseIPv4Address(const char*); DLLEXPORT struct in6_addr parseIPv6Address(const char*); +DLLEXPORT bool isValidHostname(const char *str); +DLLEXPORT bool isValidAddressString(const char *str); +DLLEXPORT bool isResolvableHostname(const char *str); #if defined(__cplusplus) }