[client] Added cipherdyne.com backup check in -R mode.

Added backup check against a cipherdyne.com 'myip' cgi instance in -R mode if
the normal check against cipherdyne.org fails.
This commit is contained in:
Michael Rash
2012-08-15 22:49:29 -04:00
parent a646a024d9
commit 3af8e4c517
4 changed files with 131 additions and 101 deletions
+2
View File
@@ -19,6 +19,8 @@ fwknop-2.0.2 (08//2012):
remote webserver IP resolution mode (-R). Previously IP resolution
could fail if HTTP headers were transferred separately from the data
(for whatever reason). Jonathan Schulz submitted a patch for this.
- [client] Added backup check against a cipherdyne.com 'myip' cgi instance
in -R mode if the normal check against cipherdyne.org fails.
- [server] Bug fix to implement FLUSH_IPT_AT_INIT and FLUSH_IPT_AT_EXIT
functionality. These are enabled by default, and now iptables rules
added by fwknopd can be made persistant by setting these variables to
+2
View File
@@ -152,11 +152,13 @@ main(int argc, char **argv)
* if this fails, consider it fatal.
*/
if (options.resolve_ip_http)
{
if(resolve_ip_http(&options) < 0)
{
fko_destroy(ctx);
return(EXIT_FAILURE);
}
}
/* Set a message string by combining the allow IP and the
* port/protocol. The fwknopd server allows no port/protocol
+2 -1
View File
@@ -63,10 +63,11 @@
* for now.
*/
#define HTTP_RESOLVE_HOST "www.cipherdyne.org"
#define HTTP_BACKUP_RESOLVE_HOST "www.cipherdyne.com"
#define HTTP_RESOLVE_URL "/cgi-bin/myip"
#define HTTP_MAX_REQUEST_LEN 2000
#define HTTP_MAX_RESPONSE_LEN 2000
#define HTTP_MAX_USER_AGENT_LEN 50
#define HTTP_MAX_USER_AGENT_LEN 100
#define MAX_HOSTNAME_LEN 70
#define MAX_URL_HOST_LEN 256
#define MAX_URL_PATH_LEN 1024
+125 -100
View File
@@ -52,90 +52,12 @@ struct url
};
static int
parse_url(char *res_url, struct url* url)
{
char *s_ndx, *e_ndx;
int tlen, tlen_offset, port;
/* https is not supported.
*/
if(strncasecmp(res_url, "https", 5) == 0)
{
fprintf(stderr, "https is not yet supported for http-resolve-ip.\n");
return(-1);
}
/* Strip off http:// portion if necessary
*/
if(strncasecmp(res_url, "http://", 7) == 0)
s_ndx = res_url + 7;
else
s_ndx = res_url;
/* Look for a colon in case an alternate port was specified.
*/
e_ndx = strchr(s_ndx, ':');
if(e_ndx != NULL)
{
port = atoi(e_ndx+1);
if(port < 1 || port > MAX_PORT)
{
fprintf(stderr, "resolve-url port value is invalid.\n");
return(-1);
}
sprintf(url->port, "%u", port);
/* Get the offset we need to skip the port portion when we
* extract the hostname part.
*/
tlen_offset = strlen(url->port)+1;
}
else
{
strlcpy(url->port, "80", 3);
tlen_offset = 0;
}
e_ndx = strchr(s_ndx, '/');
if(e_ndx == NULL)
tlen = strlen(s_ndx)+1;
else
tlen = (e_ndx-s_ndx)+1;
tlen -= tlen_offset;
if(tlen > MAX_URL_HOST_LEN)
{
fprintf(stderr, "resolve-url hostname portion is too large.\n");
return(-1);
}
strlcpy(url->host, s_ndx, tlen);
if(e_ndx != NULL)
{
if(strlen(e_ndx) > MAX_URL_PATH_LEN)
{
fprintf(stderr, "resolve-url path portion is too large.\n");
return(-1);
}
strlcpy(url->path, e_ndx, MAX_URL_PATH_LEN);
}
else
*(url->path) = '\0';
return(0);
}
int
resolve_ip_http(fko_cli_options_t *options)
try_url(struct url *url, fko_cli_options_t *options)
{
int sock, res, error, http_buf_len, i;
int bytes_read = 0, position = 0;
int o1, o2, o3, o4;
struct addrinfo *result, *rp, hints;
struct url url;
char http_buf[HTTP_MAX_REQUEST_LEN];
char http_response[HTTP_MAX_RESPONSE_LEN] = {0};
char *ndx;
@@ -153,28 +75,15 @@ resolve_ip_http(fko_cli_options_t *options)
}
#endif
if(options->resolve_url != NULL)
{
if(parse_url(options->resolve_url, &url) < 0)
{
fprintf(stderr, "Error parsing resolve-url\n");
return(-1);
}
} else {
strlcpy(url.port, "80", 3);
strlcpy(url.host, HTTP_RESOLVE_HOST, MAX_URL_HOST_LEN);
strlcpy(url.path, HTTP_RESOLVE_URL, MAX_URL_PATH_LEN);
}
/* Build our HTTP request to resolve the external IP (this is similar to
* to contacting whatismyip.org, but using a different URL).
*/
snprintf(http_buf, HTTP_MAX_REQUEST_LEN,
"GET %s HTTP/1.0\r\nUser-Agent: %s\r\nAccept: */*\r\n"
"Host: %s\r\nConnection: close\r\n\r\n",
url.path,
url->path,
options->http_user_agent,
url.host
url->host
);
http_buf_len = strlen(http_buf);
@@ -185,7 +94,7 @@ resolve_ip_http(fko_cli_options_t *options)
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
error = getaddrinfo(url.host, url.port, &hints, &result);
error = getaddrinfo(url->host, url->port, &hints, &result);
if (error != 0)
{
fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
@@ -282,19 +191,135 @@ resolve_ip_http(fko_cli_options_t *options)
{
strlcpy(options->allow_ip_str, ndx, MAX_IPV4_STR_LEN);
if(options->verbose > 1)
printf("\nHTTP response: %s\n", http_response);
if(options->verbose)
printf("Resolved external IP (via http://%s%s) as: %s\n",
url.host,
url.path,
printf("\n[+] Resolved external IP (via http://%s%s) as: %s\n",
url->host,
url->path,
options->allow_ip_str);
return(0);
return(1);
}
else
{
fprintf(stderr, "Invalid IP (%s) in HTTP response.\n", ndx);
fprintf(stderr, "Invalid IP (%s) in HTTP response:\n\n%s\n",
ndx, http_response);
return(-1);
}
}
static int
parse_url(char *res_url, struct url* url)
{
char *s_ndx, *e_ndx;
int tlen, tlen_offset, port;
/* https is not supported.
*/
if(strncasecmp(res_url, "https", 5) == 0)
{
fprintf(stderr, "https is not yet supported for http-resolve-ip.\n");
return(-1);
}
/* Strip off http:// portion if necessary
*/
if(strncasecmp(res_url, "http://", 7) == 0)
s_ndx = res_url + 7;
else
s_ndx = res_url;
/* Look for a colon in case an alternate port was specified.
*/
e_ndx = strchr(s_ndx, ':');
if(e_ndx != NULL)
{
port = atoi(e_ndx+1);
if(port < 1 || port > MAX_PORT)
{
fprintf(stderr, "resolve-url port value is invalid.\n");
return(-1);
}
sprintf(url->port, "%u", port);
/* Get the offset we need to skip the port portion when we
* extract the hostname part.
*/
tlen_offset = strlen(url->port)+1;
}
else
{
strlcpy(url->port, "80", 3);
tlen_offset = 0;
}
e_ndx = strchr(s_ndx, '/');
if(e_ndx == NULL)
tlen = strlen(s_ndx)+1;
else
tlen = (e_ndx-s_ndx)+1;
tlen -= tlen_offset;
if(tlen > MAX_URL_HOST_LEN)
{
fprintf(stderr, "resolve-url hostname portion is too large.\n");
return(-1);
}
strlcpy(url->host, s_ndx, tlen);
if(e_ndx != NULL)
{
if(strlen(e_ndx) > MAX_URL_PATH_LEN)
{
fprintf(stderr, "resolve-url path portion is too large.\n");
return(-1);
}
strlcpy(url->path, e_ndx, MAX_URL_PATH_LEN);
}
else
*(url->path) = '\0';
return(0);
}
int
resolve_ip_http(fko_cli_options_t *options)
{
int res;
struct url url;
if(options->resolve_url != NULL)
{
if(parse_url(options->resolve_url, &url) < 0)
{
fprintf(stderr, "Error parsing resolve-url\n");
return(-1);
}
res = try_url(&url, options);
} else {
strlcpy(url.port, "80", 3);
strlcpy(url.host, HTTP_RESOLVE_HOST, MAX_URL_HOST_LEN);
strlcpy(url.path, HTTP_RESOLVE_URL, MAX_URL_PATH_LEN);
res = try_url(&url, options);
if(res != 1)
{
/* try the backup url (just switches the host to cipherdyne.com)
*/
strlcpy(url.host, HTTP_BACKUP_RESOLVE_HOST, MAX_URL_HOST_LEN);
sleep(2);
res = try_url(&url, options);
}
}
return(res);
}
/***EOF***/