Added the Fko class code to wrap the _fko wrapper around libfko.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@303 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart 2010-11-27 03:18:58 +00:00
parent 00bc99a966
commit b6bf1d28bf
4 changed files with 394 additions and 8 deletions

View File

@ -14,6 +14,46 @@ To build and install the module:
* Build with "python setup.py build"
* Install with "python setup.py install"
Note: This version is just a plain wrapper around libfko. I do plan to
make a more complete OO Python module that wraps this one. --DSS
Simple usage example:
#!/usr/bin/python
#
# Import the Fko class and all constants.
#
from fko import *
# Create an Fko instance with an empty context.
#
fko = Fko()
# Set the SPA message (Note: Access request is default if not specified).
#
fko.spa_message("0.0.0.0,tcp/22")
# Create the final SPA data message string.
#
fko.spa_data_final("mypassword")
# print the spa message.
#
print fko.spa_data()
(prints something like this):
81ugT7+dv6p0qKPmFKwZYz9qAtqThBib+mIeZae9FK2UYQF5CNyujAmEH2+0CBxm3DpArlyySWqdfITvmfSBd11XbFPksK3iqWAPR65lVTYXrNywOxVN65Nmm9D0Qzsczx1hkeNg+g8qxecxO1XBc/LdHEa5C0FmI
# To decode SPA data:
#
fko = Fko("81ugT7+dv6p0qKPmFKwZYz9qAtqThBib+mIeZae9FK2UYQF5CNyujAmEH2+0CBxm3DpArlyySWqdfITvmfSBd11XbFPksK3iqWAPR65lVTYXrNywOxVN65Nmm9D0Qzsczx1hkeNg+g8qxecxO1XBc/LdHEa5C0FmI", "mypassword")
# Print some of the data:
#
print "Version:", fko.version()
print "Timestamp:", fko.timestamp()
print "Username:", fko.username()
print "Digest Type (value):", fko.digest_type()
print "Digest Type (string):", fko.digest_type_str()
print "Digest:", fko.digest()
print "SPA Message:", fko.spa_message()

345
python/fko.py Normal file
View File

@ -0,0 +1,345 @@
#
##############################################################################
#
# File: fko.py
#
# Author: Damien S. Stuart <dstuart@dstuart.org>
#
# Purpose: Module that provides a class that implements the functions for
# managing fwknop Single Packet Authorization (SPA) via the fwknop
# library (libfko).
#
##############################################################################
#
import _fko
# FKO Constants definitions
#
# Message types
FKO_COMMAND_MSG = 0
FKO_ACCESS_MSG = 1
FKO_NAT_ACCESS_MSG = 2
FKO_CLIENT_TIMEOUT_ACCESS_MSG = 3
FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG = 4
FKO_LOCAL_NAT_ACCESS_MSG = 5
FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG = 6
# Digest types
FKO_DIGEST_MD5 = 1
FKO_DIGEST_SHA1 = 2
FKO_DIGEST_SHA256 = 3
FKO_DIGEST_SHA384 = 4
FKO_DIGEST_SHA512 = 5
# Encryption types
FKO_ENCRYPTION_RIJNDAEL = 1
FKO_ENCRYPTION_GPG = 2
# FKO error codes
FKO_SUCCESS = 0
FKO_ERROR_CTX_NOT_INITIALIZED = 1
FKO_ERROR_MEMORY_ALLOCATION = 2
FKO_ERROR_FILESYSTEM_OPERATION = 3
FKO_ERROR_INVALID_DATA = 4
FKO_ERROR_DATA_TOO_LARGE = 5
FKO_ERROR_USERNAME_UNKNOWN = 6
FKO_ERROR_INCOMPLETE_SPA_DATA = 7
FKO_ERROR_MISSING_ENCODED_DATA = 8
FKO_ERROR_INVALID_DIGEST_TYPE = 9
FKO_ERROR_INVALID_ALLOW_IP = 10
FKO_ERROR_INVALID_SPA_COMMAND_MSG = 11
FKO_ERROR_INVALID_SPA_ACCESS_MSG = 12
FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG = 13
FKO_ERROR_INVALID_ENCRYPTION_TYPE = 14
FKO_ERROR_WRONG_ENCRYPTION_TYPE = 15
FKO_ERROR_DECRYPTION_SIZE = 16
FKO_ERROR_DECRYPTION_FAILURE = 17
FKO_ERROR_DIGEST_VERIFICATION_FAILED = 18
FKO_ERROR_UNSUPPORTED_FEATURE = 19
FKO_ERROR_UNKNOWN = 20
# Start GPGME-related errors
GPGME_ERR_START = 21
FKO_ERROR_MISSING_GPG_KEY_DATA = 22
FKO_ERROR_GPGME_NO_OPENPGP = 23
FKO_ERROR_GPGME_CONTEXT = 24
FKO_ERROR_GPGME_PLAINTEXT_DATA_OBJ = 25
FKO_ERROR_GPGME_SET_PROTOCOL = 26
FKO_ERROR_GPGME_CIPHER_DATA_OBJ = 27
FKO_ERROR_GPGME_BAD_PASSPHRASE = 28
FKO_ERROR_GPGME_ENCRYPT_SIGN = 29
FKO_ERROR_GPGME_CONTEXT_SIGNER_KEY = 30
FKO_ERROR_GPGME_SIGNER_KEYLIST_START = 31
FKO_ERROR_GPGME_SIGNER_KEY_NOT_FOUND = 32
FKO_ERROR_GPGME_SIGNER_KEY_AMBIGUOUS = 33
FKO_ERROR_GPGME_ADD_SIGNER = 34
FKO_ERROR_GPGME_CONTEXT_RECIPIENT_KEY = 35
FKO_ERROR_GPGME_RECIPIENT_KEYLIST_START = 36
FKO_ERROR_GPGME_RECIPIENT_KEY_NOT_FOUND = 37
FKO_ERROR_GPGME_RECIPIENT_KEY_AMBIGUOUS = 38
FKO_ERROR_GPGME_DECRYPT_FAILED = 39
FKO_ERROR_GPGME_DECRYPT_UNSUPPORTED_ALGORITHM = 40
FKO_ERROR_GPGME_BAD_GPG_EXE = 41
FKO_ERROR_GPGME_BAD_HOME_DIR = 42
FKO_ERROR_GPGME_SET_HOME_DIR = 43
FKO_ERROR_GPGME_NO_SIGNATURE = 44
FKO_ERROR_GPGME_BAD_SIGNATURE = 45
FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED = 46
### End FKO Constants ###
class Fko:
"""This class wraps the Firewall KNock OPerator (fwknop) library,
libfko. It provides the functionality to manage and process
Single Packet Authorization (SPA) data.
"""
def __init__(self, spa_data=None, key=None):
"""Constructor for the Fko class.
Creates and intitializes the fko context.
If no arguments are given, and empty context is create with
some default values. See the libfko documentation for details
on these defaults.
If spa_data and key is supplied, the context is created, then
the SPA data is decrypted using the key. If successful, the SPA
data is parsed into the context's data structure.
If spa_data is supplied without the key, then the encrypted data
is stored in the context and can be decoded later (see libfko docs).
"""
# If there is SPA data, attempt to process it. Otherwise, create
# an empty context.
#
if(spa_data != None):
self.ctx = _fko.init_ctx_with_data(spa_data, key)
else:
self.ctx = _fko.init_ctx()
# Destructor to make sure the fko context is properly destroyed and
# the memory it was using is released.
#
def __del__(self):
_fko.destroy_ctx(self.ctx)
### FKO data functions and operations. ###
def version(self):
return _fko.get_version(self.ctx)
def rand_value(self, val=None):
if(val != None):
_fko.set_rand_value(self.ctx, val)
else:
return _fko.get_rand_value(self.ctx)
def username(self, val=None):
if(val != None):
_fko.set_username(self.ctx, val)
else:
return _fko.get_username(self.ctx)
def timestamp(self, val=None):
if(val != None):
_fko.set_timestamp(self.ctx, val)
else:
return _fko.get_timestamp(self.ctx)
def digest_type(self, val=None):
if(val != None):
_fko.set_spa_digest_type(self.ctx, val)
else:
return _fko.get_spa_digest_type(self.ctx)
def encryption_type(self, val=None):
if(val != None):
_fko.set_spa_encryption_type(self.ctx, val)
else:
return _fko.get_spa_encryption_type(self.ctx)
def message_type(self, val=None):
if(val != None):
_fko.set_spa_message_type(self.ctx, val)
else:
return _fko.get_spa_message_type(self.ctx)
def spa_message(self, val=None):
if(val != None):
_fko.set_spa_message(self.ctx, val)
else:
return _fko.get_spa_message(self.ctx)
def spa_nat_access(self, val=None):
if(val != None):
_fko.set_spa_nat_access(self.ctx, val)
else:
return _fko.get_spa_nat_access(self.ctx)
def spa_server_auth(self, val=None):
if(val != None):
_fko.set_spa_server_auth(self.ctx, val)
else:
return _fko.get_spa_server_auth(self.ctx)
def spa_client_timeout(self, val=None):
if(val != None):
_fko.set_spa_client_timeout(self.ctx, val)
else:
return _fko.get_spa_client_timeout(self.ctx)
def spa_digest(self):
return _fko.get_spa_digest(self.ctx)
def gen_spa_digest(self):
_fko.set_spa_digest(self.ctx)
def spa_data(self, val=None):
if(val != None):
_fko.set_spa_data(self.ctx, val)
else:
return _fko.get_spa_data(self.ctx)
def encoded_data(self):
return _fko.get_encoded_data(self.ctx)
def spa_data_final(self, key):
_fko.spa_data_final(self.ctx, key)
def gen_spa_data(self, key):
_fko.spa_data_final(self.ctx, key)
def encode_spa_data(self):
_fko.encode_spa_data(self.ctx)
def decode_spa_data(self):
_fko.decode_spa_data(self.ctx)
def encrypt_spa_data(self, key):
_fko.encrypt_spa_data(self.ctx, key)
def decrypt_spa_data(self, key):
_fko.decrypt_spa_data(self.ctx, key)
# GPG-related functions.
def gpg_recipient(self, val=None):
if(val != None):
_fko.set_gpg_recipient(self.ctx, val)
else:
return _fko.get_gpg_recipient(self.ctx)
def gpg_signer(self, val=None):
if(val != None):
_fko.set_gpg_signer(self.ctx, val)
else:
return _fko.get_gpg_signer(self.ctx)
def gpg_home_dir(self, val=None):
if(val != None):
_fko.set_gpg_home_dir(self.ctx, val)
else:
return _fko.get_gpg_home_dir(self.ctx)
def gpg_signature_verify(self, val=None):
if(val != None):
_fko.set_gpg_signature_verify(self.ctx, val)
else:
return _fko.get_gpg_signature_verify(self.ctx)
def gpg_ignore_verify_error(self, val=None):
if(val != None):
_fko.set_gpg_ignore_verify_error(self.ctx, val)
else:
return _fko.get_gpg_ignore_verify_error(self.ctx)
def gpg_exe(self, val=None):
if(val != None):
_fko.set_gpg_exe(self.ctx, val)
else:
return _fko.get_gpg_exe(self.ctx)
def gpg_signature_id(self):
return _fko.get_gpg_signature_id(self.ctx)
def gpg_signature_fpr(self):
return _fko.get_gpg_signature_fpr(self.ctx)
def gpg_signature_summary(self):
return _fko.get_gpg_signature_summary(self.ctx)
def gpg_signature_status(self):
return _fko.get_gpg_signature_status(self.ctx)
def gpg_signature_id_match(self, val):
if(_fko.gpg_signature_id_match(self.ctx) > 0):
return True
return False
def gpg_signature_fpr_match(self, val):
if(_fko.gpg_signature_fpr_match(self.ctx) > 0):
return True
return False
# Error message string function.
def errstr(self, val):
return _fko.errstr(code)
# FKO type lookup functions.
def message_type_str(self, val=None):
if val == None:
val = _fko.get_spa_message_type(self.ctx)
if val == FKO_COMMAND_MSG:
mts = "Command Message"
elif val == FKO_ACCESS_MSG:
mts = "Access Message"
elif val == FKO_NAT_ACCESS_MSG:
mts = "NAT Access Message"
elif val == FKO_CLIENT_TIMEOUT_ACCESS_MSG:
mts = "Access Message with timeout"
elif val == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG:
mts = "NAT access Message with timeout"
elif val == FKO_LOCAL_NAT_ACCESS_MSG:
mts = "Local NAT Access Message"
elif val == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG:
mts = "Local NAT Access Message with timeout"
else:
mts = "Unknown message type"
return mts
def digest_type_str(self, val=None):
if val == None:
val = _fko.get_spa_digest_type(self.ctx)
if val == FKO_DIGEST_MD5:
dts = "MD5"
elif val == FKO_DIGEST_SHA1:
dts = "SHA1"
elif val == FKO_DIGEST_SHA256:
dts = "SHA256"
elif val == FKO_DIGEST_SHA384:
dts = "SHA384"
elif val == FKO_DIGEST_SHA512:
dts = "SHA512"
else:
dts = "Unknown digest type"
return dts
def encryption_type_str(self, val=None):
if val == None:
val = _fko.get_spa_encryption_type(self.ctx)
if val == FKO_ENCRYPTION_RIJNDAEL:
ets = "Rijndael (AES)"
elif val == FKO_ENCRYPTION_GPG:
ets = "GPG"
else:
ets = "Unknown encryption type"
return ets
###EOF###

View File

@ -209,11 +209,11 @@ static PyMethodDef FKOMethods[] = {
* Module init
*/
PyMODINIT_FUNC
initfko(void)
init_fko(void)
{
PyObject *m;
m = Py_InitModule("fko", FKOMethods);
m = Py_InitModule("_fko", FKOMethods);
if (m == NULL)
return;
@ -423,7 +423,7 @@ get_timestamp(PyObject *self, PyObject *args)
return NULL;
}
return Py_BuildValue("I", timestamp);
return Py_BuildValue("k", timestamp);
}
/* set_timestamp
@ -434,7 +434,7 @@ set_timestamp(PyObject *self, PyObject *args)
fko_ctx_t ctx;
int res, offset;
if(!PyArg_ParseTuple(args, "ki", &ctx, &offset))
if(!PyArg_ParseTuple(args, "kk", &ctx, &offset))
return NULL;
res = fko_set_timestamp(ctx, offset);

View File

@ -12,7 +12,7 @@
from distutils.core import setup, Extension
module1 = Extension(
'fko',
'_fko',
define_macros = [('MAJOR_VERSION', '1'), ('MINOR_VERSION', '0')],
libraries = ['fko'],
sources = ['fkomodule.c']
@ -29,5 +29,6 @@ setup (
Python module that wraps the fwknop library to provide the ability to
generate, decode, parse, and process SPA formatted messages.
''',
ext_modules = [module1]
ext_modules = [module1],
py_modules = ['fko']
)