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

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
client/Makefile.am Normal file
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

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

@@ -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
client/http_resolve_host.c Normal file
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***/

1
common/Makefile.am Normal file
View File

@@ -0,0 +1 @@
EXTRA_DIST = common.h

97
common/common.h Normal file
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***/

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

@@ -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