Another major re-write of the fwknop library.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@13 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart
2008-12-24 04:31:45 +00:00
parent deb85ddddf
commit a82c361e28
42 changed files with 1674 additions and 1176 deletions

View File

@@ -1 +1 @@
SUBDIRS = lib client server
SUBDIRS = lib src

View File

@@ -6,6 +6,7 @@
#
aclocal
libtoolize --automake
autoheader
automake -a
autoconf

View File

@@ -1,161 +0,0 @@
/* $Id$
*****************************************************************************
*
* File: fwknop.c
*
* Author: Damien S. Stuart
*
* Purpose: fwknop client program (or will be evenually :).
*
* Copyright (C) 2008 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.h"
/* Local prototypes
*/
void init_spa_message(spa_message_t *sm);
void dump_spa_message_data(spa_message_t *sm);
int main(int argc, char **argv)
{
spa_message_t sm;
int enc_size;
char spa_pkt_raw[1024] = {0}; // -DSS what is max size?
uchar spa_pkt_enc[1500] = {0}; // -DSS what is max size?
char spa_pkt_b64[1500] = {0}; // -DSS what is max size?
char *spb64_p = spa_pkt_b64;
char *test_pw = "BubbaWasHere";
/* Initialize - this sets random, user, and other defaults.
*/
init_spa_message(&sm);
/* Timestamp
*/
spa_timestamp(&sm, 0);
/* Construct the spa message based on what we have so far.
*/
spa_message(&sm);
/* Create the digest for this message.
*/
spa_digest(&sm);
/* Dump the spa_message struct - temp for testing.
*/
dump_spa_message_data(&sm);
/* Now take a shot at constructing the packet data.
* --DSS this is just a slap-together for testing at this point.
* I do not think we will do it this way in the end. :)
*/
sprintf(spa_pkt_raw, "%s:%s", sm.message, sm.digest);
/* Encrypt it
*/
enc_size = fko_encrypt((uchar*)spa_pkt_raw, strlen(spa_pkt_raw), test_pw, spa_pkt_enc);
/* Base64 encode it and strip off trailing '='s
*/
b64_encode(spa_pkt_enc, spb64_p, enc_size);
strip_b64_eq(spb64_p);
/* Remove the preceeding encoded "Salted__" string (if it is there).
*/
if(strncmp(spb64_p, "U2FsdGVkX1", 10) == 0)
spb64_p += 10;
printf("Hexdump of encrypted data: (%i bytes)\n", enc_size);
hex_dump(spa_pkt_enc, enc_size);
printf("Base64 version:\n\n%s\n\n", spb64_p);
return(0);
}
/* Initialize the spa_message data struct, and set some default/preliminary
* values.
*/
void init_spa_message(spa_message_t *sm)
{
/* Zero our SPA message struct.
*/
memset(sm, 0x0, sizeof(spa_message_t));
/* Initialize default values.
*/
sm->digest_type = DEFAULT_DIGEST;
sm->enc_pcap_port = DEFAULT_PORT;
sm->message_type = DEFAULT_MSG_TYPE;
sm->client_timeout = DEFAULT_CLIENT_TIMEOUT;
strlcpy(sm->access_str, DEFAULT_ACCESS_STR, MAX_ACCESS_STR_SIZE);
strlcpy(sm->allow_ip, DEFAULT_ALLOW_IP, MAX_IP_ADDR_SIZE);
/* Go ahead and and setup the random and user fields.
*/
spa_random_number(sm);
spa_user(sm, NULL);
/* Version is static, so we add it here as well.
*/
spa_version(sm);
}
/* Pretty print the data in the spa_message data struct.
*/
void dump_spa_message_data(spa_message_t *sm)
{
printf(
"\nCurrent SPA Message Data:\n\n"
" Random Val: '%s'\n"
" User: '%s'\n"
" Timestamp: '%u'\n"
" Version: '%s'\n"
" Message Type: '%u'\n"
" Access: '%s'\n"
" Allow IP: '%s'\n"
" Nat Access: '%s'\n"
" Server Auth: '%s'\n"
" Client Timeout: '%u'\n"
" Message: '%s'\n"
" Digest: '%s'\n"
"\n"
" Digest Type: '%u'\n"
" Port: '%u'\n"
"\n",
sm->rand_val,
sm->user,
sm->timestamp,
sm->version,
sm->message_type,
sm->access_str,
sm->allow_ip,
sm->nat_access,
sm->server_auth,
sm->client_timeout,
sm->message,
sm->digest,
sm->digest_type,
sm->enc_pcap_port
);
}
/***EOF***/

View File

@@ -3,35 +3,53 @@ dnl Process thie file with autoconf to produce teh configure script
AC_PREREQ(2.53)
m4_define(my_package, [fwknop])
m4_define(my_version, [2.0.0])
m4_define(my_version, [2.0.0-alpha])
m4_define(my_bug_email, [dstuart@dstuart.org])
AC_INIT(my_package, my_version)
AC_INIT(my_package, my_version, my_bug_email)
AM_INIT_AUTOMAKE(my_package, my_version)
dnl AM_MAINTAINER_MODE
AC_CONFIG_HEADER([config.h])
AC_GNU_SOURCE
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CXX
AC_PROG_RANLIB
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
# Checks for header files.
#
AC_HEADER_STDC
AC_CHECK_HEADERS([locale.h stdlib.h string.h sys/time.h unistd.h])
# Type checks.
#
AC_C_INLINE
AC_CHECK_SIZEOF(unsigned int)
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_INT8_T
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_TYPE_UINT32_T
AC_TYPE_UINT8_T
AC_C_CONST
# Network library fun.
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname,
[NETLIBS="-lnsl $NETLIBS"]))
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt,
[NETLIBS="-lsocket $NETLIBS"]))
AC_SUBST(NETLIBS)
dnl # Checking for libgpg-error.
dnl AM_PATH_GPG_ERROR(1.4,, AC_MSG_ERROR([libgpg-error was not found]))
dnl AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME,
dnl [The default error source for GPGME.])
dnl # GPGME
dnl AM_PATH_GPGME
# Checks for library functions.
#
AC_CHECK_FUNCS([gettimeofday memmove memset setlocale strchr])
AC_OUTPUT(lib/Makefile client/Makefile server/Makefile Makefile)
# Generate the Makefiles
#
AC_OUTPUT(lib/Makefile src/Makefile Makefile)

View File

@@ -1,26 +1,12 @@
lib_LIBRARIES = libfko.a
libfko_a_SOURCES = base64.c \
md5.c \
spa_message.c \
spa_version.c \
cipher_funcs.c \
rijndael.c \
spa_message_type.c \
strlcat.c \
digest.c \
sha1.c \
spa_random_number.c \
strlcpy.c \
sha256.c \
spa_timestamp.c \
spa_digest.c \
spa_user.c \
base64.h \
cipher_funcs.h \
digest.h \
fwknop.h \
md5.h \
rijndael.h \
sha.h \
types.h
libfko_source_files = \
base64.c base64.h cipher_funcs.c cipher_funcs.h digest.c digest.h \
fko_client_timeout.c fko_common.h fko_digest.c fko_encode.c \
fko_encryption.c fko_error.c fko_funcs.c fko.h fko_message.c \
fko_nat_access.c fko_rand_value.c fko_server_auth.c \
fko_timestamp.c fko_types.h fko_user.c fko_util.c fko_util.h \
md5.c md5.h rijndael.c rijndael.h sha1.c sha256.c sha.h strlcat.c \
strlcpy.c
libfko_a_SOURCES = $(libfko_source_files)

View File

@@ -22,10 +22,9 @@
*
*****************************************************************************
*/
#include "types.h"
#include "base64.h"
static unsigned char map2[] =
static uchar map2[] =
{
0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff,
@@ -53,13 +52,10 @@ int b64_decode(char *in, uchar *out, int out_len)
v = (v << 6) + map2[index];
if (i & 3) {
//--DSS temp for test
//if (dst - out < out_len) {
*dst++ = v >> (6 - 2 * (i & 3));
//}
}
if (i & 3)
*dst++ = v >> (6 - 2 * (i & 3));
}
*dst = '\0';
return(dst - out);

View File

@@ -21,12 +21,10 @@
*
*****************************************************************************
*/
#ifndef _BASE64_H_
#define _BASE64_H_
#ifndef BASE64_H
#define BASE64_H 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "fko_common.h"
/* Prototypes
*/
@@ -34,6 +32,6 @@ int b64_encode(uchar *in, char *out, int in_len);
int b64_decode(char *in, uchar *out, int out_len);
void strip_b64_eq(char *data);
#endif /* _BASE64_H_ */
#endif /* BASE64_H */
/***EOF***/

View File

@@ -34,7 +34,7 @@
/* Get random data.
*/
void get_random_data(uint8 *data, int len)
void get_random_data(unsigned char *data, int len)
{
FILE *rfd;
struct timeval tv;
@@ -67,15 +67,15 @@ void get_random_data(uint8 *data, int len)
* This is is done to be compatible with the data produced via
* the Perl Crypt::CBC module's use of Rijndael.
*/
void salt_and_iv(RIJNDAEL_context *ctx, char *pass, uint8 *data)
void salt_and_iv(RIJNDAEL_context *ctx, char *pass, unsigned char *data)
{
char pw_buf[16];
uint8 tmp_buf[64]; /* How big does this need to be? */
uint8 kiv_buf[48]; /* Key and IV buffer */
uint8 md5_buf[16]; /* Buffer for computed md5 hash */
char pw_buf[16];
unsigned char tmp_buf[64]; /* How big does this need to be? */
unsigned char kiv_buf[48]; /* Key and IV buffer */
unsigned char md5_buf[16]; /* Buffer for computed md5 hash */
int kiv_len = 0;
int plen = strlen(pass);
int kiv_len = 0;
int plen = strlen(pass);
/* First make pw 16 bytes (pad with "0" (ascii 0x30)) or truncate.
* Note: pw_buf was initialized with '0' chars (again, not the value
@@ -132,7 +132,7 @@ void salt_and_iv(RIJNDAEL_context *ctx, char *pass, uint8 *data)
/* Initialization entry point.
*/
void rijndael_init(RIJNDAEL_context *ctx, char *pass, uchar *data)
void rijndael_init(RIJNDAEL_context *ctx, char *pass, unsigned char *data)
{
/* Use ECB mode to be compatible with the Crypt::CBC perl module.
@@ -151,15 +151,15 @@ void rijndael_init(RIJNDAEL_context *ctx, char *pass, uchar *data)
/* Take a chunk of data, encrypt it in the same way the perl Crypt::CBC
* module would.
*/
int fko_encrypt(uchar *in, int in_len, char *pass, uchar *out)
int fko_encrypt(unsigned char *in, int in_len, char *pass, unsigned char *out)
{
RIJNDAEL_context ctx;
uint8 plaintext[16];
uint8 mixtext[16];
uint8 ciphertext[16];
unsigned char plaintext[16];
unsigned char mixtext[16];
unsigned char ciphertext[16];
int i, pad_val;
uchar *ondx = out;
unsigned char *ondx = out;
rijndael_init(&ctx, pass, NULL);
@@ -204,15 +204,15 @@ int fko_encrypt(uchar *in, int in_len, char *pass, uchar *out)
/* Decrypt the given data.
*/
int fko_decrypt(uchar *in, int in_len, char *pass, uchar *out)
int fko_decrypt(unsigned char *in, int in_len, char *pass, unsigned char *out)
{
RIJNDAEL_context ctx;
uint8 plaintext[16];
uint8 mixtext[16];
uint8 ciphertext[16];
unsigned char plaintext[16];
unsigned char mixtext[16];
unsigned char ciphertext[16];
int i, pad_val, pad_err = 0;
uchar *pad_s;
uchar *ondx = out;
unsigned char *pad_s;
unsigned char *ondx = out;
rijndael_init(&ctx, pass, in);
@@ -266,7 +266,8 @@ int fko_decrypt(uchar *in, int in_len, char *pass, uchar *out)
return(ondx - out);
}
void hex_dump(uchar *data, int size)
/*
void hex_dump(unsigned char *data, int size)
{
int ln, i, j = 0;
char ascii_str[17] = {0};
@@ -288,8 +289,7 @@ void hex_dump(uchar *data, int size)
printf(" ");
}
/* Remainder...
*/
// Remainder...
ln = strlen(ascii_str);
if(ln > 0)
{
@@ -299,6 +299,6 @@ void hex_dump(uchar *data, int size)
printf(" %s\n\n", ascii_str);
}
}
*/
/***EOF***/

View File

@@ -21,10 +21,10 @@
*
*****************************************************************************
*/
#ifndef _CIPHER_FUNCS_H_
#define _CIPHER_FUNCS_H_
#ifndef CIPHER_FUNCS_H
#define CIPHER_FUNCS_H 1
#include "types.h"
#include "fko_common.h"
#include "rijndael.h"
/* Provide the predicted encrypted data size for given input data based
@@ -37,6 +37,6 @@ int fko_encrypt(uchar *in, int len, char *key, uchar *out);
int fko_decrypt(uchar *in, int len, char *key, uchar *out);
void hex_dump(uchar *data, int size);
#endif /* _CIPHER_FUNCS_H_ */
#endif /* CIPHER_FUNCS_H */
/***EOF***/

View File

@@ -43,7 +43,7 @@ void md5(uchar *out, uchar *in, int size)
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (unsigned char*)in, size);
MD5Update(&ctx, (uchar*)in, size);
MD5Final(out, &ctx);
}

View File

@@ -21,21 +21,25 @@
*
*****************************************************************************
*/
#ifndef _DIGEST_H_
#define _DIGEST_H_
#ifndef DIGEST_H
#define DIGEST_H 1
#include <endian.h>
#include "types.h"
#include "fko_common.h"
/* This should be fine for most linux systems (hopefully).
* TODO: We should look into the portability of this. --DSS
*/
#define BYTEORDER __BYTE_ORDER
#include "md5.h"
#include "sha.h"
/* Size calculation macros
*/
#define MD_HEX_SIZE(x) x * 2
#define MD_B64_SIZE(x) ((x * 4) / 3) + 1
void md5(uchar* out, uchar* in, int size);
void md5_hex(char* out, uchar* in, int size);
void md5_base64(char* out, uchar* in, int size);
@@ -46,6 +50,6 @@ void sha256(uchar* out, uchar* in, int size);
void sha256_hex(char* out, uchar* in, int size);
void sha256_base64(char* out, uchar* in, int size);
#endif /* _DIGEST_H_ */
#endif /* DIGEST_H */
/***EOF***/

200
lib/fko.h Normal file
View File

@@ -0,0 +1,200 @@
/* $Id$
*****************************************************************************
*
* File: fko.h
*
* Author: Damien S. Stuart
*
* Purpose: Header for the fwknop source files
*
* Copyright (C) 2008 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 FKO_H
#define FKO_H 1
/* General params
*/
#define FKO_PROTOCOL_VERSION "1.9.10" /* The fwknop protocol version */
/* Supported FKO Message types...
*/
enum {
FKO_COMMAND_MSG = 0,
FKO_ACCESS_MSG,
FKO_NAT_ACCESS_MSG,
FKO_CLIENT_TIMEOUT_ACCESS_MSG,
FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG,
FKO_LOCAL_NAT_ACCESS_MSG,
FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG,
FKO_LAST_MSG_TYPE /* Always leave this as the last one */
};
/* Supported digest types...
*/
enum {
FKO_DIGEST_MD5 = 0,
FKO_DIGEST_SHA1,
FKO_DIGEST_SHA256,
FKO_LAST_DIGEST_TYPE /* Always leave this as the last one */
};
/* Supported encryption types...
*/
enum {
FKO_ENCRYPTION_RIJNDAEL = 0,
FKO_ENCRYPTION_GPG,
FKO_LAST_ENCRYPTION_TYPE /* Always leave this as the last one */
};
/* General state flag bit values.
* (--DSS not sure If I will keep these yet)
*/
enum {
FKO_CTX_NEW = 1,
FKO_MESSAGE_DATA_SET = 1 << 1,
FKO_SPA_ENCODE_MESSAGE_SET = 1 << 2,
FKO_SPA_DIGEST_SET = 1 << 3,
FKO_SPA_NAT_ACCESS_SET = 1 << 4,
FKO_SPA_SERVER_AUTH_SET = 1 << 5,
FKO_SPA_CLIENT_TIMEOUT_SET = 1 << 6,
FKO_RESERVED = 1 << 7
};
#define FKO_CTX_INITIALIZED (FKO_CTX_NEW|FKO_RESERVED)
#define FKO_READY_FOR_DIGEST (FKO_CTX_INITIALIZED|FKO_SPA_ENCODE_MESSAGE_SET)
#define FKO_READY_FOR_ENCODE (FKO_READY_FOR_DIGEST|FKO_SPA_DIGEST_SET)
#define CTX_INITIALIZED(x) (x->initval == FKO_CTX_INITIALIZED)
/* FKO ERROR_CODES
*
* Note: If you change this list in any way, please be syre to make the
* appropriate corresponding change to the error message list in
* fko_error.c.
*/
enum {
FKO_SUCCESS = 0,
FKO_ERROR_CTX_NOT_INITIALIZED,
FKO_ERROR_MEMORY_ALLOCATION,
FKO_ERROR_INVALID_DATA,
FKO_ERROR_DATA_TOO_LARGE,
FKO_ERROR_USERNAME_UNKNOWN,
FKO_ERROR_INCOMPLETE_SPA_DATA,
FKO_ERROR_MISSING_ENCODED_DATA,
FKO_ERROR_INVALID_DIGEST_TYPE,
/* Add more errors here */
FKO_ERROR_UNKNOWN
};
/* General Defaults
*/
#define FKO_DEFAULT_MSG_TYPE FKO_ACCESS_MSG
#define FKO_DEFAULT_DIGEST FKO_DIGEST_SHA256
#define FKO_DEFAULT_ENCRYPTION FKO_ENCRYPTION_RIJNDAEL
/* How much space we allow for the fko context error message buffer.
*/
#define MAX_FKO_ERR_MSG_SIZE 128
/* Define some limits (--DSS XXX: These sizes need to be reviewed)
*/
#define MAX_SPA_USERNAME_SIZE 64
#define MAX_SPA_MESSAGE_SIZE 256
#define MAX_SPA_NAT_ACCESS_SIZE 128
#define MAX_SPA_SERVER_AUTH_SIZE 64
#define MIN_SPA_ENCODED_MSG_SIZE 36 /* Somewhat arbitrary */
/* Misc.
*/
#define FKO_RAND_VAL_SIZE 16
#define FKO_ENCODE_TMP_BUF_SIZE 1024
#define FKO_ENCRPT_TMP_BUF_SIZE 1024
/* The pieces we need to make a FKO packet.
*/
typedef struct _fko_ctx {
/* FKO SPA message data (raw and un-encoded) */
char rand_val[FKO_RAND_VAL_SIZE+1];
char *username;
unsigned int timestamp;
char *version;
short message_type;
char *message;
char *nat_access;
char *server_auth;
unsigned int client_timeout;
char *digest;
/* FKO SPA message encoding types */
short digest_type;
short encryption_type;
/* Complete processed data (encodings, etc.) */
char *encoded_msg;
char *encrypted_msg;
//unsigned int encrypted_msg_size;
/* State info */
unsigned char state;
unsigned char initval;
//char last_err_msg[MAX_FKO_ERR_MSG_SIZE];
} fko_ctx_t;
/* Function prototypes
*/
int fko_new(fko_ctx_t *ctx);
void fko_destroy(fko_ctx_t *ctx);
char* fko_version(fko_ctx_t *ctx);
const char* fko_errstr(int err_code);
int fko_set_rand_value(fko_ctx_t *ctx, const char *val);
int fko_set_username(fko_ctx_t *ctx, const char *spoof_user);
int fko_set_timestamp(fko_ctx_t *ctx, int offset);
int fko_set_spa_message_type(fko_ctx_t *ctx, short msg_type);
int fko_set_spa_message(fko_ctx_t *ctx, const char *msg_string);
int fko_set_spa_nat_access(fko_ctx_t *ctx, const char *nat_access);
int fko_set_spa_server_auth(fko_ctx_t *ctx, const char *server_auth);
int fko_set_spa_client_timeout(fko_ctx_t *ctx, int timeout);
int fko_set_spa_digest_type(fko_ctx_t *ctx, short digest_type);
int fko_set_spa_digest(fko_ctx_t *ctx);
int fko_set_spa_encryption_type(fko_ctx_t *ctx, short encryp_type);
char* fko_get_rand_value(fko_ctx_t *ctx);
char* fko_get_username(fko_ctx_t *ctx);
unsigned int fko_get_timestamp(fko_ctx_t *ctx);
short fko_get_spa_message_type(fko_ctx_t *ctx);
char* fko_get_spa_message(fko_ctx_t *ctx);
char* fko_get_spa_nat_access(fko_ctx_t *ctx);
char* fko_get_spa_server_auth(fko_ctx_t *ctx);
int fko_get_spa_client_timeout(fko_ctx_t *ctx);
short fko_get_spa_digest_type(fko_ctx_t *ctx);
char* fko_get_spa_digest(fko_ctx_t *ctx);
short fko_get_spa_encryption_type(fko_ctx_t *ctx);
int fko_encode_spa_data(fko_ctx_t *ctx);
int fko_decode_spa_data(fko_ctx_t *ctx);
int fko_encrypt_spa_data(fko_ctx_t *ctx, const char *enc_key);
int fko_decrypt_spa_data(fko_ctx_t *ctx, unsigned char *data, int size);
#endif /* FKO_H */
/***EOF***/

View File

@@ -1,13 +1,11 @@
/* $Id$
*****************************************************************************
*
* File: spa_digest.c
* File: fko_spa_client_timeout.c
*
* Author: Damien S. Stuart
*
* Purpose: Create the base64-encoded digest for the current spa data. The
* digest used is determined by the digest_type setting in the
* spa_message struct.
* Purpose: Set/Get the spa client timeout data
*
* Copyright (C) 2008 Damien Stuart (dstuart@dstuart.org)
*
@@ -25,32 +23,38 @@
*
*****************************************************************************
*/
#include "fwknop.h"
#include "fko_common.h"
#include "fko.h"
int spa_digest(spa_message_t *sm)
/* Set the SPA Client Timeout data
*/
int fko_set_spa_client_timeout(fko_ctx_t *ctx, int timeout)
{
if(sm->message[0] == '\0')
return -1;
/* Context must be initialized.
*/
if(!CTX_INITIALIZED(ctx))
return FKO_ERROR_CTX_NOT_INITIALIZED;
switch(sm->digest_type)
{
case MD5_DIGEST:
md5_base64(sm->digest, (uchar*)sm->message, strlen(sm->message));
break;
/* Gotta have a valid string.
*/
if(timeout < 0)
return(FKO_ERROR_INVALID_DATA);
case SHA1_DIGEST:
sha1_base64(sm->digest, (uchar*)sm->message, strlen(sm->message));
break;
ctx->client_timeout = timeout;
case SHA256_DIGEST:
sha256_base64(sm->digest, (uchar*)sm->message, strlen(sm->message));
break;
default:
return(-2);
}
return(0);
return(FKO_SUCCESS);
}
/* Return the SPA message data.
*/
int fko_get_spa_client_timeout(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
return(ctx->client_timeout);
}
/***EOF***/

View File

@@ -1,11 +1,11 @@
/* $Id$
*****************************************************************************
*
* File: spa_message_type.c
* File: fko_common.h
*
* Author: Damien S. Stuart
*
* Purpose: Set the current fwknop message type.
* Purpose: Common header for libfko source files.
*
* Copyright (C) 2008 Damien Stuart (dstuart@dstuart.org)
*
@@ -23,19 +23,39 @@
*
*****************************************************************************
*/
#include "fwknop.h"
#ifndef FKO_COMMON_H
#define FKO_COMMON_H 1
int spa_message_type(spa_message_t *sm, unsigned short msg_type)
{
if(msg_type >= LAST_MSG_TYPE)
{
fprintf(stderr, "*Invlaid fwknop message type: %u.\n", msg_type);
return(-1);
}
//#if HAVE_CONFIG_H
#include "config.h"
//#endif
sm->message_type = msg_type;
#include <stdio.h>
#include <sys/types.h>
return(0);
}
#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
#ifdef __cplusplus
#define BEGIN_C_DECLS extern "C" {
#define END_C_DECLS }
#else /* !__cplusplus */
#define BEGIN_C_DECLS
#define END_C_DECLS
#endif /* __cplusplus */
#include "fko_types.h"
//#include "fko.h"
#include "fko_util.h"
#endif /* FKO_COMMON_H */
/***EOF***/

126
lib/fko_digest.c Normal file
View File

@@ -0,0 +1,126 @@
/* $Id$
*****************************************************************************
*
* File: fko_digest.c
*
* Author: Damien S. Stuart
*
* Purpose: Create the base64-encoded digest for the current spa data. The
* digest used is determined by the digest_type setting in the
* fko context.
*
* Copyright (C) 2008 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 "fko.h"
#include "fko_common.h"
#include "digest.h"
/* Set the SPA digest type.
*/
int fko_set_spa_digest_type(fko_ctx_t *ctx, short digest_type)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
if(digest_type < 0 || digest_type >= FKO_LAST_DIGEST_TYPE)
return(FKO_ERROR_INVALID_DATA);
ctx->digest_type = digest_type;
return(FKO_SUCCESS);
}
/* Return the SPA digest type.
*/
short fko_get_spa_digest_type(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
return(ctx->digest_type);
}
int fko_set_spa_digest(fko_ctx_t *ctx)
{
char *md = NULL;
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
/* Must have encoded message data to start with.
*/
if(ctx->encoded_msg == NULL)
return(FKO_ERROR_MISSING_ENCODED_DATA);
switch(ctx->digest_type)
{
case FKO_DIGEST_MD5:
if((md = malloc(MD_HEX_SIZE(MD5_DIGESTSIZE)+1)) == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
md5_base64(md,
(uchar*)ctx->encoded_msg, strlen(ctx->encoded_msg));
break;
case FKO_DIGEST_SHA1:
if((md = malloc(MD_HEX_SIZE(SHA1_DIGESTSIZE)+1)) == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
sha1_base64(md,
(uchar*)ctx->encoded_msg, strlen(ctx->encoded_msg));
break;
case FKO_DIGEST_SHA256:
if((md = malloc(MD_HEX_SIZE(SHA256_DIGESTSIZE)+1)) == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
sha256_base64(md,
(uchar*)ctx->encoded_msg, strlen(ctx->encoded_msg));
break;
default:
return(FKO_ERROR_INVALID_DIGEST_TYPE);
}
/* Just in case this is a subsquent call to this function. We
* do not want to be leaking memory.
*/
if(ctx->digest != NULL)
free(ctx->digest);
ctx->digest = md;
return(FKO_SUCCESS);
}
char* fko_get_spa_digest(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(NULL);
return(ctx->digest);
}
/***EOF***/

159
lib/fko_encode.c Normal file
View File

@@ -0,0 +1,159 @@
/* $Id$
*****************************************************************************
*
* File: fko_encode.c
*
* Author: Damien S. Stuart
*
* Purpose: Encodes some pieces of the spa data then puts together all of
* the necessary pieces to gether to create the single encoded
* message string.
*
* Copyright (C) 2008 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 "fko_common.h"
#include "fko.h"
#include "base64.h"
#include "digest.h"
/* A rough way to make enough space for a base64 encoded version of
* the given string, encode it, and return it.
*/
int append_b64(char* tbuf, char *str)
{
int len = strlen(str);
char *bs;
if((bs = malloc(((len/3)*4)+8)) == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
b64_encode((unsigned char*)str, bs, len);
/* --DSS XXX: make sure to check here if later decoding
* becomes a problem.
*/
strip_b64_eq(bs);
strlcat(tbuf, bs, FKO_ENCODE_TMP_BUF_SIZE);
free(bs);
return(FKO_SUCCESS);
}
/* Set the SPA encryption type.
*/
int fko_encode_spa_data(fko_ctx_t *ctx)
{
int res, offset = 0;
char tbuf[FKO_ENCODE_TMP_BUF_SIZE] = {0};
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
/* Check prerequisites.
* --DSS XXX: Needs review. Also, we could make this more robust (or
* (at leaset expand the error reporting for the missing
* data).
*/
if( ctx->username == NULL || strlen(ctx->username) == 0
|| ctx->version == NULL || strlen(ctx->version) == 0
|| ctx->message == NULL || strlen(ctx->message) == 0)
{
return(FKO_ERROR_INCOMPLETE_SPA_DATA);
}
if(ctx->message_type == FKO_NAT_ACCESS_MSG)
{
if(ctx->nat_access == NULL || strlen(ctx->nat_access) == 0)
return(FKO_ERROR_INCOMPLETE_SPA_DATA);
}
/* Put it together a piece at a time, starting with the rand val.
*/
strcpy(tbuf, ctx->rand_val);
/* Add the base64-encoded username.
*/
strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE);
if((res = append_b64(tbuf, ctx->username)) != FKO_SUCCESS)
return(res);
/* Add the timestamp.
*/
offset = strlen(tbuf);
sprintf(((char*)tbuf+offset), ":%u:", ctx->timestamp);
/* Add the version string.
*/
strlcat(tbuf, ctx->version, FKO_ENCODE_TMP_BUF_SIZE);
/* Add the message type value.
*/
offset = strlen(tbuf);
sprintf(((char*)tbuf+offset), ":%i:", ctx->message_type);
/* Add the base64-encoded SPA message.
*/
if((res = append_b64(tbuf, ctx->message)) != FKO_SUCCESS)
return(res);
/** --DSS TODO: Need to address nat_access, server_auth
*** XXX: and client_timeout message types here
**/
/* If encoded_msg is not null, then we assume it needs to
* be freed before re-assignment.
*/
if(ctx->encoded_msg != NULL)
free(ctx->encoded_msg);
/* Copy our encoded data into the context.
*/
ctx->encoded_msg = strdup(tbuf);
if(ctx->encoded_msg == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
ctx->state |= FKO_SPA_ENCODE_MESSAGE_SET;
/* At this point we can compute the digest for this SPA data.
*/
if((res = fko_set_spa_digest(ctx)) != FKO_SUCCESS)
return(res);
return(FKO_SUCCESS);
}
/* Return the SPA encryption type.
*/
int fko_decode_spa_data(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
return(FKO_SUCCESS);
}
/***EOF***/

117
lib/fko_encryption.c Normal file
View File

@@ -0,0 +1,117 @@
/* $Id$
*****************************************************************************
*
* File: fko_encryption.c
*
* Author: Damien S. Stuart
*
* Purpose: Set/Get the spa encryption type.
*
* Copyright (C) 2008 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 "fko_common.h"
#include "fko.h"
#include "cipher_funcs.h"
#include "base64.h"
/* Set the SPA encryption type.
*/
int fko_set_spa_encryption_type(fko_ctx_t *ctx, short encrypt_type)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
if(encrypt_type < 0 || encrypt_type >= FKO_LAST_ENCRYPTION_TYPE)
return(FKO_ERROR_INVALID_DATA);
ctx->encryption_type = encrypt_type;
return(FKO_SUCCESS);
}
/* Return the SPA encryption type.
*/
short fko_get_spa_encryption_type(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
return(ctx->encryption_type);
}
/* Encrypt the encoded SPA data.
*/
int fko_encrypt_spa_data(fko_ctx_t *ctx, const char *enc_key)
{
char *plain;
char *b64cipher;
unsigned char *cipher;
int cipher_len;
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
if(ctx->encoded_msg == NULL
|| strlen(ctx->encoded_msg) < MIN_SPA_ENCODED_MSG_SIZE)
return(FKO_ERROR_MISSING_ENCODED_DATA);
/* Make a bucket big enough to hold the enc msg + digest (plaintext)
* and populate it appropriately.
*/
plain = malloc(strlen(ctx->encoded_msg) + strlen(ctx->digest) + 2);
if(plain == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
sprintf(plain, "%s:%s", ctx->encoded_msg, ctx->digest);
/* Make a bucket for the encrypted version and populate it.
*/
cipher = malloc(strlen(plain) + 32); /* Plus padding for salt and Block */
if(cipher == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
cipher_len = fko_encrypt(
(unsigned char*)plain, strlen(plain), (char*)enc_key, cipher
);
/* Now make a bucket for the base64-encoded version and populate it.
*/
b64cipher = malloc(((cipher_len / 3) * 4) + 4);
if(b64cipher == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
b64_encode(cipher, b64cipher, cipher_len);
strip_b64_eq(b64cipher);
ctx->encrypted_msg = strdup(b64cipher);
/* Clean-up
*/
free(plain);
free(cipher);
free(b64cipher);
return(FKO_SUCCESS);
}
/***EOF***/

56
lib/fko_error.c Normal file
View File

@@ -0,0 +1,56 @@
/* $Id$
*****************************************************************************
*
* File: fko_error.c
*
* Author: Damien S. Stuart
*
* Purpose: Error handling functions for libfko
*
* Copyright (C) 2008 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 "fko_common.h"
#include "fko.h"
/* Note: These messages must matchup with the ERROR_CODES enum
* defined in fko.h.
*/
static const char *fko_err_msgs[] = {
"Success",
"FKO Context is not initialized",
"Unable to allocate memory",
"Args contains invalid data",
"Value or Size of the data exceeded the max allowed",
"Unable to determine username",
"Missing or incomplete SPA data",
"There is no encoded data to process",
"Invalid digest type",
"Invalid encryption type",
"Unknown/Unclassified error",
0
};
const char* fko_errstr(int err_code)
{
if(err_code < 0 || err_code > FKO_ERROR_UNKNOWN)
return NULL;
return(fko_err_msgs[err_code]);
}
/***EOF***/

161
lib/fko_funcs.c Normal file
View File

@@ -0,0 +1,161 @@
/* $Id$
*****************************************************************************
*
* File: fko_funcs.c
*
* Author: Damien S. Stuart
*
* Purpose: General utility functions for libfko
*
* Copyright (C) 2008 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 "fko_common.h"
#include "fko.h"
/* Initialize an fko context.
*/
int fko_new(fko_ctx_t *ctx)
{
int res;
char *ver;
/* Zero out the context...
*/
bzero(ctx, sizeof(fko_ctx_t));
/* Set default values and state.
*
* Note: We have to explicitly set the ctx->state to initialized
* just before making an fko_xxx function call, then set it
* back to zero just afer. During initialization, we need
* to make these functions think they are operating on an
* initialized context, or else they would fail.
*/
/* Set the version string.
*/
ctx->initval = FKO_CTX_INITIALIZED;
ver = strdup(FKO_PROTOCOL_VERSION);
ctx->initval = 0;
if(!ver)
return(FKO_ERROR_MEMORY_ALLOCATION);
ctx->version = ver;
/* Rand value.
*/
ctx->initval = FKO_CTX_INITIALIZED;
res = fko_set_rand_value(ctx, NULL);
ctx->initval = 0;
if(res != FKO_SUCCESS)
return res;
/* Username.
*/
ctx->initval = FKO_CTX_INITIALIZED;
res = fko_set_username(ctx, NULL);
ctx->initval = 0;
if(res != FKO_SUCCESS)
return res;
/* Timestamp.
*/
ctx->initval = FKO_CTX_INITIALIZED;
res = fko_set_timestamp(ctx, 0);
ctx->initval = 0;
if(res != FKO_SUCCESS)
return res;
/* Default Digest Type.
*/
ctx->initval = FKO_CTX_INITIALIZED;
res = fko_set_spa_digest_type(ctx, FKO_DEFAULT_DIGEST);
ctx->initval = 0;
if(res != FKO_SUCCESS)
return res;
/* Default Message Type.
*/
ctx->initval = FKO_CTX_INITIALIZED;
res = fko_set_spa_message_type(ctx, FKO_DEFAULT_MSG_TYPE);
ctx->initval = 0;
if(res != FKO_SUCCESS)
return res;
/* Default Encryption Type.
*/
ctx->initval = FKO_CTX_INITIALIZED;
res = fko_set_spa_encryption_type(ctx, FKO_DEFAULT_ENCRYPTION);
ctx->initval = 0;
if(res != FKO_SUCCESS)
return res;
/* Now we mean it.
*/
ctx->initval = FKO_CTX_INITIALIZED;
ctx->state = FKO_CTX_NEW;
return(FKO_SUCCESS);
}
/* Destroy a context and free its resources
*/
void fko_destroy(fko_ctx_t *ctx)
{
if(CTX_INITIALIZED(ctx))
{
if(ctx->username != NULL)
free(ctx->username);
if(ctx->version != NULL)
free(ctx->version);
if(ctx->message != NULL)
free(ctx->message);
if(ctx->nat_access != NULL)
free(ctx->nat_access);
if(ctx->server_auth != NULL)
free(ctx->server_auth);
if(ctx->digest != NULL)
free(ctx->digest);
if(ctx->encoded_msg != NULL)
free(ctx->encoded_msg);
if(ctx->encrypted_msg != NULL)
free(ctx->encrypted_msg);
bzero(ctx, sizeof(fko_ctx_t));
}
}
/* Return the fko version
*/
char* fko_version(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return NULL;
return(ctx->version);
}
/***EOF***/

112
lib/fko_message.c Normal file
View File

@@ -0,0 +1,112 @@
/* $Id$
*****************************************************************************
*
* File: fko_mesage.c
*
* Author: Damien S. Stuart
*
* Purpose: Set/Get the spa message (access req/command/etc) based
* on the current spa data.
*
* Copyright (C) 2008 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 "fko_common.h"
#include "fko.h"
/* Set the SPA message type.
*/
int fko_set_spa_message_type(fko_ctx_t *ctx, short msg_type)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return FKO_ERROR_CTX_NOT_INITIALIZED;
if(msg_type < 0 || msg_type >= FKO_LAST_MSG_TYPE)
return(FKO_ERROR_INVALID_DATA);
ctx->message_type = msg_type;
return(FKO_SUCCESS);
}
/* Return the SPA message type.
*/
short fko_get_spa_message_type(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return FKO_ERROR_CTX_NOT_INITIALIZED;
return(ctx->message_type);
}
/* Set the SPA MESSAGE data
*/
int fko_set_spa_message(fko_ctx_t *ctx, const char *msg)
{
/* Context must be initialized.
*/
if(!CTX_INITIALIZED(ctx))
return FKO_ERROR_CTX_NOT_INITIALIZED;
/* Gotta have a valid string.
*/
if(msg == NULL || strlen(msg) == 0)
return(FKO_ERROR_INVALID_DATA);
/* --DSS XXX: Bail out for now. But consider just
* truncating in the future...
*/
if(strlen(msg) > MAX_SPA_MESSAGE_SIZE)
return(FKO_ERROR_DATA_TOO_LARGE);
/* --DSS TODO: ???
* Do we want to add message type and format checking here
* or continue to leave it to the implementor?
*/
/**/
/* Just in case this is a subsquent call to this function. We
* do not want to be leaking memory.
*/
if(ctx->message != NULL)
free(ctx->message);
ctx->message = strdup(msg);
if(ctx->message == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
return(FKO_SUCCESS);
}
/* Return the SPA message data.
*/
char* fko_get_spa_message(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return NULL;
return(ctx->message);
}
/***EOF***/

75
lib/fko_nat_access.c Normal file
View File

@@ -0,0 +1,75 @@
/* $Id$
*****************************************************************************
*
* File: fko_nat_access.c
*
* Author: Damien S. Stuart
*
* Purpose: Set/Get the spa nat access request data.
*
* Copyright (C) 2008 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 "fko_common.h"
#include "fko.h"
/* Set the SPA Nat Access data
*/
int fko_set_spa_nat_access(fko_ctx_t *ctx, const char *msg)
{
/* Context must be initialized.
*/
if(!CTX_INITIALIZED(ctx))
return FKO_ERROR_CTX_NOT_INITIALIZED;
/* Gotta have a valid string.
*/
if(msg == NULL || strlen(msg) == 0)
return(FKO_ERROR_INVALID_DATA);
/* --DSS XXX: Bail out for now. But consider just
* truncating in the future...
*/
if(strlen(msg) > MAX_SPA_NAT_ACCESS_SIZE)
return(FKO_ERROR_DATA_TOO_LARGE);
/* Just in case this is a subsquent call to this function. We
* do not want to be leaking memory.
*/
if(ctx->nat_access != NULL)
free(ctx->nat_access);
ctx->nat_access = strdup(msg);
if(ctx->nat_access == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
return(FKO_SUCCESS);
}
/* Return the SPA message data.
*/
char* fko_get_spa_nat_access(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return NULL;
return(ctx->nat_access);
}
/***EOF***/

View File

@@ -1,11 +1,11 @@
/* $Id$
*****************************************************************************
*
* File: spa_random_number.c
* File: fko_rand_value.c
*
* Author: Damien S. Stuart
*
* Purpose: Generate a 16-byte random hex value.
* Purpose: Generate a 16-byte random numeric value.
*
* Copyright (C) 2008 Damien Stuart (dstuart@dstuart.org)
*
@@ -23,15 +23,43 @@
*
*****************************************************************************
*/
#include "fwknop.h"
#include "fko_common.h"
#include "fko.h"
char* spa_random_number(spa_message_t *sm)
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#ifdef TIME_WITH_SYS_TIME
#include <time.h>
#endif
#endif
#define RAND_FILE "/dev/urandom"
/* Set/Generate the SPA data random value string.
*/
int fko_set_rand_value(fko_ctx_t *ctx, const char *new_val)
{
FILE *rfd;
struct timeval tv;
unsigned int seed;
unsigned long rnd;
char tmp_buf[RAND_VAL_SIZE+1] = {0};
char tmp_buf[FKO_RAND_VAL_SIZE+1] = {0};
/* Context must be initialized.
*/
if(!CTX_INITIALIZED(ctx))
return FKO_ERROR_CTX_NOT_INITIALIZED;
/* If a valid value was given, use it and return happy.
*/
if(new_val != NULL)
{
if(strlen(new_val) != 16)
return(FKO_ERROR_INVALID_DATA);
strcpy(ctx->rand_val, new_val);
return(FKO_SUCCESS);
}
/* Attempt to read seed data from /dev/urandom. If that does not
* work, then fall back to a time-based method (less secure, but
@@ -43,9 +71,6 @@ char* spa_random_number(spa_message_t *sm)
*/
fread(&seed, 4, 1, rfd);
fclose(rfd);
#ifdef DEBUG
fprintf(stderr, "Using /dev/urandom for seed: %u\n", seed);
#endif
}
else
{
@@ -54,22 +79,32 @@ char* spa_random_number(spa_message_t *sm)
gettimeofday(&tv, NULL);
seed = tv.tv_usec;
#ifdef DEBUG
fprintf(stderr, "Using time and pids for seed: %u\n", seed);
#endif
}
srand(seed);
sprintf(sm->rand_val, "%u", rand());
sprintf(ctx->rand_val, "%u", rand());
while(strlen(sm->rand_val) < RAND_VAL_SIZE)
while(strlen(ctx->rand_val) < FKO_RAND_VAL_SIZE)
{
sprintf(tmp_buf, "%u", rand());
strlcat(sm->rand_val, tmp_buf, RAND_VAL_SIZE+1);
strlcat(ctx->rand_val, tmp_buf, FKO_RAND_VAL_SIZE+1);
}
return(sm->rand_val);
return(FKO_SUCCESS);
}
/* Return the current rand value.
*/
char* fko_get_rand_value(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return NULL;
return(ctx->rand_val);
}
/***EOF***/

82
lib/fko_server_auth.c Normal file
View File

@@ -0,0 +1,82 @@
/* $Id$
*****************************************************************************
*
* File: fko_server_auth.c
*
* Author: Damien S. Stuart
*
* Purpose: Set/Get the spa server auth data.
*
* Copyright (C) 2008 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 "fko_common.h"
#include "fko.h"
/* Set the SPA Server Auth data
*/
int fko_set_spa_server_auth(fko_ctx_t *ctx, const char *msg)
{
/* Context must be initialized.
*/
if(!CTX_INITIALIZED(ctx))
return FKO_ERROR_CTX_NOT_INITIALIZED;
/* Gotta have a valid string.
*/
if(msg == NULL || strlen(msg) == 0)
return(FKO_ERROR_INVALID_DATA);
/* --DSS XXX: Bail out for now. But consider just
* truncating in the future...
*/
if(strlen(msg) > MAX_SPA_SERVER_AUTH_SIZE)
return(FKO_ERROR_DATA_TOO_LARGE);
/* --DSS TODO: ???
* Do we want to add message type and format checking here
* or continue to leave it to the implementor?
*/
/**/
/* Just in case this is a subsquent call to this function. We
* do not want to be leaking memory.
*/
if(ctx->server_auth != NULL)
free(ctx->server_auth);
ctx->server_auth = strdup(msg);
if(ctx->server_auth == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
return(FKO_SUCCESS);
}
/* Return the SPA message data.
*/
char* fko_get_spa_server_auth(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return NULL;
return(ctx->server_auth);
}
/***EOF***/

69
lib/fko_timestamp.c Normal file
View File

@@ -0,0 +1,69 @@
/* $Id$
*****************************************************************************
*
* File: fko_timestamp.c
*
* Author: Damien S. Stuart
*
* Purpose: Get the current timestamp with optional offset applied.
*
* Copyright (C) 2008 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 "fko_common.h"
#include "fko.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#ifdef TIME_WITH_SYS_TIME
#include <time.h>
#endif
#endif
/* Set the timestamp.
*/
int fko_set_timestamp(fko_ctx_t *ctx, int offset)
{
unsigned int ts;
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return FKO_ERROR_CTX_NOT_INITIALIZED;
ts = time(NULL) + offset;
if(ts < 0)
return(FKO_ERROR_INVALID_DATA);
ctx->timestamp = ts;
return(FKO_SUCCESS);
}
/* Return the current timestamp.
*/
unsigned int fko_get_timestamp(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return 0;
return(ctx->timestamp);
}
/***EOF***/

View File

@@ -1,7 +1,7 @@
/* $Id$
*****************************************************************************
*
* File: types.h
* File: fko_types.h
*
* Purpose: Typedefs for fwknop.
*
@@ -21,8 +21,8 @@
*
*****************************************************************************
*/
#ifndef _TYPES_H_
#define _TYPES_H_
#ifndef FKO_TYPES_H
#define FKO_TYPES_H 1
#include <sys/types.h>
@@ -39,6 +39,6 @@ typedef int64_t int64;
typedef unsigned char uchar;
typedef unsigned short ushort;
#endif /* _TYPES_H_ */
#endif /* FKO_TYPES_H */
/***EOF***/

103
lib/fko_user.c Normal file
View File

@@ -0,0 +1,103 @@
/* $Id$
*****************************************************************************
*
* File: fko_user.c
*
* Author: Damien S. Stuart
*
* Purpose: Set/Get the current username.
*
* Copyright (C) 2008 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 "fko_common.h"
#include "fko.h"
/* Get or Set the username for the fko context spa data.
*/
int fko_set_username(fko_ctx_t *ctx, const char *spoof_user)
{
char *username = NULL;
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return FKO_ERROR_CTX_NOT_INITIALIZED;
/* If spoof_user was not passed in, check for a SPOOF_USER enviroment
* variable. If it is set, use its value.
*/
if(spoof_user != NULL && strlen(spoof_user))
username = (char*)spoof_user;
else
username = getenv("SPOOF_USER");
/* Try to get the username from the system.
*/
if(username == NULL)
{
#ifdef _XOPEN_SOURCE
/* cuserid will return the effective user (i.e. su or setuid).
*/
username = cuserid(NULL);
#else
username = getlogin();
#endif
/* If we did not get a name using the above methods, try the
* LOGNAME or USER environment variables. If none of those work,
* then we bail with an error.
*/
if(username == NULL)
if((username = getenv("LOGNAME")) == NULL)
if((username = getenv("USER")) == NULL)
return(FKO_ERROR_USERNAME_UNKNOWN);
}
/* --DSS XXX: Bail out for now. But consider just
* truncating in the future...
*/
if(strlen(username) > MAX_SPA_USERNAME_SIZE)
return(FKO_ERROR_DATA_TOO_LARGE);
/* Just in case this is a subsquent call to this function. We
* do not want to be leaking memory.
*/
if(ctx->username != NULL)
free(ctx->username);
ctx->username = strdup(username);
if(ctx->username == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
return(FKO_SUCCESS);
}
/* Return the current username for this fko context.
*/
char* fko_get_username(fko_ctx_t *ctx)
{
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return NULL;
return(ctx->username);
}
/***EOF***/

View File

@@ -1,11 +1,11 @@
/* $Id$
*****************************************************************************
*
* File: spa_version.c
* File: fko_util.c
*
* Author: Damien S. Stuart
*
* Purpose: Get the current fwknop version.
* Purpose: General utility functions for libfko (some borrowed
*
* Copyright (C) 2008 Damien Stuart (dstuart@dstuart.org)
*
@@ -23,12 +23,7 @@
*
*****************************************************************************
*/
#include "fwknop.h"
#include "fko_util.h"
char* spa_version(spa_message_t *sm)
{
strlcpy(sm->version, FWKNOP_VERSION, strlen(FWKNOP_VERSION) + 1);
return(sm->version);
}
/***EOF***/

View File

@@ -1,11 +1,11 @@
/* $Id$
*****************************************************************************
*
* File: spa_timestamp.c
* File: fko_util.h
*
* Author: Damien S. Stuart
*
* Purpose: Get the current timestamp with optional offset applied.
* Purpose: Header for utility functions used by libfko
*
* Copyright (C) 2008 Damien Stuart (dstuart@dstuart.org)
*
@@ -23,13 +23,19 @@
*
*****************************************************************************
*/
#include "fwknop.h"
#include <time.h>
#ifndef FKO_UTIL_H
#define FKO_UTIL_H 1
#include "fko_common.h"
/* Function prototypes
*/
size_t strlcat(char *dst, const char *src, size_t siz);
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif /* FKO_UTIL_H */
/***EOF***/
unsigned int spa_timestamp(spa_message_t *sm, int offset)
{
sm->timestamp = time(NULL) + offset;
return(sm->timestamp);
}
/***EOF***/

View File

@@ -1,140 +0,0 @@
/* $Id$
*****************************************************************************
*
* File: fwknop.h
*
* Author: Damien S. Stuart
*
* Purpose: Header for the fwknop source files
*
* Copyright (C) 2008 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 _FWKNOP_H_
#define _FWKNOP_H_
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include "types.h"
#include "digest.h"
#include "cipher_funcs.h"
#include "base64.h"
/* General params
*/
#define FWKNOP_VERSION "1.9.9" /* The fwknop client version # */
#define VERSION_LENGTH 11 /* Length of the version string */
#define MIN_PORT 10000
#define MAX_PORT 65535
#define ENC_KEYSIZE 16 /* RIJNDAEL Key Size */
/* For random string generation.
*/
#define RAND_VAL_SIZE 16
#define RAND_FILE "/dev/urandom"
#define RAND_MASK 0xFFFF
#define TIMESTAMP_SIZE 10
/* --DSS TODO: Do we need to adjust these? */
#define MAX_USER_SIZE 32
#define MAX_MESSAGE_SIZE 256
#define MAX_NAT_ACCESS_SIZE 128
#define MAX_SERVER_AUTH_SIZE 128
#define MAX_DIGEST_SIZE 64
#define MAX_ACCESS_STR_SIZE 64
#define MAX_IP_ADDR_SIZE 16
/* SPA Message types...
*/
enum {
SPA_COMMAND_MSG = 0,
SPA_ACCESS_MSG,
SPA_NAT_ACCESS_MSG,
SPA_CLIENT_TIMEOUT_ACCESS_MSG,
SPA_CLIENT_TIMEOUT_NAT_ACCESS_MSG,
SPA_LOCAL_NAT_ACCESS_MSG,
SPA_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG,
LAST_MSG_TYPE /* Always leave this as the last one */
};
/* Digest types...
*/
enum {
MD5_DIGEST = 0,
SHA1_DIGEST,
SHA256_DIGEST
};
/* General Defaults
*/
#define DEFAULT_USER "root"
#define DEFAULT_PORT 62201
#define DEFAULT_DIGEST SHA256_DIGEST
#define DEFAULT_MSG_TYPE SPA_ACCESS_MSG
#define DEFAULT_CLIENT_TIMEOUT 0
#define DEFAULT_ACCESS_STR "none,0"
#define DEFAULT_ALLOW_IP "0.0.0.0"
/* The pieces we need to make a SPA packet.
*/
typedef struct _spa_message {
unsigned short digest_type;
unsigned short enc_pcap_port;
char rand_val[RAND_VAL_SIZE+1];
char user[MAX_USER_SIZE];
unsigned int timestamp;
char version[VERSION_LENGTH+1];
unsigned short message_type;
char message[MAX_MESSAGE_SIZE];
char nat_access[MAX_NAT_ACCESS_SIZE];
char server_auth[MAX_SERVER_AUTH_SIZE];
unsigned int client_timeout;
char digest[MAX_DIGEST_SIZE+1];
char access_str[MAX_ACCESS_STR_SIZE];
char allow_ip[MAX_IP_ADDR_SIZE];
} spa_message_t;
/* Function prototypes
*/
char* spa_random_number(spa_message_t *sm);
char* spa_user(spa_message_t *sm, char *spoof_user);
unsigned int spa_timestamp(spa_message_t *sm, int offset);
char* spa_version(spa_message_t *sm);
int spa_message_type(spa_message_t *sm, ushort msg_type);
char* spa_message(spa_message_t *sm);
char* spa_nat_access(spa_message_t *sm);
char* spa_server_auth(spa_message_t *sm);
unsigned int spa_client_timeout(spa_message_t *sm);
//int spa_digest(char *digest, uchar *msg, int size, ushort digest_type);
int spa_digest(spa_message_t *sm);
size_t strlcat(char *dst, const char *src, size_t siz);
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif /* _FWKNOP_H_ */
/***EOF***/

View File

@@ -1,117 +0,0 @@
/* gpgme-example1:
*
* Nico Schottelius, 2007-08-05, GPLv3
*
* export all public keys
*/
#include <gpgme.h> /* gpgme */
#include <stdio.h> /* printf */
#include <unistd.h> /* write */
#include <errno.h> /* errno */
#include <locale.h> /* locale support */
#define SIZE 1024
/* USE -D_FILE_OFFSET_BITS=64 (at least) on Debian! */
int main()
{
char *p;
char buf[SIZE];
size_t read_bytes;
int tmp;
gpgme_ctx_t ceofcontext;
gpgme_error_t err;
gpgme_data_t data;
gpgme_engine_info_t enginfo;
/* The function `gpgme_check_version' must be called before any other
* function in the library, because it initializes the thread support
* subsystem in GPGME. (from the info page) */
setlocale (LC_ALL, "");
p = (char *) gpgme_check_version(NULL);
printf("version=%s\n",p);
/* set locale, because tests do also */
gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
/* check for OpenPGP support */
err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
if(err != GPG_ERR_NO_ERROR) return 1;
p = (char *) gpgme_get_protocol_name(GPGME_PROTOCOL_OpenPGP);
printf("Protocol name: %s\n",p);
/* get engine information */
err = gpgme_get_engine_info(&enginfo);
if(err != GPG_ERR_NO_ERROR) return 2;
printf("file=%s, home=%s\n",enginfo->file_name,enginfo->home_dir);
/* create our own context */
err = gpgme_new(&ceofcontext);
if(err != GPG_ERR_NO_ERROR) return 3;
/* set protocol to use in our context */
err = gpgme_set_protocol(ceofcontext,GPGME_PROTOCOL_OpenPGP);
if(err != GPG_ERR_NO_ERROR) return 4;
/* set engine info in our context; I changed it for ceof like this:
err = gpgme_ctx_set_engine_info (ceofcontext, GPGME_PROTOCOL_OpenPGP,
"/usr/bin/gpg","/home/user/nico/.ceof/gpg/");
but I'll use standard values for this example: */
err = gpgme_ctx_set_engine_info (ceofcontext, GPGME_PROTOCOL_OpenPGP,
enginfo->file_name,enginfo->home_dir);
if(err != GPG_ERR_NO_ERROR) return 5;
/* do ascii armor data, so output is readable in console */
gpgme_set_armor(ceofcontext, 1);
/* create buffer for data exchange with gpgme*/
err = gpgme_data_new(&data);
if(err != GPG_ERR_NO_ERROR) return 6;
/* set encoding for the buffer... */
err = gpgme_data_set_encoding(data,GPGME_DATA_ENCODING_ARMOR);
if(err != GPG_ERR_NO_ERROR) return 7;
/* verify encoding: not really needed */
tmp = gpgme_data_get_encoding(data);
if(tmp == GPGME_DATA_ENCODING_ARMOR) {
printf("encode ok\n");
} else {
printf("encode broken\n");
}
/* with NULL it exports all public keys */
err = gpgme_op_export(ceofcontext,NULL,0,data);
if(err != GPG_ERR_NO_ERROR) return 8;
read_bytes = gpgme_data_seek (data, 0, SEEK_END);
printf("end is=%d\n",read_bytes);
if(read_bytes == -1) {
p = (char *) gpgme_strerror(errno);
printf("data-seek-err: %s\n",p);
return 9;
}
read_bytes = gpgme_data_seek (data, 0, SEEK_SET);
printf("start is=%d (should be 0)\n",read_bytes);
/* write keys to stderr */
while ((read_bytes = gpgme_data_read (data, buf, SIZE)) > 0) {
write(2,buf,read_bytes);
}
/* append \n, so that there is really a line feed */
write(2,"\n",1);
/* free data */
gpgme_data_release(data);
/* free context */
gpgme_release(ceofcontext);
return 0;
}

View File

@@ -1,183 +0,0 @@
/* GPGME test program
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gpgme.h>
void hex_dump(unsigned char *data, int size)
{
int ln, i, j = 0;
char ascii_str[17] = {0};
for(i=0; i<size; i++)
{
if((i % 16) == 0)
{
printf(" %s\n 0x%.4x: ", ascii_str, i);
memset(ascii_str, 0x0, 17);
j = 0;
}
printf("%.2x ", data[i]);
ascii_str[j++] = (data[i] < 0x20 || data[i] > 0x7e) ? '.' : data[i];
if(j == 8)
printf(" ");
}
/* Remainder...
*/
ln = strlen(ascii_str);
if(ln > 0)
{
for(i=0; i < 16-ln; i++)
printf(" ");
printf(" %s\n\n", ascii_str);
}
}
err_out(const char *msg, gpgme_error_t err)
{
fprintf(stderr, "*Error from %s (%s): %s.\n",
msg, gpgme_strsource(err), gpgme_strerror(err));
exit(-1);
}
int main(int argc, char **argv)
{
gpgme_ctx_t ctx;
gpgme_error_t err;
gpgme_key_t key[2] = {0};
gpgme_key_t mykey = NULL;
gpgme_data_t data;
gpgme_data_t plaintext;
gpgme_engine_info_t enginfo;
const char *indata = "This is a DSS test. 1234567890.";
/* Because the manual says you should. */
char *tp = (char*) gpgme_check_version(NULL);
printf("GPGME Version: %s\n", tp);
/* Check for OpenPGP support */
err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
err_out("gpgme_engine_check_version", err);
tp = (char*) gpgme_get_protocol_name(GPGME_PROTOCOL_OpenPGP);
printf("Protocol: %s\n", tp);
/* Retrieve engine information */
err = gpgme_get_engine_info(&enginfo);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
err_out("gpgme_get_engine_info", err);
printf("File: %s, Home: %s\n", enginfo->file_name, enginfo->home_dir);
/* Create our context */
err = gpgme_new(&ctx);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
err_out("gpgme_new", err);
/* Initialize the plaintext data (place into gpgme_data object) */
err = gpgme_data_new_from_mem(&plaintext, indata, strlen(indata), 1);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
err_out("gpgme_data_new_from_mem", err);
fprintf(stderr, "+Created GPGME context+\n");
/* Set protocol */
err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP);
/* Set engine for this context. */
err = gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_OpenPGP,
enginfo->file_name, enginfo->home_dir);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
err_out("gpgme_set_engin_info", err);
/* Set ascii-armor */
gpgme_set_armor(ctx, 0);
/* Key to use for encrypting and signing */
err = gpgme_op_keylist_start(ctx, "dstuart", 0);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
err_out("gpgme_op_keylist_start", err);
//while(!err)
//{
err = gpgme_op_keylist_next(ctx, &mykey);
// if(err)
// break;
//
//gpgme_key_release(mykey);
gpgme_op_keylist_end(ctx);
//hex_dump(&mykey, 1024);
printf("Got Key:\n%s: %s <%s>\n", mykey->subkeys->keyid, mykey->uids->name, mykey->uids->email);
//}
//err = gpgme_get_key(ctx, mykey->uids->uid, &key[0], 0);
//if(gpg_err_code("gpgme_get_key", err) != GPG_ERR_NO_ERROR)
// err_out(err);
key[0] = mykey;
//if(gpg_err_code(err) != GPG_ERR_EOF)
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
err_out("gpgme_op_keylist_next", err);
err = gpgme_data_new(&data);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
err_out("gpgme_data_new(#2)", err);
//err = gpgme_data_set_encoding(data, GPGME_DATA_ENCODING_BASE64);
//if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
// err_out("gpgme_data_set_encoding", err);
err = gpgme_op_encrypt(ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, plaintext, data);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
err_out("gpgme_op_encrypt", err);
size_t ilen, olen;
//char* in = gpgme_data_release_and_get_mem(plaintext, &ilen);
char* out = gpgme_data_release_and_get_mem(data, &olen);
char tmp_buf[4096] = {0};
//printf("ILEN: %i\n", ilen);
//hex_dump((unsigned char*)in, ilen);
printf("OLEN: %i\n", olen);
//strncpy(tmp_buf, out, olen);
hex_dump((unsigned char*)out, olen);
//printf("\n%s\n\n", tmp_buf);
//char buf[1024];
//size_t nread = 0;
//while((nread = gpgme_data_read(data, buf, sizeof(buf))))
//{
// printf("NREAD: %i\n", nread);
// hex_dump((unsigned char*)buf, nread);
// }
gpgme_release(ctx);
return(0);
}
/***EOF***/

View File

@@ -27,13 +27,10 @@
*
*****************************************************************************
*/
#ifndef _MD5_H_
#define _MD5_H_
#ifndef MD5_H
#define MD5_H 1
#include <stdio.h>
#include <string.h>
#include "types.h"
#include "fko_common.h"
#define MD5_DIGESTSIZE 16
@@ -69,6 +66,6 @@ void MD5Update(MD5Context *ctx, unsigned char *buf, unsigned len);
void MD5Final(unsigned char digest[16], MD5Context *ctx);
void MD5Transform(uint32 buf[4], uint32 in[16]);
#endif /* _MD5_H_ */
#endif /* MD5_H */
/***EOF***/

View File

@@ -24,11 +24,10 @@
* http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ for details.
*/
#if !defined(RIJNDAEL_H)
#define RIJNDAEL_H
#ifndef RIJNDAEL_H
#define RIJNDAEL_H 1
#include <stdlib.h>
#include "types.h"
#include "fko_common.h"
#ifdef _CRYPT_RIJNDAEL_H_TYPES
#undef _CRYPT_RIJNDAEL_H_TYPES

View File

@@ -25,14 +25,11 @@
*
*****************************************************************************
*/
#ifndef _SHA256_H_
#define _SHA256_H_
#ifndef SHA256_H
#define SHA256_H 1
#include <stdio.h>
#include <string.h> /* for memcpy */
#include <endian.h>
#include "types.h"
#include "fko_common.h"
/* This should be fine for most systems (hopefully).
*/
@@ -62,4 +59,4 @@ void sha256_update(SHA_INFO *sha_info, uint8 *buffer, int count);
void sha256_final(SHA_INFO *sha_info);
void sha256_unpackdigest(uint8 digest[SHA256_DIGESTSIZE], SHA_INFO *sha_info);
#endif /* _SHA256_H_ */
#endif /* SHA256_H */

View File

@@ -1,72 +0,0 @@
/* $Id$
*****************************************************************************
*
* File: spa_mesage.c
*
* Author: Damien S. Stuart
*
* Purpose: Construct the raw spa message based on the current spa data.
*
* Copyright (C) 2008 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.h"
char* spa_message(spa_message_t *sm)
{
char user_b64[64] = {0};
char msg_text[128] = {0};
char msg_b64[256] = {0};
b64_encode((uchar*)sm->user, user_b64, strlen(sm->user));
switch(sm->message_type)
{
case SPA_ACCESS_MSG:
sprintf(msg_text, "%s,%s",
sm->allow_ip,
sm->access_str
);
break;
case SPA_COMMAND_MSG:
case SPA_NAT_ACCESS_MSG:
case SPA_CLIENT_TIMEOUT_ACCESS_MSG:
case SPA_CLIENT_TIMEOUT_NAT_ACCESS_MSG:
case SPA_LOCAL_NAT_ACCESS_MSG:
case SPA_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG:
default:
sprintf(msg_text, "## Mode %u not supported ##", sm->message_type);
}
b64_encode((uchar*)msg_text, msg_b64, strlen(msg_text));
sprintf(sm->message, "%s:%s:%u:%s:%u:%s",
sm->rand_val,
user_b64,
sm->timestamp,
sm->version,
sm->message_type,
msg_b64
);
// NOT DONE YET
return(sm->message);
}
/***EOF***/

View File

@@ -1,65 +0,0 @@
/* $Id$
*****************************************************************************
*
* File: spa_user.c
*
* Author: Damien S. Stuart
*
* Purpose: Get the current user
*
* Copyright (C) 2008 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.h"
char* spa_user(spa_message_t *sm, char *spoof_user)
{
size_t res;
/* If spoof_user was not passed in, check for a SPOOF_USER enviroment
* variable. If it is set, use its value.
*/
if(spoof_user == NULL)
spoof_user = getenv("SPOOF_USER");
if(spoof_user != NULL)
{
strlcpy(sm->user, spoof_user, MAX_USER_SIZE+1);
}
else
{
#ifdef _XOPEN_SOURCE
/* cuserid will return the effective user (i.e. su or setuid).
*/
res = strlcpy(sm->user, cuserid(NULL), MAX_USER_SIZE);
#else
res = strlcpy(sm->user, getlogin(), MAX_USER_SIZE);
#endif
/* If we did not get a name using the above methods, try the
* LOGNAME or USER environment variables. If none of those work,
* then we fall back to the DEFAULT_USER.
*/
if(res < 1)
if((strlcpy(sm->user, getenv("LOGNAME"), MAX_USER_SIZE)) < 1)
if((strlcpy(sm->user, getenv("USER"), MAX_USER_SIZE)) < 1)
strlcpy(sm->user, DEFAULT_USER, strlen(DEFAULT_USER) + 1);
}
return(sm->user);
}
/***EOF***/

View File

@@ -27,12 +27,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strlcat.c,v 1.9 2003/03/14 14:35:29 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
#include "fko_common.h"
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
@@ -41,8 +36,7 @@ static char *rcsid = "$OpenBSD: strlcat.c,v 1.9 2003/03/14 14:35:29 millert Exp
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
size_t strlcat(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
@@ -68,3 +62,5 @@ strlcat(char *dst, const char *src, size_t siz)
return(dlen + (s - src)); /* count does not include NUL */
}
/***EOF***/

View File

@@ -27,20 +27,14 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strlcpy.c,v 1.6 2003/03/14 14:35:29 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
#include "fko_common.h"
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
size_t strlcpy(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
@@ -64,3 +58,5 @@ strlcpy(char *dst, const char *src, size_t siz)
return(s - src - 1); /* count does not include NUL */
}
/***EOF***/

View File

@@ -1,4 +0,0 @@
bin_PROGRAMS = fko_test
fko_test_SOURCES = fko_test.c
fko_test_LDADD = $(top_builddir)/lib/libfko.a
fko_test_CPPFLAGS = -I $(top_srcdir)/lib

View File

@@ -1,235 +0,0 @@
/* $Id$
*****************************************************************************
*
* File: fko_test.c
*
* Author: Damien S. Stuart
*
* Purpose: Temp test program for libfwknop
*
* Copyright (C) 2008 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.h"
int main(int argc, char **argv)
{
spa_message_t sm;
//char test_str[1024] = {0};
/* Zero our SPA message struct.
*/
memset(&sm, 0x0, sizeof(spa_message_t));
#if 0
/*********************************************************************
* Get a random 16-byte string of hex values.
*/
spa_random_number(&sm);
printf(" SPA_RAND_VAL: %s\n", sm.rand_val);
/*********************************************************************
* Get the current user, then a spoofed user.
*/
spa_user(&sm, NULL);
printf(" SPA_USER: %s\n", sm.user);
spa_user(&sm, "bubba");
printf(" SPA_USER (spoof): %s\n", sm.user);
/*********************************************************************
* Get the timestamp, then with an positive and negative offset.
*/
spa_timestamp(&sm, 0);
printf(" SPA_TIMESTAMP: %u\n", sm.timestamp);
spa_timestamp(&sm, 300);
printf("SPA_TIMESTAMP (+300): %u\n", sm.timestamp);
spa_timestamp(&sm, -600);
printf("SPA_TIMESTAMP (-600): %u\n", sm.timestamp);
/*********************************************************************
* Get the version of fwknop.
*/
printf(" SPA_Version: %s\n", spa_version(&sm));
/*********************************************************************
* Set and get the message type. set ACCESS, COMMAND, NAT, Then
* invalid
*/
spa_message_type(&sm, SPA_ACCESS_MSG);
printf(" SPA Message Type: %u\n", sm.message_type);
spa_message_type(&sm, SPA_COMMAND_MSG);
printf("SPA CMD Message Type: %u\n", sm.message_type);
spa_message_type(&sm, SPA_LOCAL_NAT_ACCESS_MSG);
printf("SPA NAT Message Type: %u\n", sm.message_type);
spa_message_type(&sm, 100);
printf("SPA bad Message Type: %u\n\n", sm.message_type);
/*********************************************************************
* Various Base 64 tests.
*/
char btest_raw[90] = {0};
char btest_enc[120] = {0};
uchar btest_dec[120] = {0};
/*
*/
// 1 char
strcpy(btest_raw, "1");
b64_encode((uchar*)btest_raw, btest_enc, strlen(btest_raw));
printf("----\n B64 RAW: %s\n", btest_raw);
printf(" B64 ENC: %s\n", btest_enc);
b64_decode(btest_enc, btest_dec, strlen(btest_enc));
printf(" B64 DEC: %s\n", btest_dec);
// 2 chars
strcpy(btest_raw, "22");
b64_encode((uchar*)btest_raw, btest_enc, strlen(btest_raw));
printf("----\n B64 RAW: %s\n", btest_raw);
printf(" B64 ENC: %s\n", btest_enc);
b64_decode(btest_enc, btest_dec, strlen(btest_enc));
printf(" B64 DEC: %s\n", btest_dec);
// 3 chars
strcpy(btest_raw, "333");
b64_encode((uchar*)btest_raw, btest_enc, strlen(btest_raw));
printf("----\n B64 RAW: %s\n", btest_raw);
printf(" B64 ENC: %s\n", btest_enc);
b64_decode(btest_enc, btest_dec, strlen(btest_enc));
printf(" B64 DEC: %s\n", btest_dec);
// 4 chars
strcpy(btest_raw, "4444");
b64_encode((uchar*)btest_raw, btest_enc, strlen(btest_raw));
printf("----\n B64 RAW: %s\n", btest_raw);
printf(" B64 ENC: %s\n", btest_enc);
b64_decode(btest_enc, btest_dec, strlen(btest_enc));
printf(" B64 DEC: %s\n", btest_dec);
// Longer string
strcpy(btest_raw, "The quick brown fox jumps over the lazy doq (1234567890).");
b64_encode((uchar*)btest_raw, btest_enc, strlen(btest_raw));
printf("----\n B64 RAW: %s\n", btest_raw);
printf(" B64 ENC: %s\n", btest_enc);
b64_decode(btest_enc, btest_dec, strlen(btest_enc));
printf(" B64 DEC: %s\n", btest_dec);
// Binary data (yeah, I know.. pretty lame...
memset(btest_raw, 0x07, 4);
b64_encode((uchar*)btest_raw, btest_enc, 4);
printf("----\n B64 RAW: %02x %02x %02x %02x\n", btest_raw[0],btest_raw[1],btest_raw[2],btest_raw[3]);
printf(" B64 ENC: %s\n", btest_enc);
b64_decode(btest_enc, btest_dec, strlen(btest_enc));
printf(" B64 DEC: %02x %02x %02x %02x\n", btest_dec[0],btest_dec[1],btest_dec[2],btest_dec[3]);
printf("\n");
/*********************************************************************
* DIGEST tests.
********************************************************************/
char tst_string[] = "This is a test.";
/*********************************************************************
* MD5 test.
*/
char md5_digest[33] = {0};
char tst_md5_digest[] = "120ea8a25e5d487bf68b5f7096440019";
md5_hex(md5_digest, (uchar*)tst_string, strlen(tst_string));
printf(
"\nMD5 of '%s':\n"
" Should be: %s\n"
" Computed as: %s\n",
tst_string, tst_md5_digest, md5_digest
);
/*********************************************************************
* SHA1 test.
*/
char sha1_digest[41] = {0};
char tst_sha1_digest[] = "afa6c8b3a2fae95785dc7d9685a57835d703ac88";
sha1_hex(sha1_digest, (uchar*)tst_string, strlen(tst_string));
printf(
"\nSHA1 of '%s':\n"
" Should be: %s\n"
" Computed as: %s\n",
tst_string, tst_sha1_digest, sha1_digest
);
/*********************************************************************
* SHA256 test.
*/
char sha256_digest[65] = {0};
char tst_sha256_digest[] = "a8a2f6ebe286697c527eb35a58b5539532e9b3ae3b64d4eb0a46fb657b41562c";
sha256_hex(sha256_digest, (uchar*)tst_string, strlen(tst_string));
printf(
"\nSHA256 of '%s':\n"
" Should be: %s\n"
" Computed as: %s\n",
tst_string, tst_sha256_digest, sha256_digest
);
#endif
/*********************************************************************
* Rijndael test.
*/
char *pass = "BubbaWasHere";
char b64buf[1024] = {0};
uchar encbuf[1024] = {0};
uchar decbuf[1024] = {0};
char tst_string[] = "This is a test.";
int len = strlen(tst_string);
int enc_len, dec_len;
/* Use our handy macro to predict the size of the encrypted data.
*/
//int pred_len = PREDICT_ENCSIZE(len);
enc_len = fko_encrypt((uchar*)tst_string, len, pass, encbuf);
b64_encode(encbuf, b64buf, enc_len);
dec_len = fko_decrypt(encbuf, enc_len, pass, decbuf);
printf(
"\n Orig string is: '%s'\n"
" Base64 of enc is: %s\n"
" Decrypted as: '%s'\n",
tst_string, b64buf, decbuf
);
//char tst_dec[] = "U2FsdGVkX19GsvEbSbjzMs6uKLFBN8YsHiyqGn2hu26o7kDyT+74fq/rqd+c5SLZGEgZ3OrFX5ogEof2UOt3HcZG7IAO7YBLHDwfTb069O9rsN8uLYa/ABdDsRDd6X5Z1dwIlOBhqrpEQDHvThWWlqgXUOsg10zxXf0miy/4HmEDWJCEszq4WrZ2Jx2ymNCf";
char tst_dec[] = "U2FsdGVkX188TWDKS1fJShJQF6ZzQJlUjbi5Byv45JVyjklRltN3DhRODCwc5/iY/lIFExA30Zwv0dkA4WG685X7UavFmf7grEoaeyZJhVyz1ycSp3IBCsL1h2QU7pocCIMHppuwkXnqpfqBNkCFiB26yq4xscxgFwGm8GQXAgvuYxepWPK67FWsyxdTW1OT";
int blen = b64_decode(tst_dec, encbuf, strlen(tst_dec));
printf("BLEN: %i\n", blen);
hex_dump(encbuf, blen);
fko_decrypt(encbuf, blen, "BubbaWasHere", (uchar*)b64buf);
printf("DSS TEST:\n%s\n", b64buf);
return(0);
}
/***EOF***/

View File

@@ -1,4 +1,6 @@
bin_PROGRAMS = fwknop
fwknop_SOURCES = fwknop.c
fwknop_LDADD = $(top_builddir)/lib/libfko.a
fwknop_CPPFLAGS = -I $(top_srcdir)/lib

165
src/fwknop.c Normal file
View File

@@ -0,0 +1,165 @@
/* $Id$
*****************************************************************************
*
* File: fko_test.c
*
* Author: Damien S. Stuart
*
* Purpose: Temp test program for libfwknop
*
* Copyright (C) 2008 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 <stdio.h>
#include <string.h>
#include "fko.h"
void display_ctx(fko_ctx_t *ctx);
void hex_dump(unsigned char *data, int size);
int main(int argc, char **argv)
{
fko_ctx_t ctx;
int res;
/* Intialize the context */
res = fko_new(&ctx);
if(res != FKO_SUCCESS)
fprintf(stderr, "Error #%i from fko_new: %s\n", res, fko_errstr(res));
/* Set a message string */
res = fko_set_spa_message(&ctx, "0.0.0.0,access.0");
if(res != FKO_SUCCESS)
fprintf(stderr, "Error #%i from fko_set_spa_message: %s\n", res, fko_errstr(res));
/* Set a nat_access string
res = fko_set_spa_nat_access(&ctx, "192.168.1.5,10616");
if(res != FKO_SUCCESS)
fprintf(stderr, "Error #%i from fko_set_nat_access: %s\n", res, fko_errstr(res));
*/
/* Set a server_auth string
res = fko_set_spa_server_auth(&ctx, "crypt,letmein");
if(res != FKO_SUCCESS)
fprintf(stderr, "Error #%i from fko_set_spa_server_auth: %s\n", res, fko_errstr(res));
*/
/* Set a client_timeout string
res = fko_set_spa_client_timeout(&ctx, 66);
if(res != FKO_SUCCESS)
fprintf(stderr, "Error #%i from fko_set_spa_client_timeout: %s\n", res, fko_errstr(res));
*/
//fko_set_spa_digest_type(&ctx, FKO_DIGEST_SHA1);
/* Encode the SPA data */
res = fko_encode_spa_data(&ctx);
if(res != FKO_SUCCESS)
fprintf(stderr, "Error #%i from fko_encode_spa_data: %s\n", res, fko_errstr(res));
/* Encrypt the SPA data */
res = fko_encrypt_spa_data(&ctx, "BubbaWasHere");
if(res != FKO_SUCCESS)
fprintf(stderr, "Error #%i from fko_encrypt_spa_data: %s\n", res, fko_errstr(res));
display_ctx(&ctx);
//printf("\nHex dump of fko_ctx:\n====================\n");
//hex_dump((unsigned char*)&ctx, sizeof(fko_ctx_t));
fko_destroy(&ctx);
return(0);
}
void display_ctx(fko_ctx_t *ctx)
{
printf("\nFKO Context Values:\n===================\n\n");
if((ctx->state & FKO_CTX_INITIALIZED) == 0)
{
printf("*Context not initialized*\n");
return;
}
printf(
" Random Value: %s\n"
" Username: %s\n"
" Timestamp: %u\n"
" FKO Version: %s\n"
" Message Type: %i\n"
" Message String: %s\n"
" Nat Access: %s\n"
" Server Auth: %s\n"
" Client Timeout: %u\n"
" Digest Type: %u\n"
"SPA Data Digest: %s\n"
"\n Encoded Data:\n%s\n"
"\n Encrypted Data:\n%s\n"
,
fko_get_rand_value(ctx),
(fko_get_username(ctx) == NULL) ? "<NULL>" : fko_get_username(ctx),
fko_get_timestamp(ctx),
fko_version(ctx),
fko_get_spa_message_type(ctx),
(fko_get_spa_message(ctx) == NULL) ? "<NULL>" : fko_get_spa_message(ctx),
(fko_get_spa_nat_access(ctx) == NULL) ? "<NULL>" : fko_get_spa_nat_access(ctx),
(fko_get_spa_server_auth(ctx) == NULL) ? "<NULL>" : fko_get_spa_server_auth(ctx),
fko_get_spa_client_timeout(ctx),
fko_get_spa_digest_type(ctx),
(fko_get_spa_digest(ctx) == NULL) ? "<NULL>" : fko_get_spa_digest(ctx),
(ctx->encoded_msg == NULL) ? "<NULL>" : ctx->encoded_msg,
(ctx->encrypted_msg == NULL) ? "<NULL>" : ctx->encrypted_msg
);
}
void hex_dump(unsigned char *data, int size)
{
int ln, i, j = 0;
char ascii_str[17] = {0};
for(i=0; i<size; i++)
{
if((i % 16) == 0)
{
printf(" %s\n 0x%.4x: ", ascii_str, i);
memset(ascii_str, 0x0, 17);
j = 0;
}
printf("%.2x ", data[i]);
ascii_str[j++] = (data[i] < 0x20 || data[i] > 0x7e) ? '.' : data[i];
if(j == 8)
printf(" ");
}
/* Remainder...
*/
ln = strlen(ascii_str);
if(ln > 0)
{
for(i=0; i < 16-ln; i++)
printf(" ");
printf(" %s\n\n", ascii_str);
}
}
/***EOF***/