[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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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***/
|
||||
|
||||
Reference in New Issue
Block a user