Fixed libfko so gpgme engine is gpg by default. Added functions to libfko to set/get path to gpgme engine. Fixed some memory leaks. Reworkd the get_user_pw routine. Added code in fwknopd to put back the "hQ" string on the front of incoming GPG-encypted message data. Removed the previously add pretty-print routine to configure. Updated configure to check for path to gpg executable. Updated docs accordingly.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@205 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart
2010-02-06 03:43:54 +00:00
parent 02e5d45bf0
commit d0373a5b33
15 changed files with 375 additions and 726 deletions
+14
View File
@@ -1,3 +1,17 @@
2010-02-05 Damien Stuart <dstuart@dstuart.org>
* Updated libfko to set gpgme to use of gpg (vice gpg2) by default.
* Added fko_set_gpg_exe and fko_get_gpg_exe function for getting or
setting the path to gpg. Updated docs accordingly.
* Fixed some potential memory leak issues in libfko and fwknopd.
* Reworked the get_user_pw routines to accomodate use of gpg-agent and not
prompting for a password when GPG is used without signing.
* Fixed bug where the 'hQ' prefix was removed by the client, but not put
back by the server.
* Added check for (and ability to override) the path to gpg to the
configure script.
* Reverted/removed the pretty-print routines from the configure script as
the changes caused more issues than they were worth.
2010-01-30 Damien Stuart <dstuart@dstuart.org>
* Set working version to 2.0.0-alpha-pre2.
* Added additional sanity checks and clean-up of access.conf processing
+1 -1
View File
@@ -6,7 +6,7 @@
#
set -x
aclocal -I config -I m4
aclocal -I config
libtoolize --automake --copy --force
autoheader
automake --add-missing --copy
+30 -14
View File
@@ -211,7 +211,7 @@ main(int argc, char **argv)
errmsg("fko_set_gpg_recipient", res);
if(IS_GPG_ERROR(res))
fprintf(stderr, "GPG ERR: %s\n", fko_gpg_errorstr(ctx));
fprintf(stderr, "GPG ERR: %s\n", fko_gpg_errstr(ctx));
return(EXIT_FAILURE);
}
@@ -223,7 +223,7 @@ main(int argc, char **argv)
errmsg("fko_set_gpg_signer", res);
if(IS_GPG_ERROR(res))
fprintf(stderr, "GPG ERR: %s\n", fko_gpg_errorstr(ctx));
fprintf(stderr, "GPG ERR: %s\n", fko_gpg_errstr(ctx));
return(EXIT_FAILURE);
}
@@ -250,7 +250,7 @@ main(int argc, char **argv)
errmsg("fko_spa_data_final", res);
if(IS_GPG_ERROR(res))
fprintf(stderr, "GPG ERR: %s\n", fko_gpg_errorstr(ctx));
fprintf(stderr, "GPG ERR: %s\n", fko_gpg_errstr(ctx));
return(EXIT_FAILURE);
}
@@ -345,7 +345,7 @@ main(int argc, char **argv)
* programs like the fwknop test suite don't interpret this as
* an unrecoverable error), but print the error string for
debugging purposes. */
fprintf(stderr, "GPG ERR: %s\n%s\n", fko_gpg_errorstr(ctx2),
fprintf(stderr, "GPG ERR: %s\n%s\n", fko_gpg_errstr(ctx2),
"[*] No access to recipient private key?\n");
return(EXIT_SUCCESS);
}
@@ -699,17 +699,31 @@ set_message_type(fko_ctx_t ctx, fko_cli_options_t *options)
char*
get_user_pw(fko_cli_options_t *options, int crypt_op)
{
char *pw_ptr = NULL;
char *pw_ptr = NULL;
static char *no_pw = "";
if (options->get_key_file[0] != 0x0) {
/* grab the key/password from the --get-key file
*/
pw_ptr = getpasswd_file(options->get_key_file,
options->spa_server_str);
/* First of all if we are using GPG and GPG_AGENT
* then there is no password to return.
*/
if(options->use_gpg
&& (options->use_gpg_agent
|| (crypt_op == CRYPT_OP_ENCRYPT && options->gpg_signer_key == NULL)))
return(no_pw);
/* If --get-key file was specified grab the key/password from it.
*/
if (options->get_key_file[0] != 0x0)
{
pw_ptr = getpasswd_file(options->get_key_file, options->spa_server_str);
}
else if (options->use_gpg) {
pw_ptr = options->use_gpg_agent ? ""
: getpasswd("Enter passphrase for secret key: ");
else if (options->use_gpg)
{
if(crypt_op == CRYPT_OP_DECRYPT)
pw_ptr = getpasswd("Enter passphrase for secret key: ");
else if(options->gpg_signer_key && strlen(options->gpg_signer_key))
pw_ptr = getpasswd("Enter passphrase for signing: ");
else
pw_ptr = no_pw;
}
else
{
@@ -721,7 +735,9 @@ get_user_pw(fko_cli_options_t *options, int crypt_op)
pw_ptr = getpasswd("Enter password: ");
}
if (pw_ptr == NULL || pw_ptr[0] == '\0')
/* Empty password is allowed, NULL password is not.
*/
if (pw_ptr == NULL)
{
fprintf(stderr, "[*] Received no password data, exiting.\n");
exit(EXIT_FAILURE);
+35 -17
View File
@@ -26,8 +26,6 @@ dnl AM_MAINTAINER_MODE
AC_CONFIG_HEADER([config.h])
AC_CONFIG_MACRO_DIR([m4])
dnl The top of our header
dnl
AH_TOP([
@@ -61,8 +59,6 @@ AC_ARG_ENABLE([server],
[])
AM_CONDITIONAL([WANT_SERVER], [test "$want_server" = yes])
CONFIGURE_PART(Compilation Environment)
AC_GNU_SOURCE
AC_PROG_CC
@@ -79,8 +75,6 @@ AC_PROG_LIBTOOL
# Checks for header files.
#
CONFIGURE_PART(Header File Checks)
AC_HEADER_STDC
AC_HEADER_TIME
AC_HEADER_RESOLV
@@ -89,8 +83,6 @@ AC_CHECK_HEADERS([ctype.h endian.h errno.h locale.h netdb.h net/ethernet.h netin
# Type checks.
#
CONFIGURE_PART(Type Checks)
AC_C_CONST
AC_TYPE_INT8_T
AC_TYPE_INT16_T
@@ -112,8 +104,6 @@ AC_C_BIGENDIAN
# Checks for library functions.
#
CONFIGURE_PART(Library Function Checks)
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_FUNC_STAT
@@ -123,8 +113,8 @@ AC_CHECK_FUNCS([bzero gettimeofday memmove memset socket strchr strcspn strdup s
AC_SEARCH_LIBS([socket], [socket])
AC_SEARCH_LIBS([inet_addr], [nsl])
CONFIGURE_PART(3rd-party Libraries)
# Check for 3rd-party libs
#
AC_ARG_WITH([gpgme],
[AS_HELP_STRING([--with-gpgme],
[support for gpg encryption using libgpgme @<:@default=check@:>@])],
@@ -160,11 +150,38 @@ AS_IF([test "$want_server" = yes], [
)]
)
CONFIGURE_PART(Find local executables used by the server)
dnl Add various common way to sbin dir to the path (just in case)
APP_PATH=$PATH$PATH_SEPARATOR/sbin$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/usr/local/sbin
dnl Check for gpg (not gpg2)
dnl
AC_ARG_WITH([gpg],
[AS_HELP_STRING([--with-gpg=/path/to/gpg],
[Specify path to the gpg executable that gpgme will use @<:@default=check path@:>@])],
[
AS_IF([ test "x$withval" = x -o "x$withval" = xyes -o "x$withval" = xno ],
[AC_MSG_ERROR([--with-gpg requires an argument specifying a path to gpg])],
[
AC_CHECK_FILE([$withval], [], [
AC_MSG_WARN([Specified path to gpg does not exist on this system])
gpg_exe_warn="*not found*"
])
GPG_EXE=$withval
]
)
],
[
AC_PATH_PROG(GPG_EXE, [gpg], [], [$APP_PATH])
]
)
AS_IF([test "x$GPG_EXE" != x],
[
AC_DEFINE_UNQUOTED([GPG_EXE], ["$GPG_EXE"], [Path to gpg executable])
gpg_exe=$GPG_EXE
], [ gpg_exe="(not found)"]
)
dnl Check for iptables
dnl
AC_ARG_WITH([iptables],
@@ -306,8 +323,6 @@ dnl
)
])
CONFIGURE_PART(Generating Files)
AC_CONFIG_FILES([Makefile
lib/Makefile
client/Makefile
@@ -317,7 +332,10 @@ AC_CONFIG_FILES([Makefile
AC_OUTPUT
CONFIGURE_PART(Configure Summary)
if [test $have_gpgme = "yes" ]; then
have_gpgme="$have_gpgme
Gpgme engine: $GPG_EXE"
fi
echo "
$PACKAGE_NAME-$PACKAGE_VERSION configuration.
+16 -1
View File
@@ -894,6 +894,13 @@ signature verification errors are ignored (but still captured) and the
decoding process will continue. The default value of this flag is false.
@end deftypefun
@deftypefun int fko_set_gpg_exe (@w{fko_ctx_t @var{ctx}, const char @var{gpg_exe}});
Sets the path to the @acronym{GPG} executable that @emph{gpgme} will use. By default,
@emph{libfko} forces @emph{gpgme} to use @command{gpg} in case @emph{gpgme} was compiled
to use @command{gpg2} as its default engine. You can use this function to override and
set what @acronym{GPG} executable @emph{gpgme} will use.
@end deftypefun
@noindent
@strong{Note}: On a libfko build without @acronym{GPG} support, the
GPG-related functions above will simply return the FKO_ERROR_UNSUPPORTED_FEATURE
@@ -1037,7 +1044,7 @@ to. The return value is an FKO error status.
@deftypefun int fko_get_gpg_home_dir (@w{fko_ctx_t @var{ctx}, char @var{**gpg_dir}});
Assigns the pointer to the string holding the the @acronym{GPG} home directory
associated with the current context to the address @var{recipient} is pointing
associated with the current context to the address @var{gpg_dir} is pointing
to. The return value is an FKO error status.
@end deftypefun
@@ -1077,6 +1084,12 @@ error status value associated with the current context. The return value is an F
status.
@end deftypefun
@deftypefun int fko_get_gpg_exe (@w{fko_ctx_t @var{ctx}, char @var{**gpg_exe}});
Assigns the pointer to the string holding the the @acronym{GPG} executable path
associated with the current context to the address @var{gpg_exe} is pointing
to. The return value is an FKO error status.
@end deftypefun
@noindent
@strong{Note}: The char* values retrieved by the GPG-related functions above
will be NULL if the context value was not previously set.
@@ -1263,6 +1276,8 @@ The key for the given recipient was not found
Ambiguous name/id for the recipient key (mulitple matches)
@item FKO_ERROR_GPGME_DECRYPT_FAILED
Decryption operation failed
@item FKO_ERROR_GPGME_BAD_GPG_EXE
Unable to stat the given GPG executable
@item FKO_ERROR_GPGME_BAD_HOME_DIR
Unable to stat the given GPG home directory
@item FKO_ERROR_GPGME_SET_HOME_DIR
+6 -5
View File
@@ -28,6 +28,12 @@
#include "rijndael.h"
#include "gpgme_funcs.h"
/* Define the consistent prefixes or salt on some ecryption schemes.
* We identify them here so we can remove and reinsert when needed.
*/
#define B64_RIJNDAEL_SALT "U2FsdGVkX1"
#define B64_GPG_PREFIX "hQ"
/* Provide the predicted encrypted data size for given input data based
* on a 16-byte block size (for Rijndael implementation,this also accounts
* for the 16-byte salt as well).
@@ -37,11 +43,6 @@
size_t rij_encrypt(unsigned char *in, size_t len, char *key, unsigned char *out);
size_t rij_decrypt(unsigned char *in, size_t len, char *key, unsigned char *out);
#if HAVE_LIBGPGME
int gpg_encrypt(fko_ctx_t ctx, char *enc_key);
int gpg_decrypt(fko_ctx_t ctx, char *dec_key, size_t b64_len);
#endif /* HAVE_LIBGPGME */
#endif /* CIPHER_FUNCS_H */
/***EOF***/
+13 -3
View File
@@ -64,7 +64,9 @@ typedef enum {
/* Supported digest types...
*/
typedef enum {
FKO_DIGEST_MD5 = 1,
FKO_DIGEST_INVALID_DATA = -1,
FKO_DIGEST_UNKNOWN = 0,
FKO_DIGEST_MD5,
FKO_DIGEST_SHA1,
FKO_DIGEST_SHA256,
FKO_DIGEST_SHA384,
@@ -75,7 +77,9 @@ typedef enum {
/* Supported encryption types...
*/
typedef enum {
FKO_ENCRYPTION_RIJNDAEL = 1,
FKO_ENCRYPTION_INVALID_DATA = -1,
FKO_ENCRYPTION_UNKNOWN = 0,
FKO_ENCRYPTION_RIJNDAEL,
FKO_ENCRYPTION_GPG,
FKO_LAST_ENCRYPTION_TYPE /* Always leave this as the last one */
} fko_encryption_type_t;
@@ -130,6 +134,7 @@ typedef enum {
FKO_ERROR_GPGME_RECIPIENT_KEY_AMBIGUOUS,
FKO_ERROR_GPGME_DECRYPT_FAILED,
FKO_ERROR_GPGME_DECRYPT_UNSUPPORTED_ALGORITHM,
FKO_ERROR_GPGME_BAD_GPG_EXE,
FKO_ERROR_GPGME_BAD_HOME_DIR,
FKO_ERROR_GPGME_SET_HOME_DIR,
FKO_ERROR_GPGME_NO_SIGNATURE,
@@ -200,6 +205,7 @@ DLL_API int fko_set_spa_data(fko_ctx_t ctx, char *enc_msg);
/* Data processing and misc utility functions
*/
DLL_API const char* fko_errstr(int err_code);
DLL_API int fko_encryption_type(char *enc_data);
DLL_API int fko_encode_spa_data(fko_ctx_t ctx);
DLL_API int fko_decode_spa_data(fko_ctx_t ctx);
@@ -208,6 +214,7 @@ DLL_API int fko_decrypt_spa_data(fko_ctx_t ctx, char *dec_key);
DLL_API int fko_get_encoded_data(fko_ctx_t ctx, char **enc_data);
/* Get context data functions
*/
DLL_API int fko_get_rand_value(fko_ctx_t ctx, char **rand_val);
@@ -226,6 +233,9 @@ DLL_API int fko_get_spa_data(fko_ctx_t ctx, char **spa_data);
DLL_API int fko_get_version(fko_ctx_t ctx, char **version);
/* GPG-related functions */
DLL_API int fko_set_gpg_exe(fko_ctx_t ctx, const char *gpg_exe);
DLL_API int fko_get_gpg_exe(fko_ctx_t ctx, char **gpg_exe);
DLL_API int fko_set_gpg_recipient(fko_ctx_t ctx, const char *recip);
DLL_API int fko_get_gpg_recipient(fko_ctx_t ctx, char **recip);
DLL_API int fko_set_gpg_signer(fko_ctx_t ctx, const char *signer);
@@ -233,7 +243,7 @@ DLL_API int fko_get_gpg_signer(fko_ctx_t ctx, char **signer);
DLL_API int fko_set_gpg_home_dir(fko_ctx_t ctx, const char *gpg_home_dir);
DLL_API int fko_get_gpg_home_dir(fko_ctx_t ctx, char **gpg_home_dir);
DLL_API const char* fko_gpg_errorstr(fko_ctx_t ctx);
DLL_API const char* fko_gpg_errstr(fko_ctx_t ctx);
DLL_API int fko_set_gpg_signature_verify(fko_ctx_t ctx, unsigned char val);
DLL_API int fko_get_gpg_signature_verify(fko_ctx_t ctx, unsigned char *val);
+1
View File
@@ -73,6 +73,7 @@ struct fko_context {
#if HAVE_LIBGPGME
/* For gpgme support */
char *gpg_exe;
char *gpg_recipient;
char *gpg_signer;
char *gpg_home_dir;
+133 -31
View File
@@ -35,8 +35,6 @@
#endif
#endif
#define B64_RIJNDAEL_SALT "U2FsdGVkX1"
/* Prep and encrypt using Rijndael
*/
int
@@ -92,13 +90,15 @@ _rijndael_encrypt(fko_ctx_t ctx, char *enc_key)
/* Decode, decrypt, and parse SPA data into the context.
*/
int
_rijndael_decrypt(fko_ctx_t ctx, char *dec_key, int b64_len)
_rijndael_decrypt(fko_ctx_t ctx, char *dec_key)
{
char *tbuf;
unsigned char *ndx;
unsigned char *cipher;
int cipher_len, pt_len, i, err = 0;
int b64_len = strlen(ctx->encrypted_msg);
/* Now see if we need to add the "Salted__" string to the front of the
* encrypted data.
*/
@@ -238,12 +238,38 @@ gpg_encrypt(fko_ctx_t ctx, char *enc_key)
/* Prep and decrypt using gpgme
*/
int
gpg_decrypt(fko_ctx_t ctx, char *dec_key, size_t b64_len)
gpg_decrypt(fko_ctx_t ctx, char *dec_key)
{
char *tbuf;
unsigned char *cipher;
size_t cipher_len;
int res;
int b64_len = strlen(ctx->encrypted_msg);
/* Now see if we need to add the "hQ" string to the front of the
* base64-encoded-GPG-encrypted data.
*/
if(strncmp(ctx->encrypted_msg, B64_GPG_PREFIX, strlen(B64_GPG_PREFIX)))
{
/* We need to realloc space for the GPG prefix of hQ.
*/
tbuf = realloc(ctx->encrypted_msg, b64_len + 12);
if(tbuf == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
memmove(tbuf+strlen(B64_GPG_PREFIX), tbuf, b64_len);
ctx->encrypted_msg = memcpy(tbuf, B64_GPG_PREFIX, strlen(B64_GPG_PREFIX));
/* Adjust b64_len for added SALT value and Make sure we are still
* a properly NULL-terminated string (Ubuntu was one system for
* which this was an issue).
*/
b64_len += strlen(B64_GPG_PREFIX);
tbuf[b64_len] = '\0';
}
/* Create a bucket for the (base64) decoded encrypted data and get the
* raw cipher data.
*/
@@ -251,19 +277,21 @@ gpg_decrypt(fko_ctx_t ctx, char *dec_key, size_t b64_len)
if(cipher == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
cipher_len = b64_decode(ctx->encrypted_msg, cipher, b64_len);
cipher_len = b64_decode(ctx->encrypted_msg, cipher, strlen(ctx->encrypted_msg));
/* Create a bucket for the plaintext data and decrypt the message
* data into it.
*/
ctx->encoded_msg = malloc(cipher_len);
if(ctx->encoded_msg == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
/* --DSS Actually, the needed memory will be malloced in the gpgme_decrypt
// function. Just leaving this here for reference (for now).
//ctx->encoded_msg = malloc(cipher_len);
//if(ctx->encoded_msg == NULL)
// return(FKO_ERROR_MEMORY_ALLOCATION);
*/
res = gpgme_decrypt(ctx, cipher, cipher_len,
dec_key, (unsigned char**)&ctx->encoded_msg, &cipher_len
);
/* Done with cipher...
*/
@@ -371,16 +399,46 @@ fko_encrypt_spa_data(fko_ctx_t ctx, char *enc_key)
int
fko_decrypt_spa_data(fko_ctx_t ctx, char *dec_key)
{
int b64_len, res;
//char *ndx;
int enc_type, res;
/* First, make sure we have data to work with.
/* Get the (assumed) type of encryption used. This will also provide
* some data validation.
*/
if(ctx->encrypted_msg == NULL
|| strlen(ctx->encrypted_msg) < MIN_SPA_ENCODED_MSG_SIZE)
enc_type = fko_encryption_type(ctx->encrypted_msg);
//strlen(ctx->encrypted_msg) < MIN_SPA_ENCODED_MSG_SIZE)
if(enc_type == FKO_ENCRYPTION_GPG)
{
return(FKO_ERROR_INVALID_DATA);
ctx->encryption_type = FKO_ENCRYPTION_GPG;
#if HAVE_LIBGPGME
res = gpg_decrypt(ctx, dec_key);
#else
res = FKO_ERROR_UNSUPPORTED_FEATURE;
#endif
}
else if(enc_type == FKO_ENCRYPTION_RIJNDAEL)
{
ctx->encryption_type = FKO_ENCRYPTION_RIJNDAEL;
res = _rijndael_decrypt(ctx, dec_key);
}
else
return(FKO_ERROR_INVALID_DATA);
return(res);
}
/* Return the assumed encryption type based on the raw encrypted data.
*/
int
fko_encryption_type(char *enc_data)
{
int enc_data_len;
/* Sanity check the data.
*/
if(enc_data == NULL)
return(FKO_ENCRYPTION_INVALID_DATA);
/* Determine type of encryption used. For know, we are using the
* size of the message.
@@ -388,24 +446,17 @@ fko_decrypt_spa_data(fko_ctx_t ctx, char *dec_key)
* XXX: We will want to come up with a more reliable method of
* identifying the encryption type.
*/
b64_len = strlen(ctx->encrypted_msg);
enc_data_len = strlen(enc_data);
if(b64_len > MIN_GNUPG_MSG_SIZE)
{
ctx->encryption_type = FKO_ENCRYPTION_GPG;
#if HAVE_LIBGPGME
res = gpg_decrypt(ctx, dec_key, b64_len);
#else
res = FKO_ERROR_UNSUPPORTED_FEATURE;
#endif
}
else /* We are assuming the default of Rijndael */
{
ctx->encryption_type = FKO_ENCRYPTION_RIJNDAEL;
res = _rijndael_decrypt(ctx, dec_key, b64_len);
}
if(enc_data_len >= MIN_GNUPG_MSG_SIZE)
return(FKO_ENCRYPTION_GPG);
return(res);
else if(enc_data_len < MIN_GNUPG_MSG_SIZE
&& enc_data_len >= MIN_SPA_ENCODED_MSG_SIZE)
return(FKO_ENCRYPTION_RIJNDAEL);
else
return(FKO_ENCRYPTION_UNKNOWN);
}
/* Set the GPG recipient key name.
@@ -449,6 +500,57 @@ fko_set_gpg_recipient(fko_ctx_t ctx, const char *recip)
#endif /* HAVE_LIBGPGME */
}
/* Set the GPG home dir.
*/
int
fko_set_gpg_exe(fko_ctx_t ctx, const char *gpg_exe)
{
#if HAVE_LIBGPGME
struct stat st;
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
/* If we are unable to stat the given path/file and determine if it
* is a regular file or symbolic link, then return with error.
*/
if(stat(gpg_exe, &st) != 0)
return(FKO_ERROR_GPGME_BAD_GPG_EXE);
if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
return(FKO_ERROR_GPGME_BAD_GPG_EXE);
ctx->gpg_exe = strdup(gpg_exe);
if(ctx->gpg_exe == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
return(FKO_SUCCESS);
#else
return(FKO_ERROR_UNSUPPORTED_FEATURE);
#endif /* HAVE_LIBGPGME */
}
/* Get the GPG home dir.
*/
int
fko_get_gpg_exe(fko_ctx_t ctx, char **gpg_exe)
{
#if HAVE_LIBGPGME
/* Must be initialized
*/
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
*gpg_exe = ctx->gpg_exe;
return(FKO_SUCCESS);
#else
return(FKO_ERROR_UNSUPPORTED_FEATURE);
#endif /* HAVE_LIBGPGME */
}
/* Get the GPG recipient key name.
*/
int
+4 -1
View File
@@ -160,6 +160,9 @@ fko_errstr(int err_code)
case FKO_ERROR_GPGME_DECRYPT_UNSUPPORTED_ALGORITHM:
return("Decryption operation failed due to unsupported algorithm");
case FKO_ERROR_GPGME_BAD_GPG_EXE:
return("Unable to stat the given GPG executable");
case FKO_ERROR_GPGME_BAD_HOME_DIR:
return("Unable to stat the given GPG home directory");
@@ -187,7 +190,7 @@ fko_errstr(int err_code)
}
const char*
fko_gpg_errorstr(fko_ctx_t ctx)
fko_gpg_errstr(fko_ctx_t ctx)
{
#if HAVE_LIBGPGME
if(ctx->gpg_err)
+15 -13
View File
@@ -25,12 +25,7 @@
*/
#include "fko_common.h"
#include "fko.h"
/* The base64 encoded version of "Salted__" that may be found at the head
* of Rijndael encrypted data.
*/
#define B64_RIJNDAEL_SALT "U2FsdGVkX1"
#define B64_GPG_PREFIX "hQ"
#include "cipher_funcs.h"
/* Initialize an fko context.
*/
@@ -74,7 +69,7 @@ fko_new(fko_ctx_t *r_ctx)
ctx->initval = 0;
if(res != FKO_SUCCESS)
{
free(ctx);
fko_destroy(ctx);
return res;
}
@@ -85,7 +80,7 @@ fko_new(fko_ctx_t *r_ctx)
ctx->initval = 0;
if(res != FKO_SUCCESS)
{
free(ctx);
fko_destroy(ctx);
return res;
}
@@ -96,7 +91,7 @@ fko_new(fko_ctx_t *r_ctx)
ctx->initval = 0;
if(res != FKO_SUCCESS)
{
free(ctx);
fko_destroy(ctx);
return res;
}
@@ -107,7 +102,7 @@ fko_new(fko_ctx_t *r_ctx)
ctx->initval = 0;
if(res != FKO_SUCCESS)
{
free(ctx);
fko_destroy(ctx);
return res;
}
@@ -118,7 +113,7 @@ fko_new(fko_ctx_t *r_ctx)
ctx->initval = 0;
if(res != FKO_SUCCESS)
{
free(ctx);
fko_destroy(ctx);
return res;
}
@@ -129,7 +124,7 @@ fko_new(fko_ctx_t *r_ctx)
ctx->initval = 0;
if(res != FKO_SUCCESS)
{
free(ctx);
fko_destroy(ctx);
return res;
}
@@ -137,6 +132,7 @@ fko_new(fko_ctx_t *r_ctx)
/* Set gpg signature verify on.
*/
ctx->verify_gpg_sigs = 1;
#endif /* HAVE_LIBGPGME */
/* Now we mean it.
@@ -196,8 +192,8 @@ fko_new_with_data(fko_ctx_t *r_ctx, char *enc_msg, char *dec_key)
/* Set gpg signature verify on.
*/
ctx->verify_gpg_sigs = 1;
#endif /* HAVE_LIBGPGME */
#endif /* HAVE_LIBGPGME */
*r_ctx = ctx;
@@ -243,6 +239,12 @@ fko_destroy(fko_ctx_t ctx)
free(ctx->encrypted_msg);
#if HAVE_LIBGPGME
if(ctx->gpg_exe != NULL)
free(ctx->gpg_exe);
if(ctx->gpg_home_dir != NULL)
free(ctx->gpg_home_dir);
if(ctx->gpg_recipient != NULL)
free(ctx->gpg_recipient);
+18 -35
View File
@@ -50,11 +50,20 @@ init_gpgme(fko_ctx_t fko_ctx)
err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
{
/* GPG engine is not available. */
/* GPG engine is not available.
*/
fko_ctx->gpg_err = err;
return(FKO_ERROR_GPGME_NO_OPENPGP);
}
/* Extract the current gpgme engine information.
*/
gpgme_set_engine_info(
GPGME_PROTOCOL_OpenPGP,
(fko_ctx->gpg_exe != NULL) ? fko_ctx->gpg_exe : GPG_EXE,
fko_ctx->gpg_home_dir /* If this is NULL, the default is used */
);
/* Create our gpgme context
*/
err = gpgme_new(&(fko_ctx->gpg_ctx));
@@ -64,29 +73,6 @@ init_gpgme(fko_ctx_t fko_ctx)
return(FKO_ERROR_GPGME_CONTEXT);
}
/* Extract the current gpgme engine information.
*/
eng_info = gpgme_ctx_get_engine_info(fko_ctx->gpg_ctx);
/* If a gpg_home_dir was not given or the given dir does not
* match what we already have, then add the new dir to the context.
*/
if(fko_ctx->gpg_home_dir != NULL)
{
err = gpgme_ctx_set_engine_info(
fko_ctx->gpg_ctx,
eng_info->protocol,
eng_info->file_name,
fko_ctx->gpg_home_dir
);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
{
fko_ctx->gpg_err = err;
return(FKO_ERROR_GPGME_SET_HOME_DIR);
}
}
fko_ctx->have_gpgme_context = 1;
return(FKO_SUCCESS);
@@ -95,25 +81,22 @@ init_gpgme(fko_ctx_t fko_ctx)
/* Callback function that supplies the password when gpgme needs it.
*/
gpgme_error_t
passphrase_cb(
my_passphrase_cb(
void *pw, const char *uid_hint, const char *passphrase_info,
int prev_was_bad, int fd)
{
ssize_t num_bytes = 0;
/* We only need to try once as it is fed by the program
* (for now --DSS).
*/
if(prev_was_bad)
return(GPG_ERR_CANCELED);
num_bytes = write(fd, (const char*)pw, strlen((const char*)pw));
if (num_bytes != strlen((const char*)pw))
return(FKO_ERROR_FILESYSTEM_OPERATION);
if(write(fd, (const char*)pw, strlen((const char*)pw))
!= strlen((const char*)pw))
return(GPG_ERR_SYSTEM_ERROR); /* Must be a GPG error, but which one? */
num_bytes = write(fd, "\n", 1);
if (num_bytes != 1)
return(FKO_ERROR_FILESYSTEM_OPERATION);
if(write(fd, "\n", 1) != 1)
return(GPG_ERR_SYSTEM_ERROR); /* Must be a GPG error, but which one? */
return 0;
}
@@ -371,7 +354,7 @@ gpgme_encrypt(fko_ctx_t fko_ctx, unsigned char *indata, size_t in_len, const cha
/* Set the passphrase callback.
*/
gpgme_set_passphrase_cb(gpg_ctx, passphrase_cb, (void*)pw);
gpgme_set_passphrase_cb(gpg_ctx, my_passphrase_cb, (void*)pw);
/* Encrypt and sign (if a sig was provided) the SPA data.
*/
@@ -472,7 +455,7 @@ gpgme_decrypt(fko_ctx_t fko_ctx, unsigned char *indata, size_t in_len, const cha
/* Set the passphrase callback.
*/
gpgme_set_passphrase_cb(gpg_ctx, passphrase_cb, (void*)pw);
gpgme_set_passphrase_cb(gpg_ctx, my_passphrase_cb, (void*)pw);
/* Now decrypt and verify.
*/
-273
View File
@@ -1,273 +0,0 @@
dnl Helper Functions for the Fwknop configure.ac script
dnl (mostly borrowed from RRDtool source dist).
dnl
dnl this file gets included into aclocal.m4 when runnning aclocal
dnl
dnl
dnl
dnl Pthread check from http://autoconf-archive.cryp.to/acx_pthread.m4
dnl
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
dnl
dnl This macro figures out how to build C programs using POSIX threads.
dnl It sets the PTHREAD_LIBS output variable to the threads library and
dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
dnl C compiler flags that are needed. (The user can also force certain
dnl compiler flags/libs to be tested by setting these environment
dnl variables.)
dnl
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
dnl multi-threaded programs (defaults to the value of CC otherwise).
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
dnl
dnl NOTE: You are assumed to not only compile your program with these
dnl flags, but also link it with them as well. e.g. you should link
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
dnl $LIBS
dnl
dnl If you are only building threads programs, you may wish to use
dnl these variables in your default LIBS, CFLAGS, and CC:
dnl
dnl LIBS="$PTHREAD_LIBS $LIBS"
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
dnl CC="$PTHREAD_CC"
dnl
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
dnl
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
dnl default action will define HAVE_PTHREAD.
dnl
dnl Please let the authors know if this macro fails on any platform, or
dnl if you have any other suggestions or comments. This macro was based
dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
dnl We are also grateful for the helpful feedback of numerous users.
dnl
dnl @category InstalledPackages
dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
dnl @version 2005-01-14
dnl @license GPLWithACException
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_PUSH(C)
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthread or
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
if test x"$acx_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], [[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ]])],[acx_pthread_ok=yes],[])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], [[int attr=$attr;]])],[attr_name=$attr; break],[])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
x_rflag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) x_rflag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) x_rflag="-D_REENTRANT";;
*-linux* | *-k*bsd*-gnu*)
if test x"$PTHREAD_CFLAGS" = "x-pthread"; then
# For Linux/gcc "-pthread" implies "-lpthread". We need, however, to make this explicit
# in PTHREAD_LIBS such that a shared library to be built properly depends on libpthread.
PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
fi;;
esac
AC_MSG_RESULT(${x_rflag})
if test "x$x_rflag" != xno; then
PTHREAD_CFLAGS="$x_rflag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with cc_r
AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
AC_LANG_POP(C)
])dnl ACX_PTHREAD
dnl a macro to add some color to the build process.
dnl CONFIGURE_PART(MESSAGE)
AC_DEFUN([CONFIGURE_PART],[
case $TERM in
# for the most important terminal types we directly know the sequences
xterm|xterm*|vt220|vt220*)
T_MD=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
T_ME=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
;;
vt100|vt100*|cygwin)
T_MD=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
T_ME=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
;;
*)
T_MD=''
T_ME=''
;;
esac
AC_MSG_RESULT()
AC_MSG_RESULT([${T_MD}$1${T_ME}])
])
-307
View File
@@ -1,307 +0,0 @@
# gpgme.m4 - autoconf macro to detect GPGME.
# Copyright (C) 2002, 2003, 2004 g10 Code GmbH
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
AC_DEFUN([_AM_PATH_GPGME_CONFIG],
[ AC_ARG_WITH(gpgme-prefix,
AC_HELP_STRING([--with-gpgme-prefix=PFX],
[prefix where GPGME is installed (optional)]),
gpgme_config_prefix="$withval", gpgme_config_prefix="")
if test "x$gpgme_config_prefix" != x ; then
GPGME_CONFIG="$gpgme_config_prefix/bin/gpgme-config"
fi
AC_PATH_PROG(GPGME_CONFIG, gpgme-config, no)
if test "$GPGME_CONFIG" != "no" ; then
gpgme_version=`$GPGME_CONFIG --version`
fi
gpgme_version_major=`echo $gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
gpgme_version_minor=`echo $gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
gpgme_version_micro=`echo $gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
])
dnl AM_PATH_GPGME([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libgpgme and define GPGME_CFLAGS and GPGME_LIBS.
dnl
AC_DEFUN([AM_PATH_GPGME],
[ AC_REQUIRE([_AM_PATH_GPGME_CONFIG])dnl
tmp=ifelse([$1], ,1:0.4.2,$1)
if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
req_gpgme_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
min_gpgme_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
else
req_gpgme_api=0
min_gpgme_version="$tmp"
fi
AC_MSG_CHECKING(for GPGME - version >= $min_gpgme_version)
ok=no
if test "$GPGME_CONFIG" != "no" ; then
req_major=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
req_minor=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
req_micro=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
if test "$gpgme_version_major" -gt "$req_major"; then
ok=yes
else
if test "$gpgme_version_major" -eq "$req_major"; then
if test "$gpgme_version_minor" -gt "$req_minor"; then
ok=yes
else
if test "$gpgme_version_minor" -eq "$req_minor"; then
if test "$gpgme_version_micro" -ge "$req_micro"; then
ok=yes
fi
fi
fi
fi
fi
fi
if test $ok = yes; then
# If we have a recent GPGME, we should also check that the
# API is compatible.
if test "$req_gpgme_api" -gt 0 ; then
tmp=`$GPGME_CONFIG --api-version 2>/dev/null || echo 0`
if test "$tmp" -gt 0 ; then
if test "$req_gpgme_api" -ne "$tmp" ; then
ok=no
fi
fi
fi
fi
if test $ok = yes; then
GPGME_CFLAGS=`$GPGME_CONFIG --cflags`
GPGME_LIBS=`$GPGME_CONFIG --libs`
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
GPGME_CFLAGS=""
GPGME_LIBS=""
AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi
AC_SUBST(GPGME_CFLAGS)
AC_SUBST(GPGME_LIBS)
])
dnl AM_PATH_GPGME_PTH([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libgpgme and define GPGME_PTH_CFLAGS and GPGME_PTH_LIBS.
dnl
AC_DEFUN([AM_PATH_GPGME_PTH],
[ AC_REQUIRE([_AM_PATH_GPGME_CONFIG])dnl
tmp=ifelse([$1], ,1:0.4.2,$1)
if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
req_gpgme_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
min_gpgme_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
else
req_gpgme_api=0
min_gpgme_version="$tmp"
fi
AC_MSG_CHECKING(for GPGME Pth - version >= $min_gpgme_version)
ok=no
if test "$GPGME_CONFIG" != "no" ; then
if `$GPGME_CONFIG --thread=pth 2> /dev/null` ; then
req_major=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
req_minor=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
req_micro=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
if test "$gpgme_version_major" -gt "$req_major"; then
ok=yes
else
if test "$gpgme_version_major" -eq "$req_major"; then
if test "$gpgme_version_minor" -gt "$req_minor"; then
ok=yes
else
if test "$gpgme_version_minor" -eq "$req_minor"; then
if test "$gpgme_version_micro" -ge "$req_micro"; then
ok=yes
fi
fi
fi
fi
fi
fi
fi
if test $ok = yes; then
# If we have a recent GPGME, we should also check that the
# API is compatible.
if test "$req_gpgme_api" -gt 0 ; then
tmp=`$GPGME_CONFIG --api-version 2>/dev/null || echo 0`
if test "$tmp" -gt 0 ; then
if test "$req_gpgme_api" -ne "$tmp" ; then
ok=no
fi
fi
fi
fi
if test $ok = yes; then
GPGME_PTH_CFLAGS=`$GPGME_CONFIG --thread=pth --cflags`
GPGME_PTH_LIBS=`$GPGME_CONFIG --thread=pth --libs`
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
GPGME_PTH_CFLAGS=""
GPGME_PTH_LIBS=""
AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi
AC_SUBST(GPGME_PTH_CFLAGS)
AC_SUBST(GPGME_PTH_LIBS)
])
dnl AM_PATH_GPGME_PTHREAD([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libgpgme and define GPGME_PTHREAD_CFLAGS
dnl and GPGME_PTHREAD_LIBS.
dnl
AC_DEFUN([AM_PATH_GPGME_PTHREAD],
[ AC_REQUIRE([_AM_PATH_GPGME_CONFIG])dnl
tmp=ifelse([$1], ,1:0.4.2,$1)
if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
req_gpgme_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
min_gpgme_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
else
req_gpgme_api=0
min_gpgme_version="$tmp"
fi
AC_MSG_CHECKING(for GPGME pthread - version >= $min_gpgme_version)
ok=no
if test "$GPGME_CONFIG" != "no" ; then
if `$GPGME_CONFIG --thread=pthread 2> /dev/null` ; then
req_major=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
req_minor=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
req_micro=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
if test "$gpgme_version_major" -gt "$req_major"; then
ok=yes
else
if test "$gpgme_version_major" -eq "$req_major"; then
if test "$gpgme_version_minor" -gt "$req_minor"; then
ok=yes
else
if test "$gpgme_version_minor" -eq "$req_minor"; then
if test "$gpgme_version_micro" -ge "$req_micro"; then
ok=yes
fi
fi
fi
fi
fi
fi
fi
if test $ok = yes; then
# If we have a recent GPGME, we should also check that the
# API is compatible.
if test "$req_gpgme_api" -gt 0 ; then
tmp=`$GPGME_CONFIG --api-version 2>/dev/null || echo 0`
if test "$tmp" -gt 0 ; then
if test "$req_gpgme_api" -ne "$tmp" ; then
ok=no
fi
fi
fi
fi
if test $ok = yes; then
GPGME_PTHREAD_CFLAGS=`$GPGME_CONFIG --thread=pthread --cflags`
GPGME_PTHREAD_LIBS=`$GPGME_CONFIG --thread=pthread --libs`
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
GPGME_PTHREAD_CFLAGS=""
GPGME_PTHREAD_LIBS=""
AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi
AC_SUBST(GPGME_PTHREAD_CFLAGS)
AC_SUBST(GPGME_PTHREAD_LIBS)
])
dnl AM_PATH_GPGME_GLIB([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libgpgme-glib and define GPGME_GLIB_CFLAGS and GPGME_GLIB_LIBS.
dnl
AC_DEFUN([AM_PATH_GPGME_GLIB],
[ AC_REQUIRE([_AM_PATH_GPGME_CONFIG])dnl
tmp=ifelse([$1], ,1:0.4.2,$1)
if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
req_gpgme_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
min_gpgme_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
else
req_gpgme_api=0
min_gpgme_version="$tmp"
fi
AC_MSG_CHECKING(for GPGME - version >= $min_gpgme_version)
ok=no
if test "$GPGME_CONFIG" != "no" ; then
req_major=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
req_minor=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
req_micro=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
if test "$gpgme_version_major" -gt "$req_major"; then
ok=yes
else
if test "$gpgme_version_major" -eq "$req_major"; then
if test "$gpgme_version_minor" -gt "$req_minor"; then
ok=yes
else
if test "$gpgme_version_minor" -eq "$req_minor"; then
if test "$gpgme_version_micro" -ge "$req_micro"; then
ok=yes
fi
fi
fi
fi
fi
fi
if test $ok = yes; then
# If we have a recent GPGME, we should also check that the
# API is compatible.
if test "$req_gpgme_api" -gt 0 ; then
tmp=`$GPGME_CONFIG --api-version 2>/dev/null || echo 0`
if test "$tmp" -gt 0 ; then
if test "$req_gpgme_api" -ne "$tmp" ; then
ok=no
fi
fi
fi
fi
if test $ok = yes; then
GPGME_GLIB_CFLAGS=`$GPGME_CONFIG --glib --cflags`
GPGME_GLIB_LIBS=`$GPGME_CONFIG --glib --libs`
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
GPGME_GLIB_CFLAGS=""
GPGME_GLIB_LIBS=""
AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi
AC_SUBST(GPGME_GLIB_CFLAGS)
AC_SUBST(GPGME_GLIB_LIBS)
])
+89 -25
View File
@@ -38,8 +38,7 @@ incoming_spa(fko_srv_options_t *opts)
char spa_msg_src_ip[16];
char spa_msg_remain[1024]; /* --DSS should not have arbitrary limit */
time_t now_ts;
int res;
int ts_diff;
int res, ts_diff, enc_type;
int got_spa_error = 0;
spa_pkt_info_t *spa_pkt = &(opts->spa_pkt);
@@ -76,40 +75,105 @@ incoming_spa(fko_srv_options_t *opts)
fprintf(stderr, "SPA Packet: '%s'\n", spa_pkt->packet_data);
/* --DSS temp */
/* Decode the packet data. Try the plain key, then fallback to the gpg
* decrypt pw.
*/
if(acc->key != NULL)
{
res = fko_new_with_data(&ctx, spa_pkt->packet_data, acc->key);
/* If we had a decryption failure, fallback to gpg if we have a
* decryption key to try.
*/
if(res == FKO_ERROR_DECRYPTION_FAILURE && acc->gpg_decrypt_pw != NULL)
res = fko_new_with_data(&ctx, spa_pkt->packet_data, acc->gpg_decrypt_pw);
}
else if(acc->gpg_decrypt_pw != NULL)
{
/* Otherwise this is probably a GPG-only stanza...
*/
res = fko_new_with_data(&ctx, spa_pkt->packet_data, acc->gpg_decrypt_pw);
}
/* Reset the packet data length to 0. This our indicator to the rest of
* the program that we do not have a current spa packet to process
* (whcih we won't be the time we return from this function for whatever
* reason.
* (which we won't by the time we return from this function for whatever
* reason).
*/
spa_pkt->packet_data_len = 0;
/* Get encryption type and try its decoding routine first (if the key
* for that type is set)
*/
enc_type = fko_encryption_type(spa_pkt->packet_data);
if(enc_type == FKO_ENCRYPTION_RIJNDAEL)
{
if(acc->key != NULL)
res = fko_new_with_data(&ctx, spa_pkt->packet_data, acc->key);
else
{
log_msg(LOG_ERR|LOG_STDERR,
"No KEY for RIJNDAEL encrypted messages");
return(SPA_MSG_FKO_CTX_ERROR);
}
}
else if(enc_type == FKO_ENCRYPTION_GPG)
{
/* For GPG we create the new context without decrypting on the fly
* so we can set some GPG parameters first.
*/
if(acc->gpg_decrypt_pw != NULL)
{
res = fko_new_with_data(&ctx, spa_pkt->packet_data, NULL);
if(res != FKO_SUCCESS)
{
log_msg(LOG_WARNING|LOG_STDERR,
"Error creating fko context (before decryption): %s",
fko_errstr(res)
);
return(SPA_MSG_FKO_CTX_ERROR);
}
/* Set whatever GPG parameters we have.
*/
if(acc->gpg_home_dir != NULL)
fko_set_gpg_home_dir(ctx, acc->gpg_home_dir);
if(acc->gpg_decrypt_id != NULL)
fko_set_gpg_recipient(ctx, acc->gpg_decrypt_id);
/* If REMOTE_ID is set validate the check the signer. Otherwise,
* skip and ignore verify errors.
*
* TODO: At present we are not checking signatures.
*/
if(acc->gpg_remote_id != NULL)
{
/* TODO: Add sig verify code */
/** --DSS replace these with the real code **/
/**/ fko_set_gpg_signature_verify(ctx, 0); /**/
/**/ fko_set_gpg_ignore_verify_error(ctx, 1); /**/
/** --DSS replace these with the real code **/
}
else
{
fko_set_gpg_signature_verify(ctx, 0);
fko_set_gpg_ignore_verify_error(ctx, 1);
}
/* Now decrypt the data.
*/
res = fko_decrypt_spa_data(ctx, acc->gpg_decrypt_pw);
}
else
{
log_msg(LOG_ERR|LOG_STDERR,
"No GPG_DECRYPT_PW for GPG encrypted messages");
return(SPA_MSG_FKO_CTX_ERROR);
}
}
else
{
log_msg(LOG_ERR|LOG_STDERR, "Unable to determing encryption type. Got type=%i.",
enc_type);
return(SPA_MSG_FKO_CTX_ERROR);
}
/* Do we have a valid FKO context?
*/
if(res != FKO_SUCCESS)
{
log_msg(LOG_WARNING|LOG_STDERR, "Error creating fko context: %s",
fko_errstr(res));
return(SPA_MSG_FKO_CTX_ERROR);
if(IS_GPG_ERROR(res))
log_msg(LOG_WARNING|LOG_STDERR, " - GPG ERROR: %s",
fko_gpg_errstr(ctx));
goto clean_and_bail;
}
/* --DSS temp */