Set FD_CLOEXEC on pid file descriptor.
Added support for setting the URL for resolving source IP via command-line or the .fwknoprc file.
This commit is contained in:
parent
ca5f82c067
commit
69f41eb399
@ -350,6 +350,20 @@ parse_rc_param(fko_cli_options_t *options, char *var, char * val)
|
||||
{
|
||||
strlcpy(options->http_user_agent, val, HTTP_MAX_USER_AGENT_LEN);
|
||||
}
|
||||
/* Resolve URL */
|
||||
else if(CONF_VAR_IS(var, "RESOLVE_URL"))
|
||||
{
|
||||
if(options->resolve_url != NULL)
|
||||
free(options->resolve_url);
|
||||
tmpint = strlen(val)+1;
|
||||
options->resolve_url = malloc(tmpint);
|
||||
if(options->resolve_url == NULL)
|
||||
{
|
||||
fprintf(stderr, "Memory allocation error for resolve URL.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
strlcpy(options->resolve_url, val, tmpint);
|
||||
}
|
||||
/* NAT Local ? */
|
||||
else if(CONF_VAR_IS(var, "NAT_LOCAL"))
|
||||
{
|
||||
@ -562,6 +576,9 @@ validate_options(fko_cli_options_t *options)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (options->resolve_url != NULL)
|
||||
options->resolve_ip_http = 1;
|
||||
|
||||
if (!options->resolve_ip_http && options->allow_ip_str[0] == 0x0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
@ -742,6 +759,17 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
case 'R':
|
||||
options->resolve_ip_http = 1;
|
||||
break;
|
||||
case RESOLVE_URL:
|
||||
if(options->resolve_url != NULL)
|
||||
free(options->resolve_url);
|
||||
options->resolve_url = malloc(strlen(optarg)+1);
|
||||
if(options->resolve_url == NULL)
|
||||
{
|
||||
fprintf(stderr, "Memory allocation error for resolve URL.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
strcpy(options->resolve_url, optarg);
|
||||
break;
|
||||
case SHOW_LAST_ARGS:
|
||||
options->show_last_command = 1;
|
||||
break;
|
||||
@ -857,8 +885,12 @@ usage(void)
|
||||
" -S, --source-port Set the source port for outgoing SPA packet.\n"
|
||||
" -Q, --spoof-source Set the source IP for outgoing SPA packet.\n"
|
||||
" -R, --resolve-ip-http Resolve the external network IP by\n"
|
||||
" connecting to the URL:\n"
|
||||
" connecting to a URL such as the default of:\n"
|
||||
" http://" HTTP_RESOLVE_HOST HTTP_RESOLVE_URL "\n"
|
||||
" This can be overridden with the --resolve-url\n"
|
||||
" option.\n"
|
||||
" --resolve-url Override the default URL used for resolving\n"
|
||||
" the source IP address.\n"
|
||||
" -u, --user-agent Set the HTTP User-Agent for resolving the\n"
|
||||
" external IP via -R, or for sending SPA\n"
|
||||
" packets over HTTP.\n"
|
||||
|
||||
@ -49,6 +49,7 @@ enum {
|
||||
TIME_OFFSET_PLUS,
|
||||
NO_SAVE_ARGS,
|
||||
SHOW_LAST_ARGS,
|
||||
RESOLVE_URL,
|
||||
/* Put GPG-related items below the following line */
|
||||
GPG_ENCRYPTION = 0x200,
|
||||
GPG_RECIP_KEY,
|
||||
@ -94,6 +95,7 @@ static struct option cmd_opts[] =
|
||||
{"spoof-src", 1, NULL, 'Q'},
|
||||
{"rand-port", 0, NULL, 'r'},
|
||||
{"resolve-ip-http", 0, NULL, 'R'},
|
||||
{"resolve-url", 1, NULL, RESOLVE_URL},
|
||||
{"show-last", 0, NULL, SHOW_LAST_ARGS},
|
||||
{"source-ip", 0, NULL, 's'},
|
||||
{"source-port", 1, NULL, 'S'},
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
.\" Title: fwknop
|
||||
.\" Author: [see the "AUTHORS" section]
|
||||
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
|
||||
.\" Date: 07/08/2010
|
||||
.\" Date: 07/06/2011
|
||||
.\" Manual: Fwknop Client
|
||||
.\" Source: Fwknop Client
|
||||
.\" Language: English
|
||||
.\"
|
||||
.TH "FWKNOP" "8" "07/08/2010" "Fwknop Client" "Fwknop Client"
|
||||
.TH "FWKNOP" "8" "07/06/2011" "Fwknop Client" "Fwknop Client"
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * set default formatting
|
||||
.\" -----------------------------------------------------------------
|
||||
@ -333,6 +333,11 @@ uses the URL:
|
||||
to resolve the caller IP\&.
|
||||
.RE
|
||||
.PP
|
||||
\fB\-\-resolve\-url\fR
|
||||
.RS 4
|
||||
Override the default URL used for resolving the source IP address\&. For best results, the URL specified here should point to a web service that provides just an IP address in the body of the HTTP response\&.
|
||||
.RE
|
||||
.PP
|
||||
\fB\-s, \-\-source\-ip\fR
|
||||
.RS 4
|
||||
Instruct the
|
||||
@ -472,6 +477,11 @@ resolve the external network IP via HTTP request (the
|
||||
option)\&.
|
||||
.RE
|
||||
.PP
|
||||
\fBRESOLVE_URL\fR
|
||||
.RS 4
|
||||
Set to a URL that will be used for resolving the source IP address (\-\-resolve\-url)\&.
|
||||
.RE
|
||||
.PP
|
||||
\fBTIME_OFFSET\fR
|
||||
.RS 4
|
||||
Set a value to apply to the timestamp in the SPA packet\&. This can be either a positive or negative value (\fI\-\-time\-offset\-plus/minus\fR)\&.
|
||||
|
||||
@ -62,12 +62,14 @@
|
||||
* so we will make the default run on cipherdyne website
|
||||
* for now.
|
||||
*/
|
||||
#define HTTP_RESOLVE_HOST "www.cipherdyne.org"
|
||||
#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 MAX_HOSTNAME_LEN 70
|
||||
#define HTTP_RESOLVE_HOST "www.cipherdyne.org"
|
||||
#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 MAX_HOSTNAME_LEN 70
|
||||
#define MAX_URL_HOST_LEN 256
|
||||
#define MAX_URL_PATH_LEN 1024
|
||||
|
||||
/* fwknop client configuration parameters and values
|
||||
*/
|
||||
@ -101,6 +103,7 @@ typedef struct fko_cli_options
|
||||
/* External IP resolution via HTTP
|
||||
*/
|
||||
int resolve_ip_http;
|
||||
char *resolve_url;
|
||||
char http_user_agent[HTTP_MAX_USER_AGENT_LEN];
|
||||
|
||||
/* HTTP proxy support
|
||||
|
||||
@ -44,12 +44,97 @@
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
struct url
|
||||
{
|
||||
char port[6];
|
||||
char host[256];
|
||||
char path[1024];
|
||||
};
|
||||
|
||||
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 > 65535)
|
||||
{
|
||||
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
|
||||
{
|
||||
strcpy(url->port, "80");
|
||||
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 sock, res, error, http_buf_len, i;
|
||||
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;
|
||||
@ -67,13 +152,28 @@ 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: Keep-Alive\r\n\r\n",
|
||||
HTTP_RESOLVE_URL, options->http_user_agent, HTTP_RESOLVE_HOST
|
||||
url.path,
|
||||
options->http_user_agent,
|
||||
url.host
|
||||
);
|
||||
|
||||
http_buf_len = strlen(http_buf);
|
||||
@ -84,7 +184,7 @@ resolve_ip_http(fko_cli_options_t *options)
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
error = getaddrinfo(HTTP_RESOLVE_HOST, "80", &hints, &result);
|
||||
error = getaddrinfo(url.host, url.port, &hints, &result);
|
||||
if (error != 0)
|
||||
{
|
||||
fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
|
||||
@ -173,7 +273,9 @@ resolve_ip_http(fko_cli_options_t *options)
|
||||
|
||||
if(options->verbose)
|
||||
printf("Resolved external IP (via http://%s%s) as: %s\n",
|
||||
HTTP_RESOLVE_HOST, HTTP_RESOLVE_URL, options->allow_ip_str);
|
||||
url.host,
|
||||
url.path,
|
||||
options->allow_ip_str);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -273,6 +273,11 @@ SPA OPTIONS
|
||||
NAT address. Presently, *fwknop* uses the URL:
|
||||
'http://www.cipherdyne.org/cgi-bin/myip' to resolve the caller IP.
|
||||
|
||||
*--resolve-url*::
|
||||
Override the default URL used for resolving the source IP address. For
|
||||
best results, the URL specified here should point to a web service that
|
||||
provides just an IP address in the body of the HTTP response.
|
||||
|
||||
*-s, --source-ip*::
|
||||
Instruct the *fwknop* client to form an SPA packet that contains the
|
||||
special-case IP address ``+0.0.0.0+'' which will inform the destination
|
||||
@ -391,6 +396,10 @@ description and its matching command-line option(s):
|
||||
to allow (the *-s* option), or use the word "resolve" to have *fwknop*
|
||||
resolve the external network IP via HTTP request (the *-R* option).
|
||||
|
||||
*RESOLVE_URL*::
|
||||
Set to a URL that will be used for resolving the source IP address
|
||||
(--resolve-url).
|
||||
|
||||
*TIME_OFFSET*::
|
||||
Set a value to apply to the timestamp in the SPA packet. This can
|
||||
be either a positive or negative value ('--time-offset-plus/minus').
|
||||
|
||||
@ -586,6 +586,8 @@ write_pid_file(fko_srv_options_t *opts)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fcntl(op_fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
/* Attempt to lock the PID file. If we get an EWOULDBLOCK
|
||||
* error, another instance already has the lock. So we grab
|
||||
* the pid from the existing lock file, complain and bail.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user