Major rearrangement. Renamed directories: "fko" to "lib", "src" to "client". Added "common" and "server" directories. Setup autoconf to allow disabling the server and/or client builds.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@127 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart
2009-08-09 15:43:16 +00:00
parent 078661e355
commit 53b7fae8bb
56 changed files with 327 additions and 222 deletions
+14 -1
View File
@@ -1,4 +1,17 @@
SUBDIRS = fko src doc
if WANT_CLIENT
CLIENT_DIR = client
endif
if WANT_SERVER
SERVER_DIR = server
endif
SUBDIRS = \
lib \
common \
$(CLIENT_DIR) \
$(SERVER_DIR) \
doc
EXTRA_DIST = \
perl/FKO/README \
+8
View File
@@ -0,0 +1,8 @@
bin_PROGRAMS = fwknop
fwknop_SOURCES = fwknop.c fwknop.h config_init.c config_init.h \
fwknop_common.h spa_comm.c spa_comm.h utils.c utils.h \
http_resolve_host.c getpasswd.c getpasswd.h
fwknop_LDADD = $(top_builddir)/lib/libfko.la
fwknop_CPPFLAGS = -I $(top_srcdir)/lib -I $(top_srcdir)/common
+29 -132
View File
@@ -40,7 +40,10 @@ static int set_message_type(fko_ctx_t ctx, fko_cli_options_t *options);
static int set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options);
static int get_rand_port(fko_ctx_t ctx);
static void dump_transmit_options(fko_cli_options_t *options);
static void resolve_ip_http(fko_cli_options_t *options);
int resolve_ip_http(fko_cli_options_t *options);
int
main(int argc, char **argv)
@@ -69,7 +72,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_new", res);
return(1);
return(EXIT_FAILURE);
}
/* Display version info and exit.
@@ -80,7 +83,7 @@ main(int argc, char **argv)
fprintf(stdout, "[+] fwknop client %s, FKO protocol version %s\n",
MY_VERSION, version);
return(0);
return(EXIT_SUCCESS);
}
/* Set client timeout
@@ -91,7 +94,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_set_spa_client_timeout", res);
return(1);
return(EXIT_FAILURE);
}
}
@@ -101,7 +104,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_set_spa_message_type", res);
return(1);
return(EXIT_FAILURE);
}
if(options.server_command[0] != 0x0)
@@ -114,8 +117,12 @@ main(int argc, char **argv)
}
else
{
/* Resolve the client's public facing IP address if requestesd.
* if this fails, consider it fatal.
*/
if (options.resolve_ip_http)
resolve_ip_http(&options);
if(resolve_ip_http(&options) < 0)
return(EXIT_FAILURE);
/* Set a message string by combining the allow IP and the
* port/protocol. The fwknopd server allows no port/protocol
@@ -137,7 +144,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_set_spa_message", res);
return(1);
return(EXIT_FAILURE);
}
/* Set NAT access string
@@ -148,7 +155,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_set_nat_access_str", res);
return(1);
return(EXIT_FAILURE);
}
}
@@ -160,7 +167,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_set_username", res);
return(1);
return(EXIT_FAILURE);
}
}
@@ -180,7 +187,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_set_spa_encryption_type", res);
return(1);
return(EXIT_FAILURE);
}
/* If a GPG home dir was specified, set it here. Note: Setting
@@ -193,7 +200,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_set_gpg_home_dir", res);
return(1);
return(EXIT_FAILURE);
}
}
@@ -204,7 +211,7 @@ main(int argc, char **argv)
if(IS_GPG_ERROR(res))
fprintf(stderr, "GPG ERR: %s\n", fko_gpg_errorstr(ctx));
return(1);
return(EXIT_FAILURE);
}
if(options.gpg_signer_key != NULL && strlen(options.gpg_signer_key))
@@ -217,7 +224,7 @@ main(int argc, char **argv)
if(IS_GPG_ERROR(res))
fprintf(stderr, "GPG ERR: %s\n", fko_gpg_errorstr(ctx));
return(1);
return(EXIT_FAILURE);
}
}
}
@@ -230,7 +237,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_set_spa_digest_type", res);
return(1);
return(EXIT_FAILURE);
}
}
@@ -244,7 +251,7 @@ main(int argc, char **argv)
if(IS_GPG_ERROR(res))
fprintf(stderr, "GPG ERR: %s\n", fko_gpg_errorstr(ctx));
return(1);
return(EXIT_FAILURE);
}
/* Display the context data.
@@ -274,7 +281,7 @@ main(int argc, char **argv)
if(res < 0)
{
fprintf(stderr, "[*] send_spa_packet: packet not sent.\n");
return(1);
return(EXIT_FAILURE);
}
else
{
@@ -292,7 +299,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_get_spa_data", res);
return(1);
return(EXIT_FAILURE);
}
/* If gpg-home-dir is specified, we have to defer decrypting if we
@@ -307,7 +314,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_new_with_data", res);
return(1);
return(EXIT_FAILURE);
}
/* See if we are using gpg and if we need to set the GPG home dir.
@@ -320,7 +327,7 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_set_gpg_home_dir", res);
return(1);
return(EXIT_FAILURE);
}
}
}
@@ -343,10 +350,10 @@ main(int argc, char **argv)
debugging purposes. */
fprintf(stderr, "GPG ERR: %s\n%s\n", fko_gpg_errorstr(ctx2),
"[*] No access to recipient private key?\n");
return(0);
return(EXIT_SUCCESS);
}
return(1);
return(EXIT_FAILURE);
}
printf("\nDump of the Decoded Data\n");
@@ -357,7 +364,7 @@ main(int argc, char **argv)
fko_destroy(ctx);
return(0);
return(EXIT_SUCCESS);
}
static void
@@ -448,116 +455,6 @@ ipv4_str_has_port(char *str)
return rv;
}
static void resolve_ip_http(fko_cli_options_t *options)
{
int sock, res, error, http_buf_len, i;
struct addrinfo *result, *rp, hints;
char http_buf[HTTP_MAX_REQUEST_LEN];
char http_response[HTTP_MAX_RESPONSE_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,
"%s%s%s%s%s%s%s",
"GET ",
HTTP_RESOLVE_URL,
" HTTP/1.0\r\nUser-Agent: ",
options->http_user_agent,
"\r\nAccept: */*\r\nHost: ",
HTTP_RESOLVE_HOST,
"\r\nConnection: Keep-Alive\r\n\r\n"
);
http_buf_len = strlen(http_buf);
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
error = getaddrinfo(HTTP_RESOLVE_HOST, "80", &hints, &result);
if (error != 0)
{
fprintf(stderr, "[*] error in getaddrinfo: %s\n", gai_strerror(error));
exit(EXIT_FAILURE);
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
sock = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sock < 0)
continue;
if (error = connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* made it */
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif
}
if (rp == NULL) {
perror("[*] resolve_ip_http: Could not create socket: ");
exit(EXIT_FAILURE);
}
freeaddrinfo(result);
res = send(sock, http_buf, http_buf_len, 0);
if(res < 0)
{
perror("[*] resolve_ip_http: write error: ");
}
else if(res != http_buf_len)
{
fprintf(stderr,
"[#] Warning: bytes sent (%i) not spa data length (%i).\n",
res, http_buf_len
);
}
res = recv(sock, http_response, HTTP_MAX_RESPONSE_LEN, 0);
http_response[HTTP_MAX_RESPONSE_LEN-1] = '\0';
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif
/* Now parse the response for the IP address (which should be at
* the end of the string
*/
for (i=res-3; i >= 0; i--)
{
if(http_response[i] == '\n')
break;
if(http_response[i] != '.' && ! isdigit(http_response[i]))
{
fprintf(stderr, "[*] Invalid IP in HTTP response.\n");
exit(EXIT_FAILURE);
}
}
if (i < MIN_IP_STR_LEN)
{
fprintf(stderr, "[*] Invalid IP in HTTP response.\n");
exit(EXIT_FAILURE);
}
http_response[res-1] = '\0';
strlcpy(options->allow_ip_str,
(http_response + i+1), (res - (i+2)));
printf("[+] Resolved external IP (via http://%s%s) as: %s\n",
HTTP_RESOLVE_HOST, HTTP_RESOLVE_URL, options->allow_ip_str);
return;
}
/* Set NAT access string
*/
static int
View File
+7 -73
View File
@@ -26,49 +26,13 @@
#ifndef FWKNOP_COMMON_H
#define FWKNOP_COMMON_H
/* Common includes for our other fwknop client source files.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#if STDC_HEADERS
#include <stdlib.h>
#include <string.h>
#elif HAVE_STRINGS_H
#include <strings.h>
#endif /* STDC_HEADERS*/
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef WIN32
#define strncasecmp _strnicmp
#define snprintf _snprintf
#define unlink _unlink
#else
#include <signal.h>
#endif
#include "fko.h"
#include "common.h"
/* My Name and Version
*/
#define MY_NAME "fwknop"
#define MY_DESC "Single Packet Authorization client"
#define FKO_PROTO_VERSION "1.9.12"
/* Get our program version from VERSION (defined in config.h).
*/
#define MY_VERSION VERSION
@@ -77,33 +41,13 @@
*/
#define DEF_CONFIG_FILE MY_NAME".conf"
/* Protocol assignment values
/* For time offset handling
*/
enum {
FKO_PROTO_UDP,
FKO_PROTO_TCP,
FKO_PROTO_TCP_RAW,
FKO_PROTO_ICMP,
FKO_PROTO_HTTP,
};
/* Other common defines
*/
#define FKO_DEFAULT_PROTO FKO_PROTO_UDP
#define FKO_DEFAULT_PORT 62201
#define DEFAULT_NAT_PORT 55000
#define MIN_HIGH_PORT 10000 /* sensible minimum for SPA dest port */
#define MAX_PORT 65535
#define MAX_PORT_STR_LEN 6
#define MAX_PROTO_STR_LEN 6
#define MAX_IP_STR_LEN 16
#define MIN_IP_STR_LEN 9
#define MAX_SERVER_STR_LEN 50
#define MAX_LINE_LEN 1024
#define MAX_PATH_LEN 1024
#define MAX_GPG_KEY_ID 128
#define MAX_USERNAME_LEN 30
#define MAX_TIME_STR_LEN 9
#define TIME_OFFSET_SECONDS 1
#define TIME_OFFSET_MINUTES 60
#define TIME_OFFSET_HOURS 3600
#define TIME_OFFSET_DAYS 86400
/* For resolving the allow IP via HTTP and sending SPA packets over
* HTTP
@@ -114,16 +58,6 @@ enum {
#define HTTP_MAX_RESPONSE_LEN 2000
#define HTTP_MAX_USER_AGENT_LEN 50
/* For time offset handling
*/
#define MAX_TIME_STR_LEN 9
enum {
TIME_OFFSET_SECONDS,
TIME_OFFSET_MINUTES,
TIME_OFFSET_HOURS,
TIME_OFFSET_DAYS
};
/* fwknop client configuration parameters and values
*/
typedef struct fko_cli_options
+140
View File
@@ -0,0 +1,140 @@
/*
*****************************************************************************
*
* File: http_resolve_host.c
*
* Author: Damien S. Stuart
*
* Purpose: Routine for using an http request to obtain a client's IP
* address as seen from the outside world.
*
* Copyright (C) 2009 Damien Stuart (dstuart@dstuart.org)
*
* License (GNU Public License):
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
*****************************************************************************
*/
#include "fwknop_common.h"
#include <netdb.h>
int
resolve_ip_http(fko_cli_options_t *options)
{
int sock, res, error, http_buf_len, i;
struct addrinfo *result, *rp, hints;
char http_buf[HTTP_MAX_REQUEST_LEN];
char http_response[HTTP_MAX_RESPONSE_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
);
http_buf_len = strlen(http_buf);
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
error = getaddrinfo(HTTP_RESOLVE_HOST, "80", &hints, &result);
if (error != 0)
{
fprintf(stderr, "[*] error in getaddrinfo: %s\n", gai_strerror(error));
return(-1);
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
sock = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sock < 0)
continue;
if (error = connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* made it */
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif
}
if (rp == NULL) {
perror("[*] resolve_ip_http: Could not create socket: ");
return(-1);
}
freeaddrinfo(result);
res = send(sock, http_buf, http_buf_len, 0);
if(res < 0)
{
perror("[*] resolve_ip_http: write error: ");
}
else if(res != http_buf_len)
{
fprintf(stderr,
"[#] Warning: bytes sent (%i) not spa data length (%i).\n",
res, http_buf_len
);
}
res = recv(sock, http_response, HTTP_MAX_RESPONSE_LEN, 0);
http_response[HTTP_MAX_RESPONSE_LEN-1] = '\0';
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif
/* Now parse the response for the IP address (which should be at
* the end of the string
*/
for (i=res-3; i >= 0; i--)
{
if(http_response[i] == '\n')
break;
if(http_response[i] != '.' && ! isdigit(http_response[i]))
{
fprintf(stderr, "[*] Invalid IP in HTTP response.\n");
return(-1);
}
}
if (i < MIN_IP_STR_LEN)
{
fprintf(stderr, "[*] Invalid IP in HTTP response.\n");
return(-1);
}
http_response[res-1] = '\0';
strlcpy(options->allow_ip_str,
(http_response + i+1), (res - (i+2)));
if(options->verbose)
printf("[+] Resolved external IP (via http://%s%s) as: %s\n",
HTTP_RESOLVE_HOST, HTTP_RESOLVE_URL, options->allow_ip_str);
return(0);
}
/***EOF***/
View File
View File
+1
View File
@@ -0,0 +1 @@
EXTRA_DIST = common.h
+97
View File
@@ -0,0 +1,97 @@
/*
******************************************************************************
*
* File: common.h
*
* Author: Damien Stuart
*
* Purpose: Common header file for fwknop client and server programs.
*
* Copyright (C) 2009 Damien Stuart (dstuart@dstuart.org)
*
* License (GNU Public License):
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
******************************************************************************
*/
#ifndef _COMMON_H
#define _COMMON_H
/* Common includes for our other fwknop client and server source files.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#if STDC_HEADERS
#include <stdlib.h>
#include <string.h>
#elif HAVE_STRINGS_H
#include <strings.h>
#endif /* STDC_HEADERS*/
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef WIN32
#define strncasecmp _strnicmp
#define snprintf _snprintf
#define unlink _unlink
#else
#include <signal.h>
#endif
#include "fko.h"
/* Get our program version from VERSION (defined in config.h).
*/
#define MY_VERSION VERSION
enum {
FKO_PROTO_UDP,
FKO_PROTO_TCP,
FKO_PROTO_TCP_RAW,
FKO_PROTO_ICMP,
FKO_PROTO_HTTP,
};
/* Other common defines
*/
#define FKO_DEFAULT_PROTO FKO_PROTO_UDP
#define FKO_DEFAULT_PORT 62201
#define DEFAULT_NAT_PORT 55000
#define MIN_HIGH_PORT 10000 /* sensible minimum for SPA dest port */
#define MAX_PORT 65535
#define MAX_PORT_STR_LEN 6
#define MAX_PROTO_STR_LEN 6
#define MAX_IP_STR_LEN 16
#define MIN_IP_STR_LEN 9
#define MAX_SERVER_STR_LEN 50
#define MAX_LINE_LEN 1024
#define MAX_PATH_LEN 1024
#define MAX_GPG_KEY_ID 128
#define MAX_USERNAME_LEN 30
#endif /* _COMMON_H */
/***EOF***/
+31 -8
View File
@@ -7,10 +7,10 @@ m4_define(my_version, [0.63])
m4_define(my_bug_email, [dstuart@dstuart.org])
AC_INIT(my_package, my_version, my_bug_email)
AC_CONFIG_AUX_DIR(config)
#AM_INIT_AUTOMAKE(my_package, my_version)
AM_INIT_AUTOMAKE([-Wall foreign])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
dnl AM_MAINTAINER_MODE
@@ -20,9 +20,9 @@ AC_GNU_SOURCE
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CXX
AC_PROG_AWK
AC_PROG_CPP
AC_PROG_AWK
AC_PROG_GREP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
@@ -169,16 +169,39 @@ AS_IF([test "x$with_gpgme" != xno],
fi
], [have_gpgme=no])], [have_gpgme=no])
dnl Decide whether or not to build the client
dnl
want_client=yes
AC_ARG_ENABLE([client],
[AS_HELP_STRING([--enable-client],
[Build the fwknop client @<:@default=yes@:>@])],
[want_client=$enableval],
[])
AM_CONDITIONAL([WANT_CLIENT], [test "$want_client" = yes])
dnl Decide whether or not to build the server
dnl
want_server=yes
AC_ARG_ENABLE([server],
[AS_HELP_STRING([--enable-server],
[Build the fwknop server @<:@default=yes@:>@])],
[want_server=$enableval],
[])
AM_CONDITIONAL([WANT_SERVER], [test "$want_server" = yes])
AC_CONFIG_FILES([Makefile
fko/Makefile
doc/Makefile
src/Makefile])
lib/Makefile
client/Makefile
server/Makefile
common/Makefile
doc/Makefile])
AC_OUTPUT
echo "
libfko v${VERSION} has been configured.
============================================
GPG encryption support: $have_gpgme
Client build: $want_client
Server build: $want_server
GPG encryption support: $have_gpgme
"
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
-8
View File
@@ -1,8 +0,0 @@
bin_PROGRAMS = fwknop
fwknop_SOURCES = fwknop.c fwknop.h config_init.c config_init.h \
fwknop_common.h spa_comm.c spa_comm.h utils.c utils.h \
getpasswd.c getpasswd.h
fwknop_LDADD = $(top_builddir)/fko/libfko.la
fwknop_CPPFLAGS = -I $(top_srcdir)/fko