Commit 3dc63e9d authored by 's avatar

Added the --enable-ssl option for enabling secure sockets in DiMAPI"


git-svn-id: file:///home/svn/mapi/trunk@779 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent 69644079
......@@ -168,15 +168,17 @@ if test "x$prefix" = "xNONE"; then
prefix=$ac_default_prefix
fi
AC_MSG_NOTICE([options -----------------------------------------------------])
AC_MSG_NOTICE([MAPI options ------------------------------------------------])
AC_DEFINE(CONF_FILE, "mapi.conf", [configuration file])
AC_DEFINE(MAPICOMMD_SSL_KEY_FILE, "mapicommd_key.pem", [mapicommd SSL key])
AC_DEFINE(MAPICOMMD_SSL_CERT_FILE, "mapicommd_cert.pem", [mapicommd SSL certificate])
# development defines - leave them enabled for now
AC_DEFINE(DEBUG, 1, [keep debugging on during beta testing])
AC_DEFINE(VALGRIND, 1, [easier debugging using valgrind])
#AC_DEFINE(WITH_AUTHENTICATION, 1, [support for authentication])
# in the end will contain all the compiled MAPI function libraries
# in the end will contain all the enabled MAPI function libraries
MAPI_FUNC_LIBS="stdflib.so"
# DiMAPI
......@@ -196,6 +198,37 @@ else
AC_MSG_RESULT(no)
fi
# SSL sockets (only for DiMAPI)
if test x$dimapi = xtrue; then
AC_MSG_CHECKING([if SSL for DiMAPI is enabled])
fi
AC_ARG_ENABLE(ssl,
AS_HELP_STRING([--enable-ssl], [Enable encryption of DiMAPI traffic]),
[
if test x$dimapi = xfalse; then
AC_MSG_ERROR(Please use --enable-ssl only in conjunction with --enable-dimapi. You don't need to enable SSL if you are not going to use DiMAPI)
fi
case "${enableval}" in
yes) ssl=true ;;
no) ssl=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-ssl) ;;
esac
],
[
ssl=false
]
)
if test x$dimapi = xtrue; then
if test x$ssl = xtrue; then
AC_DEFINE(DIMAPISSL, 1, [SSL support for DiMAPI])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
fi
# for etc/Makefile.am
AM_CONDITIONAL(SSL_IS_ENABLED, test x$ssl = xtrue)
# DAG support
AC_MSG_CHECKING(if DAG cards support is enabled)
AC_ARG_ENABLE(dag,
......@@ -320,7 +353,9 @@ fi
# Checks for libraries
AC_MSG_NOTICE([libraries ---------------------------------------------------])
#
# libpcap
#
AC_MSG_CHECKING([for libpcap])
AC_ARG_WITH(libpcap,
AS_HELP_STRING([--with-libpcap=DIR], [Manual libpcap path configuration, in case the configuration script can't find it. Search for libpcap in DIR/lib, and for the header file in DIR/include]),
......@@ -357,7 +392,9 @@ AS_HELP_STRING([--with-libpcap=DIR], [Manual libpcap path configuration, in case
AC_SUBST(PCAPINC)
AC_SUBST(PCAPLIB)
#
# libdag (only for --enable-dag)
#
AC_MSG_CHECKING([for libdag])
AC_ARG_WITH(libdag,
AS_HELP_STRING([--with-libdag=DIR], [Manual libdag path configuration, in case the configuration script can't find it. Search for libdag in DIR/lib, and for the header file in DIR/include. Effective only if --enable-dag has been previously specified]),
......@@ -405,7 +442,9 @@ AS_HELP_STRING([--with-libdag=DIR], [Manual libdag path configuration, in case t
AC_SUBST(DAGINC)
AC_SUBST(DAGLIB)
#
# libpcre (only for --enable-extraflib) - based on Snort's configure.in
#
AC_ARG_WITH(libpcre_includes,
AS_HELP_STRING([--with-libpcre-includes=DIR], [Search for libpcre headers in DIR. Effective only if --enable-extraflib has been previously specified]),
[with_libpcre_includes="$withval"],[with_libpcre_includes=no])
......@@ -480,8 +519,64 @@ if test x$extraflib = xtrue; then
fi # test x$extraflib = xtrue
#
# SSL - based on stunnel's configure.ac (only for --enable-ssl)
#
checkssldir() { :
if test -f "$1/include/openssl/ssl.h"
then AC_DEFINE([HAVE_OPENSSL], 1, [whether we are using openssl])
ssldir="$1"
return 0
fi
if test -f "$1/include/ssl.h"
then ssldir="$1"
return 0
fi
return 1
}
if test x$ssl = xtrue; then
AC_MSG_CHECKING([for SSL directory]);
fi
AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=DIR], [Location of installed SSL libraries/include files]),
[
# Check the specified localtion only
if test x$ssl = xtrue; then
checkssldir "$withval"
else
AC_MSG_ERROR(Please use --with-ssl only in conjunction with --enable-dimapi and --enable-ssl. You don't need to configure SSL if you are not going to use DiMAPI with secure sockets.)
fi
],
[
if test x$ssl = xtrue; then
# Search default localtions of SSL library
for maindir in /usr/local /usr/lib /usr/pkg /usr /var/ssl /opt; do
for dir in $maindir $maindir/openssl $maindir/ssl; do
checkssldir $dir && break 2
done
done
fi
]
)
if test x$ssl = xtrue; then
if test -z "$ssldir"; then
AC_MSG_RESULT([Not found])
echo
echo "Couldn't find your SSL library installation dir"
echo "Use --with-ssl option to fix this problem"
echo
exit 1
fi
AC_MSG_RESULT([$ssldir])
SSLINC="-I$ssldir/include"
SSLLIB="-L$ssldir/lib -lssl"
AC_SUBST(SSLINC)
AC_SUBST(SSLLIB)
fi
#
# misc libs
#
save_LIBS=$LIBS
AC_CHECK_LIB(m, floor,,)
AC_CHECK_LIB(rt, sem_wait,,)
......@@ -554,6 +649,9 @@ echo "MAPI function libraries: ${MAPI_FUNC_LIBS}"
if test x$dimapi = xtrue; then
echo "option: DiMAPI"
fi
if test x$ssl = xtrue; then
echo "option: SSL"
fi
if test x$dag = xtrue; then
echo "option: support for DAG cards"
fi
......
......@@ -389,6 +389,7 @@ optional features:
\begin{tabular}{rp{7cm}}
{\tt --enable-dimapi} & Support for remote and distributed monitoring (cf.
Section~\ref{sec:dimapi}) \\
{\tt --enable-ssl} & Enable encryption of DiMAPI traffic \\
{\tt --enable-dag} & Support for Endace DAG packet capture cards \\
\multicolumn{2}{l}{MAPI function libraries} \\
{\tt --enable-trackflib} & Build the traffic characterization library \\
......
confdir = $(sysconfdir)/mapi
conf_DATA = mapi.conf
conf_DATA = mapi.conf
# override the default conf install to check for mapi.conf overwrite
install-confDATA: $(conf_DATA)
......@@ -15,3 +15,18 @@ else \
$(confDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(confdir)/$$f"; \
fi \
done
# ssl stuff
if SSL_IS_ENABLED
install-data-local:
echo Generating SSL keys
openssl genrsa -out mapicommd_key.pem 1024 2> /dev/null
openssl req -new -x509 -days 30000 -key mapicommd_key.pem -out mapicommd_cert.pem -config mapicommd_cert.cnf
${INSTALL} -m 600 mapicommd_key.pem $(DESTDIR)$(confdir)/mapicommd_key.pem
${INSTALL} -m 600 mapicommd_cert.pem $(DESTDIR)$(confdir)/mapicommd_cert.pem
rm mapicommd_key.pem mapicommd_cert.pem
uninstall-local:
rm -f $(DESTDIR)$(confdir)/mapicommd_key.pem
rm -f $(DESTDIR)$(confdir)/mapicommd_cert.pem
endif
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
C = GB
ST = Test State or Province
L = Test Locality
O = Organization Name
OU = Organizational Unit Name
CN = Common Name
emailAddress = test@email.address
GR
-
Herakleion
ICS FORTH
DCS
User
dcs@ics.forth.gr
## Process this file with automake to produce Makefile.in
AM_CPPFLAGS = -I.. -I../lib -I../drivers -D_GNU_SOURCE -D_THREAD_SAFE
AM_CPPFLAGS = -I.. -I../lib -I../drivers @SSLINC@ -D_GNU_SOURCE -D_THREAD_SAFE
noinst_LTLIBRARIES = libflist.la libfhelp.la libmapiipc.la libparseconf.la libprintfstring.la libmapilibhandler.la libmsearch.la libacsmx2.la
libflist_la_SOURCES = flist.c flist.h
libflist_la_DEPENDENCIES = mapi_errors.h
libfhelp_la_SOURCES = fhelp.c fhelp.h
libmapiipc_la_SOURCES = mapiipc.c mapiipc.h
libmapiipc_la_LIBADD = @SSLLIB@
libparseconf_la_SOURCES = parseconf.c parseconf.h
libprintfstring_la_SOURCES = printfstring.c printfstring.h
libmapilibhandler_la_SOURCES = mapilibhandler.c mapilibhandler.h
......
......@@ -111,7 +111,7 @@ flist_t *remote_flowlist=NULL;
int mapiipc_remote_write(struct dmapiipcbuf *dbuf, struct host *h)
//Sends an IPC message to mapid
{
// qbuf->uid=getuid();
// qbuf->uid=getuid();
#ifdef DIMAPISSL
if(SSL_write(h->con,dbuf,dbuf->length) == -1){
......@@ -119,17 +119,14 @@ int mapiipc_remote_write(struct dmapiipcbuf *dbuf, struct host *h)
// exit(1);
return -1;
}
#else
if(send(h->sockfd, dbuf, dbuf->length, 0) == -1) {
WARNING_CMD(printf("send: %s [%s:%d]\n",strerror(errno),__FILE__,__LINE__));
// exit(1);
return -1;
}
#endif
#ifndef DIMAPISSL
if(send(h->sockfd, dbuf, dbuf->length, 0) == -1) {
WARNING_CMD(printf("send: %s [%s:%d]\n",strerror(errno),__FILE__,__LINE__));
// exit(1);
return -1;
}
#endif
return 0;
return 0;
}
......@@ -149,7 +146,7 @@ int mapiipc_remote_write_to_all(remote_flowdescr_t* rflow)
}
//pthread_mutex_unlock(&rflow->mutex);
for (fnode=flist_head(rflow->host_flowlist); fnode!=NULL; fnode=flist_next(fnode)) {
sem_wait(&rflow->fd_sem);
sem_wait(&rflow->fd_sem);
}
return 0;
}
......@@ -169,21 +166,18 @@ void *mapiipc_comm_thread(void *host) {
/* Guarantees that thread resources are deallocated upon return */
pthread_detach(pthread_self());
dbuf = (struct dmapiipcbuf *)malloc(sizeof(struct dmapiipcbuf));
dbuf = (struct dmapiipcbuf *)malloc(sizeof(struct dmapiipcbuf));
while (1) {
if (host==NULL) break;
if (host==NULL) break;
#ifdef DIMAPISSL
recv_bytes = SSL_readn(hostconn,dbuf,BASIC_SIZE);
recv_bytes = SSL_readn(hostconn,dbuf,BASIC_SIZE);
#else
recv_bytes = readn(sockfd, dbuf, BASIC_SIZE);
#endif
#ifndef DIMAPISSL
recv_bytes=readn(sockfd, dbuf, BASIC_SIZE);
#endif
if (recv_bytes == 0) { // the peer has gone
//printf("Socket closed\n");
break;
......@@ -192,19 +186,17 @@ void *mapiipc_comm_thread(void *host) {
//ERROR_CMD(printf("recv: %s [%s:%d]\n",strerror(errno),__FILE__,__LINE__));
continue;
}
if (dbuf->length > DIMAPI_DATA_SIZE) {
fprintf(stderr,"Bad IPC message from agent\n");
continue;
}
if (dbuf->length-BASIC_SIZE>0) {
#ifdef DIMAPISSL
recv_bytes = SSL_readn(hostconn,(char *)dbuf + BASIC_SIZE, dbuf->length - BASIC_SIZE );
#endif
#ifndef DIMAPISSL
recv_bytes = SSL_readn(hostconn,(char *)dbuf + BASIC_SIZE, dbuf->length - BASIC_SIZE );
#else
recv_bytes=readn(sockfd, (char*)dbuf+BASIC_SIZE, dbuf->length-BASIC_SIZE);
#endif
if (recv_bytes == 0) { // the peer has gone
......@@ -216,7 +208,7 @@ void *mapiipc_comm_thread(void *host) {
continue;
}
}
hflow=(host_flow*)flist_get( ((struct host*)host)->flows, dbuf->fd );
if (hflow!=NULL) {
rflow=flist_get(remote_flowlist, hflow->scope_fd);
......@@ -251,8 +243,7 @@ int mapiipc_remote_init(struct host *h)
struct hostent* host=gethostbyname(h->hostname);
struct timeval tv;
#ifdef DIMAPISSL
#ifdef DIMAPISSL
SSL_library_init();
SSL_load_error_strings();
......@@ -264,10 +255,8 @@ int mapiipc_remote_init(struct host *h)
ERR_print_errors_fp(stderr);
return 0;;
}
#endif
if ((h->sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
ERROR_CMD(printf("socket: %s [%s:%d]\n",strerror(errno),__FILE__,__LINE__));
//exit(-1);
......@@ -307,15 +296,14 @@ int mapiipc_remote_init(struct host *h)
remoteaddr.sin_addr = *((struct in_addr *)host->h_addr);
remoteaddr.sin_port = htons(h->port);
if (connect(h->sockfd, (struct sockaddr *)&remoteaddr, sizeof(remoteaddr)) < 0) {
if (connect(h->sockfd, (struct sockaddr *)&remoteaddr, sizeof(remoteaddr)) < 0) {
ERROR_CMD(printf("connect failed: %s [%s:%d]\n",strerror(errno),__FILE__,__LINE__));
//exit(EXIT_FAILURE);
return -1;
}
#ifdef DIMAPISSL
if (SSL_set_fd(h->con, h->sockfd) == 0) {
if (SSL_set_fd(h->con, h->sockfd) == 0) {
ERR_print_errors_fp(stderr);
return 0;
}
......@@ -323,7 +311,6 @@ int mapiipc_remote_init(struct host *h)
ERR_print_errors_fp(stderr);
return 0;
}
#endif
return 0;
......@@ -332,15 +319,16 @@ int mapiipc_remote_init(struct host *h)
void mapiipc_remote_close(struct host *h)
//Releases socket resources
{
#ifdef DIMAPISSL
if (SSL_shutdown(h->con) == -1)
if (SSL_shutdown(h->con) == -1) {
ERR_print_errors_fp(stderr);
}
#endif
shutdown(h->sockfd, SHUT_RDWR);
close(h->sockfd);
shutdown(h->sockfd, SHUT_RDWR);
close(h->sockfd);
}
#endif
#endif /* DIMAPI */
// Helper functions for function arguments retrieval
......@@ -534,14 +522,14 @@ ssize_t readn(int fd, void *vptr, size_t n) {
#ifdef DIMAPISSL
ssize_t SSL_readn(SSL *con, void *vptr, size_t n) {
size_t nleft;
ssize_t nread;
char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
errno=0;
if ( (nread = SSL_read(con, ptr, nleft)) < 0) {
......
#ifndef _MAPIIPC_H
#define _MAPIIPC_H 1
//#define DIMAPISSL
#ifdef DIMAPISSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif
#include "mapi.h"
......@@ -17,7 +8,16 @@
#include <pthread.h>
#include <semaphore.h>
#include "flist.h"
#endif
#ifdef DIMAPISSL
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#else
#include <ssl.h>
#include <err.h>
#endif /* HAVE_OPENSSL */
#endif /* DIMAPISSL */
#endif /* DIMAPI */
#define MAX_SEND_SIZE 8192//1024
#define FUNCTARGS_BUF_SIZE 7168
......@@ -33,18 +33,14 @@
//system that do not need to be changed for each new function type
//that is added.
#ifdef DIMAPISSL
static SSL_CTX *ctx;
struct overload{
SSL * connection;
int sock;
};
#endif
//Messages types that can be sent to/from mapi and mapid
typedef enum {
CREATE_FLOW,
......@@ -99,7 +95,6 @@ typedef enum {
SEND_FD,
GET_NEXT_PKT,
GET_NEXT_PKT_ACK
} mapiipcMsg;
......@@ -128,7 +123,7 @@ int mapiipc_client_init(void);
void mapiipc_daemon_init(void);
//Sends an IPC message
int mapiipc_write(struct mapiipcbuf *qbuf);
int mapiipc_write(struct mapiipcbuf *qbuf);
//Reads an IPC message. Blocking call.
int mapiipc_read(struct mapiipcbuf *qbuf);
......@@ -192,7 +187,7 @@ typedef struct remote_flowdescr {
//pthread_mutex_t mutex;
//struct mapipkt* pkt; DELETE
flist_t* function_res;
unsigned char is_connected; // This should be 1 if the flow is connected 0 otherwise
unsigned char is_connected; // This should be 1 if the flow is connected 0 otherwise
/* int error;
char errstr[MAPI_ERRORSTR_LENGTH];
*/
......
......@@ -33,37 +33,40 @@ int die(char *msg);
int getfid(struct dmapiipcbuf *dbuf);
int main() {
int serv_sock = 0;
int new_sock = 0; /* client's socket descriptor (from connect()) */
socklen_t clnt_len; /* length of client address data structure */
int yes=1;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
#ifdef DIMAPISSL
struct overload *inst;
SSL *con=NULL;
OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
SSL_library_init();
SSL_load_error_strings();
#endif
#endif
pthread_t chld_thr;
char* mapi_conf;
//mapi_conf = malloc(sizeof(CONF_FILE)-2+strlen(getenv("HOME")));
//sprintf(mapi_conf,CONF_FILE,getenv("HOME"));
mapi_conf = printf_string( CONFDIR"/"CONF_FILE );
printf("using %s\n", mapi_conf);
#ifdef DIMAPISSL
printf("SSL enabled\n");
#endif
if (pc_load (mapi_conf))
{
dimapi_port = atoi( pc_get_param (pc_get_category(""), "dimapi_port") );
}
else
else
{
printf("Error: cannot load mapi.conf file.\n");
exit(1);
......@@ -75,33 +78,26 @@ int main() {
die("Unexpected error on socket()");
exit(-1);
}
memset(&serv_addr, 0, sizeof serv_addr);
serv_addr.sin_family = AF_INET;
memset(&serv_addr, 0, sizeof serv_addr);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(dimapi_port);
#ifdef DIMAPISSL
/**** SSL CHANGES **********/
if ((ctx=SSL_CTX_new(SSLv3_server_method())) == NULL) {
ERR_print_errors_fp(stderr);
return 0;
}
if (SSL_CTX_use_certificate_file(ctx, "/usr/local/share/mapi/cacert.pem", SSL_FILETYPE_PEM) <= 0) {
if (SSL_CTX_use_certificate_file(ctx, CONFDIR"/"MAPICOMMD_SSL_CERT_FILE, SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
return 0;
}
if (SSL_CTX_use_PrivateKey_file(ctx, "/usr/local/share/mapi/privkey.pem", SSL_FILETYPE_PEM) <= 0) {
if (SSL_CTX_use_PrivateKey_file(ctx, CONFDIR"/"MAPICOMMD_SSL_KEY_FILE, SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
return 0;
}
/*** END OF SSL CHANGES *****/
#endif
/* DANGEROUS, but useful for debugging, so leave it for now */
......@@ -135,68 +131,48 @@ int main() {
}
#ifdef DIMAPISSL
printf("\n\t\tDiMAPI (SSL ENCRYPTION)\n");
if ((con=SSL_new(ctx)) == NULL) {
ERR_print_errors_fp(stderr);
return 0;;
}
if (SSL_set_fd(con, new_sock) == 0) {
ERR_print_errors_fp(stderr);
return 0;
}
if (SSL_accept(con) <= 0) {
ERR_print_errors_fp(stderr);
return 0;
}
#endif
#ifndef DIMAPISSL
printf("\n\t\tDiMAPI (no encryption)\n");
#endif
printf("<*> got connection from %s\n", inet_ntoa(clnt_addr.sin_addr));
#ifdef DIMAPISSL
inst = (struct overload *)malloc(sizeof(struct overload));
inst = (struct overload *)malloc(sizeof(struct overload));
inst->connection = con;
inst->sock = new_sock;
if (pthread_create(&chld_thr, NULL, handle_request,(void *) inst) != 0){
die("pthread_create() failed");
continue;
}
#endif
#ifndef DIMAPISSL
#else
if (pthread_create(&chld_thr, NULL, handle_request, (void *)new_sock) != 0) {
die("pthread_create() failed");
die("pthread_create() failed");
continue;
}
#endif
}
} /* while (1) */
return 0; /* never reached */
}
void *handle_request(void *arg) {
#ifdef DIMAPISSL
SSL *con ;
con = ((struct overload*)arg)->connection;
int sock = ((struct overload*)arg)->sock;
#endif
#ifndef DIMAPISSL
#else
int sock=(int)arg;
#endif
#endif
int recv_bytes;
//char buffer[DIMAPI_DATA_SIZE]; DELETE
struct dmapiipcbuf *dbuf=NULL;
......@@ -211,20 +187,15 @@ void *handle_request(void *arg) {
struct timeval tv; /*used for timestamping results when produced */
struct mapipkt *pkt;
/* Guarantees that thread resources are deallocated upon return */
pthread_detach(pthread_self());
pthread_detach(pthread_self());
dbuf = (struct dmapiipcbuf *)malloc(sizeof(struct dmapiipcbuf));
#ifdef DIMAPISSL
printf("<+> new thread %d, socket number = %d\n", (int)pthread_self(),(int) con);
#endif
#ifndef DIMAPISSL
#else
printf("<+> new thread %d, socket number = %d\n", (int)pthread_self(), sock);
#endif
while(1) {