From be7cc5efd2c1ad8227794f77c27e3376f509ef4a Mon Sep 17 00:00:00 2001 From: Jakub Sławiński Date: Wed, 3 Oct 2007 23:32:17 +0200 Subject: v0.8.4 - Added (by Joshua Judson Rosen): certificate-based authentication --- ChangeLog | 3 + NEWS | 4 ++ README | 12 +++- configure.ac | 4 +- doc/afclient.1 | 7 ++- doc/afclient.conf.5 | 7 ++- doc/afclient_example.conf | 1 + doc/afserver.1 | 12 +++- doc/afserver.conf.5 | 12 +++- doc/afserver_example.conf | 5 +- doc/en/README | 12 +++- src/activefor.h | 2 +- src/afclient.c | 23 +++++++- src/afserver.c | 56 ++++++++++++++++-- src/client_configuration_struct.c | 38 ++++++++++++ src/client_configuration_struct.h | 3 + src/file_client.c | 3 + src/file_server.c | 6 ++ src/server_configuration_struct.c | 119 ++++++++++++++++++++++++++++++++++++++ src/server_configuration_struct.h | 12 ++++ src/usage.c | 7 ++- 21 files changed, 323 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c952a2..2cbe382 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +03.10.2007 (v0.8.4): + - Added (by Joshua Judson Rosen): certificate-based authentication + 21.11.2006 (v0.8.3): - Fixed: bug in udp_listen function when AF_INET6 is not defined diff --git a/NEWS b/NEWS index f566ebb..463bc0a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +03.10.2007: + * Joshua Judson Rosen has added certificate-based authentication + to APF + 16.03.2006: * configure and other scripts have been updated diff --git a/README b/README index 11b080e..e9f5b20 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -AF - Active Port Forwarder 0.8.3 - README +AF - Active Port Forwarder 0.8.4 - README Copyright (C) 2003-2007 jeremian - ================================================================= @@ -130,7 +130,10 @@ Multiple clients allow to create more sophisticated tunneling scheme. Configuration: -c, --cerfile - the name of the file with certificate - (default: cacert.pem) + (default: server-cert.pem) + -A, --cacerfile - the name of the file with CA certificates + (if used, require clients to have valid certificates) + -d, --cerdepth - the maximum depth of valid certificate-chains -k, --keyfile - the name of the file with RSA key (default: server.rsa) -f, --cfgfile - the name of the file with the configuration for the active forwarder (server) @@ -211,6 +214,8 @@ Multiple clients allow to create more sophisticated tunneling scheme. Configuration: -k, --keyfile - the name of the file with RSA key (default: client.rsa) + -c, --cerfile - the name of the file with certificate + (default: no certificate used) -f, --cfgfile - the name of the file with the configuration for the active forwarder (client) -s, --storefile - the name of the file with stored public keys @@ -662,6 +667,9 @@ README file. Thanks to Marco Solari for a lot of requests, suggestions and ideas. + Thanks to Joshua Judson Rosen for the patch adding +certificate-based authentication to the APF. + And thanks for using this software! LICENSE diff --git a/configure.ac b/configure.ac index ce850ea..5e63907 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([Active port forwarder], [0.8.3], [jeremian@poczta.fm], [apf]) -AM_INIT_AUTOMAKE([apf], [0.8.3]) +AC_INIT([Active port forwarder], [0.8.4], [jeremian@poczta.fm], [apf]) +AM_INIT_AUTOMAKE([apf], [0.8.4]) AC_COPYRIGHT([ Copyright (C) 2003-2007 jeremian - =================== diff --git a/doc/afclient.1 b/doc/afclient.1 index 3e3bebf..677ec7a 100644 --- a/doc/afclient.1 +++ b/doc/afclient.1 @@ -1,4 +1,4 @@ -.TH afclient 1 "apf 0.8.3" Jeremian +.TH afclient 1 "apf 0.8.4" Jeremian .SH NAME afclient \- active port forwarder client .SH SYNOPSIS @@ -72,6 +72,9 @@ is running (required) .B -k, --keyfile FILE the name of the file with RSA key (default: client.rsa) +.B -c, --cerfile + the name of the file with certificate (default: no certificate used) + .B -f, --cfgfile FILE the name of the file with the configuration for the .I afclient @@ -334,7 +337,7 @@ Jeremian .SH CONTRIBUTIONS -Alex Dyatlov , Simon , Ilia Perevezentsev and Marco Solari +Alex Dyatlov , Simon , Ilia Perevezentsev , Marco Solari , and Joshua Judson Rosen .SH LICENSE diff --git a/doc/afclient.conf.5 b/doc/afclient.conf.5 index a343d11..4f8a5c6 100644 --- a/doc/afclient.conf.5 +++ b/doc/afclient.conf.5 @@ -1,4 +1,4 @@ -.TH afclient.conf 5 "apf 0.8.3" Jeremian +.TH afclient.conf 5 "apf 0.8.4" Jeremian .SH NAME afclient.conf \- Configuration File for afclient .SH INTRODUCTION @@ -67,6 +67,9 @@ is running .B keyfile FILE the name of the file with RSA key (default: client.rsa) +.B cerfile FILE + the name of the file with certificate (default: no certificate used) + .B storefile FILE the name of the file with stored public keys (default: known_hosts) @@ -142,7 +145,7 @@ Jeremian .SH CONTRIBUTIONS -Alex Dyatlov , Simon , Ilia Perevezentsev and Marco Solari +Alex Dyatlov , Simon , Ilia Perevezentsev , Marco Solari , and Joshua Judson Rosen .SH LICENSE diff --git a/doc/afclient_example.conf b/doc/afclient_example.conf index 45b2556..d336ce3 100644 --- a/doc/afclient_example.conf +++ b/doc/afclient_example.conf @@ -15,6 +15,7 @@ #ignorepkeys #ignore invalid server's public keys #keyfile client.rsa #the name of the file with RSA key (default: client.rsa) +#cerfile filename #the name of the file with certificate (default: no certificate used) #storefile known_hosts #the name of the file with stored public keys (default: known_hosts) #dateformat %Y-%m-%d %H:%M:%S #format of the date printed in logs (default: %Y-%m-%d %H:%M:%S) #keep-alive 15 #send keepalive packets every N seconds (default: not send keepalive packets) diff --git a/doc/afserver.1 b/doc/afserver.1 index 3e41af3..887d79b 100644 --- a/doc/afserver.1 +++ b/doc/afserver.1 @@ -1,4 +1,4 @@ -.TH afserver 1 "apf 0.8.3" Jeremian +.TH afserver 1 "apf 0.8.4" Jeremian .SH NAME afserver \- active port forwarder server .SH SYNOPSIS @@ -51,7 +51,13 @@ connects to it (default: 50126) .I Configuration .B -c, --cerfile FILE - the name of the file with certificate (default: cacert.pem) + the name of the file with certificate (default: server-cert.pem) + +.B -A, --cacerfile FILE + the name of the file with CA certificates (if used, require clients to have valid certificates) + +.B -d, --cerdepth + the maximum depth of valid certificate-chains .B -k, --keyfile FILE the name of the file with RSA key (default: server.rsa) @@ -236,7 +242,7 @@ Jeremian .SH CONTRIBUTIONS -Alex Dyatlov , Simon , Ilia Perevezentsev and Marco Solari +Alex Dyatlov , Simon , Ilia Perevezentsev Marco Solari , and Joshua Judson Rosen .SH LICENSE diff --git a/doc/afserver.conf.5 b/doc/afserver.conf.5 index 36f8fca..c62e105 100644 --- a/doc/afserver.conf.5 +++ b/doc/afserver.conf.5 @@ -1,4 +1,4 @@ -.TH afserver.conf 5 "apf 0.8.3" Jeremian +.TH afserver.conf 5 "apf 0.8.4" Jeremian .SH NAME afserver.conf \- Configuration File for afserver .SH INTRODUCTION @@ -35,7 +35,13 @@ commands. .SH "GLOBAL OPTIONS" .B cerfile FILE - the name of the file with certificate (default: cacert.pem) + the name of the file with certificate (default: server-cert.pem) + +.B cacerfile FILE + the name of the file with CA certificates (if used, require clients to have valid certificates) + +.B cerdepth N + the maximum depth of valid certificate-chains .B keyfile FILE the name of the file with RSA key (default: server.rsa) @@ -125,7 +131,7 @@ Jeremian .SH CONTRIBUTIONS -Alex Dyatlov , Simon , Ilia Perevezentsev and Marco Solari +Alex Dyatlov , Simon , Ilia Perevezentsev , Marco Solari , and Joshua Judson Rosen .SH LICENSE diff --git a/doc/afserver_example.conf b/doc/afserver_example.conf index a11f5c1..8bdafa6 100644 --- a/doc/afserver_example.conf +++ b/doc/afserver_example.conf @@ -1,7 +1,7 @@ # This is an example configuration file for active port forwarder (server) # Firstly, we have to declare our files with key and certificate -cerfile cacert.pem +cerfile server-cert.pem # Please note, that we can place only blank characters between words @@ -47,6 +47,9 @@ manageport 50126 #portnumber on which server is listening for afclient #ipv4 #use ipv4 only #ipv6 #use ipv6 only #enableproxy #enable http proxy mode +#cacerfile filename #the name of the file with CA certificates + # (if used, require clients to have valid certificates) +#cerdepth #the maximum depth of valid certificate-chains # and now the second realm diff --git a/doc/en/README b/doc/en/README index 11b080e..e9f5b20 100644 --- a/doc/en/README +++ b/doc/en/README @@ -1,4 +1,4 @@ -AF - Active Port Forwarder 0.8.3 - README +AF - Active Port Forwarder 0.8.4 - README Copyright (C) 2003-2007 jeremian - ================================================================= @@ -130,7 +130,10 @@ Multiple clients allow to create more sophisticated tunneling scheme. Configuration: -c, --cerfile - the name of the file with certificate - (default: cacert.pem) + (default: server-cert.pem) + -A, --cacerfile - the name of the file with CA certificates + (if used, require clients to have valid certificates) + -d, --cerdepth - the maximum depth of valid certificate-chains -k, --keyfile - the name of the file with RSA key (default: server.rsa) -f, --cfgfile - the name of the file with the configuration for the active forwarder (server) @@ -211,6 +214,8 @@ Multiple clients allow to create more sophisticated tunneling scheme. Configuration: -k, --keyfile - the name of the file with RSA key (default: client.rsa) + -c, --cerfile - the name of the file with certificate + (default: no certificate used) -f, --cfgfile - the name of the file with the configuration for the active forwarder (client) -s, --storefile - the name of the file with stored public keys @@ -662,6 +667,9 @@ README file. Thanks to Marco Solari for a lot of requests, suggestions and ideas. + Thanks to Joshua Judson Rosen for the patch adding +certificate-based authentication to the APF. + And thanks for using this software! LICENSE diff --git a/src/activefor.h b/src/activefor.h index 294421e..6a73c69 100644 --- a/src/activefor.h +++ b/src/activefor.h @@ -53,7 +53,7 @@ #define S_STATE_OPENING_CLOSED 17 #define S_STATE_KICKING 19 -#define AF_VER(info) info" v0.8.3" +#define AF_VER(info) info" v0.8.4" #define TYPE_TCP 1 #define TYPE_UDP 3 diff --git a/src/afclient.c b/src/afclient.c index 2963aef..fbafcc1 100644 --- a/src/afclient.c +++ b/src/afclient.c @@ -32,6 +32,7 @@ static struct option long_options[] = { {"portnum", 1, 0, 'p'}, {"verbose", 0, 0, 'v'}, {"keyfile", 1, 0, 'k'}, + {"cerfile", 1, 0, 'c'}, {"storefile", 1, 0, 's'}, {"cfgfile", 1, 0, 'f'}, {"log", 1, 0, 'o'}, @@ -107,6 +108,7 @@ main(int argc, char **argv) char* localPort = NULL; char* localDestinationName = NULL; char* keys = NULL; + char* certif = NULL; char* store = NULL; char* dateformat = NULL; char* kaTimeout = NULL; @@ -180,7 +182,7 @@ main(int argc, char **argv) while ((n = getopt_long(argc, argv, GETOPT_LONG_LIBDL(GETOPT_LONG_LIBPTHREAD( - GETOPT_LONG_AF_INET6("huUn:m:d:p:vk:s:o:i:D:rP:X:VK:A:T:f:"))) + GETOPT_LONG_AF_INET6("huUn:m:d:p:vk:c:s:o:i:D:rP:X:VK:A:T:f:"))) , long_options, 0)) != -1) { switch (n) { case 'h': { @@ -250,6 +252,10 @@ main(int argc, char **argv) keys = optarg; break; } + case 'c': { + certif = optarg; + break; + } case 's': { store = optarg; break; @@ -385,6 +391,9 @@ main(int argc, char **argv) else { ClientConfiguration_set_keysFile(cconfig, keys); } + if (certif != NULL) { + ClientConfiguration_set_certificateFile(cconfig, certif); + } if (store == NULL) { if (ClientConfiguration_get_storeFile(cconfig) == NULL) { ClientConfiguration_set_storeFile(cconfig, "known_hosts"); @@ -486,6 +495,7 @@ main(int argc, char **argv) exit(1); } ClientConfiguration_set_keysFile(cconfig, keys); + ClientConfiguration_set_certificateFile(cconfig, certif); ClientConfiguration_set_storeFile(cconfig, store); ClientConfiguration_set_dateFormat(cconfig, dateformat); ClientConfiguration_set_realmsNumber(cconfig, 1); @@ -695,7 +705,16 @@ main(int argc, char **argv) "Setting rsa key failed (%s)... exiting", keys); exit(1); } - + + certif = ClientConfiguration_get_certificateFile(cconfig); + if (certif) { + if (SSL_CTX_use_certificate_file(ctx, certif, SSL_FILETYPE_PEM) != 1) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Setting certificate failed (%s)... exiting", certif); + exit(1); + } + } + if ((ClientRealm_get_clientMode(pointer) != CLIENTREALM_MODE_REMOTE) && (!verbose)) daemon(0, 0); diff --git a/src/afserver.c b/src/afserver.c index c87ce9c..f509404 100644 --- a/src/afserver.c +++ b/src/afserver.c @@ -37,6 +37,8 @@ static struct option long_options[] = { {"usrpcli", 1, 0, 'U'}, {"climode", 1, 0, 'M'}, {"cerfile", 1, 0, 'c'}, + {"cacerfile", 1, 0, 'A'}, + {"cerdepth", 1, 0, 'd'}, {"keyfile", 1, 0, 'k'}, {"cfgfile", 1, 0, 'f'}, {"proto", 1, 0, 'p'}, @@ -110,6 +112,8 @@ main(int argc, char **argv) ConnectClient** srRaClientsTable; char* certif = NULL; + char* cacertif = NULL; + char* cerdepth = NULL; char* keys = NULL; char* dateformat = NULL; static char* stemp = NULL; @@ -150,7 +154,7 @@ main(int argc, char **argv) #endif while ((n = getopt_long(argc, argv, - GETOPT_LONG_LIBPTHREAD(GETOPT_LONG_AF_INET6("hn:l:m:vu:c:k:f:p:o:t:C:U:M:abD:R:r:V")) + GETOPT_LONG_LIBPTHREAD(GETOPT_LONG_AF_INET6("hn:l:m:vu:c:A:d:k:f:p:o:t:C:U:M:abD:R:r:V")) , long_options, 0)) != -1) { switch (n) { case 'h': { @@ -213,6 +217,14 @@ main(int argc, char **argv) certif = optarg; break; } + case 'A': { + cacertif = optarg; + break; + } + case 'd': { + cerdepth = optarg; + break; + } case 'k': { keys = optarg; break; @@ -331,12 +343,18 @@ main(int argc, char **argv) else { if (certif == NULL) { if (ServerConfiguration_get_certificateFile(config) == NULL) { - ServerConfiguration_set_certificateFile(config, "cacert.pem"); + ServerConfiguration_set_certificateFile(config, "server-cert.pem"); } } else { ServerConfiguration_set_certificateFile(config, certif); } + if (cacertif != NULL) { + ServerConfiguration_set_cacertificateFile(config, cacertif); + } + if (cerdepth != NULL) { + ServerConfiguration_set_sCertificateDepth(config, cerdepth); + } if (keys == NULL) { if (ServerConfiguration_get_keysFile(config) == NULL) { ServerConfiguration_set_keysFile(config, "server.rsa"); @@ -377,6 +395,8 @@ main(int argc, char **argv) exit(1); } ServerConfiguration_set_certificateFile(config, certif); + ServerConfiguration_set_cacertificateFile(config, cacertif); + ServerConfiguration_set_sCertificateDepth(config, cerdepth); ServerConfiguration_set_keysFile(config, keys); ServerConfiguration_set_dateFormat(config, dateformat); @@ -398,7 +418,7 @@ main(int argc, char **argv) exit(1); } if (ServerConfiguration_get_certificateFile(config) == NULL) { - ServerConfiguration_set_certificateFile(config, "cacert.pem"); + ServerConfiguration_set_certificateFile(config, "server-cert.pem"); } if (ServerConfiguration_get_keysFile(config) == NULL) { ServerConfiguration_set_keysFile(config, "server.rsa"); @@ -533,6 +553,29 @@ main(int argc, char **argv) "Setting certificate failed (%s)... exiting", ServerConfiguration_get_certificateFile(config)); exit(1); } + + cacertif = ServerConfiguration_get_cacertificateFile(config); + if (cacertif) { + if (SSL_CTX_load_verify_locations(ctx, + cacertif, + NULL) + != 1) + { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Setting CA certificate failed (%s)... exiting", cacertif); + exit(1); + } + + SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + NULL); + + cerdepth = ServerConfiguration_get_sCertificateDepth (config); + if (cerdepth == NULL) { + cerdepth = "9"; + } + SSL_CTX_set_verify_depth(ctx, check_value_liberal (cerdepth, "Invalid max certificate-depth")); + } + if (ServerConfiguration_get_realmsNumber(config) == 0) { aflog(LOG_T_INIT, LOG_I_CRIT, "Working without sense is really without sense..."); @@ -1393,7 +1436,12 @@ main(int argc, char **argv) case 2: { close(SslFd_get_fd(ConnectClient_get_sslFd(srClientsTable[k]))); FD_CLR(SslFd_get_fd(ConnectClient_get_sslFd(srClientsTable[k])), &allset); - SSL_clear(SslFd_get_ssl(ConnectClient_get_sslFd(srClientsTable[k]))); + + /* This SSL-object is busted; don't reuse it + (SSL_clear isn't sufficient because ssl->new_session is set): */ + SslFd_set_ssl(ConnectClient_get_sslFd(srClientsTable[k]), + SSL_new (ctx)); + ConnectClient_set_state(srClientsTable[k], CONNECTCLIENT_STATE_FREE); if ((task = ConnectClient_get_task(srClientsTable[k]))) { TaskScheduler_removeTask(scheduler, task); diff --git a/src/client_configuration_struct.c b/src/client_configuration_struct.c index dbf14f8..6edb6f1 100644 --- a/src/client_configuration_struct.c +++ b/src/client_configuration_struct.c @@ -66,6 +66,10 @@ ClientConfiguration_free(ClientConfiguration** cc) free((*cc)->keysFile); (*cc)->keysFile = NULL; } + if ((*cc)->certificateFile) { + free((*cc)->certificateFile); + (*cc)->certificateFile = NULL; + } if ((*cc)->storeFile) { free((*cc)->storeFile); (*cc)->storeFile = NULL; @@ -101,6 +105,23 @@ ClientConfiguration_set_keysFile(ClientConfiguration* cc, char* keysFile) } /* + * Function name: ClientConfiguration_set_certificateFile + * Description: Set certs filename. + * Arguments: cc - pointer to ClientConfiguration structure + * certificateFile - certs filename + */ + +void +ClientConfiguration_set_certificateFile(ClientConfiguration* cc, char* certificateFile) +{ + assert(cc != NULL); + if (cc == NULL) { + return; + } + string_cp(&(cc->certificateFile), certificateFile); +} + +/* * Function name: ClientConfiguration_set_storeFile * Description: Set store filename. * Arguments: cc - pointer to ClientConfiguration structure @@ -213,6 +234,23 @@ ClientConfiguration_get_keysFile(ClientConfiguration* cc) } /* + * Function name: ClientConfiguration_get_certificateFile + * Description: Get certs filename. + * Arguments: cc - pointer to ClientConfiguration structure + * Returns: Certs filename. + */ + +char* +ClientConfiguration_get_certificateFile(ClientConfiguration* cc) +{ + assert(cc != NULL); + if (cc == NULL) { + return NULL; + } + return cc->certificateFile; +} + +/* * Function name: ClientConfiguration_get_storeFile * Description: Get store filename. * Arguments: cc - pointer to ClientConfiguration structure diff --git a/src/client_configuration_struct.h b/src/client_configuration_struct.h index 4c28b36..15e590d 100644 --- a/src/client_configuration_struct.h +++ b/src/client_configuration_struct.h @@ -26,6 +26,7 @@ typedef struct { char* keysFile; + char* certificateFile; char* storeFile; char* dateFormat; int realmsNumber; @@ -39,6 +40,7 @@ ClientConfiguration* ClientConfiguration_new(); void ClientConfiguration_free(ClientConfiguration** cc); /* setters */ void ClientConfiguration_set_keysFile(ClientConfiguration* cc, char* keysFile); +void ClientConfiguration_set_certificateFile(ClientConfiguration* cc, char* certificateFile); void ClientConfiguration_set_storeFile(ClientConfiguration* cc, char* storeFile); void ClientConfiguration_set_dateFormat(ClientConfiguration* cc, char* dateFormat); void ClientConfiguration_set_realmsNumber(ClientConfiguration* cc, int realmsNumber); @@ -46,6 +48,7 @@ void ClientConfiguration_set_realmsTable(ClientConfiguration* cc, ClientRealm** void ClientConfiguration_set_ignorePublicKeys(ClientConfiguration* cc, char ignorePublicKeys); /* getters */ char* ClientConfiguration_get_keysFile(ClientConfiguration* cc); +char* ClientConfiguration_get_certificateFile(ClientConfiguration* cc); char* ClientConfiguration_get_storeFile(ClientConfiguration* cc); char* ClientConfiguration_get_dateFormat(ClientConfiguration* cc); int ClientConfiguration_get_realmsNumber(ClientConfiguration* cc); diff --git a/src/file_client.c b/src/file_client.c index 13e26f5..672eeaf 100644 --- a/src/file_client.c +++ b/src/file_client.c @@ -197,6 +197,9 @@ cparsefile(char* name, int* status) if ((strcmp(helpbuf1, "k") == 0) || (strcmp(helpbuf1, "keyfile") == 0)) { ClientConfiguration_set_keysFile(cfg, helpbuf2); } + else if ((strcmp(helpbuf1, "c") == 0) || (strcmp(helpbuf1, "certificate") == 0) || (strcmp(helpbuf1, "cerfile") == 0)) { + ClientConfiguration_set_certificateFile(cfg, helpbuf2); + } else if ((strcmp(helpbuf1, "s") == 0) || (strcmp(helpbuf1, "storefile") == 0)) { ClientConfiguration_set_storeFile(cfg, helpbuf2); } diff --git a/src/file_server.c b/src/file_server.c index e199d43..3abfc57 100644 --- a/src/file_server.c +++ b/src/file_server.c @@ -269,6 +269,12 @@ parsefile(char* name, int* status) else if ((strcmp(helpbuf1, "certificate") == 0) || (strcmp(helpbuf1, "cerfile") == 0)) { ServerConfiguration_set_certificateFile(cfg, helpbuf2); } + else if (strcmp(helpbuf1, "cacerfile") == 0) { + ServerConfiguration_set_cacertificateFile(cfg, helpbuf2); + } + else if (strcmp(helpbuf1, "cerdepth") == 0) { + ServerConfiguration_set_sCertificateDepth(cfg, helpbuf2); + } else if ((strcmp(helpbuf1, "key") == 0) || (strcmp(helpbuf1, "keyfile") == 0)) { ServerConfiguration_set_keysFile(cfg, helpbuf2); } diff --git a/src/server_configuration_struct.c b/src/server_configuration_struct.c index 9170a0c..7f88275 100644 --- a/src/server_configuration_struct.c +++ b/src/server_configuration_struct.c @@ -66,6 +66,18 @@ ServerConfiguration_free(ServerConfiguration** sc) free((*sc)->certificateFile); (*sc)->certificateFile = NULL; } + if ((*sc)->cacertificateFile) { + free((*sc)->cacertificateFile); + (*sc)->cacertificateFile = NULL; + } + if ((*sc)->cacertificatePath) { + free((*sc)->cacertificatePath); + (*sc)->cacertificatePath = NULL; + } + if ((*sc)->sCertificateDepth) { + free((*sc)->sCertificateDepth); + (*sc)->sCertificateDepth = NULL; + } if ((*sc)->keysFile) { free((*sc)->keysFile); (*sc)->keysFile = NULL; @@ -105,6 +117,59 @@ ServerConfiguration_set_certificateFile(ServerConfiguration* sc, char* certifica } /* + * Function name: ServerConfiguration_set_cacertificateFile + * Description: Set CA certificate filename. + * Arguments: sc - pointer to ServerConfiguration structure + * certificateFile - CA certificate filename + */ + +void +ServerConfiguration_set_cacertificateFile(ServerConfiguration* sc, char* cacertificateFile) +{ + assert(sc != NULL); + if (sc == NULL) { + return; + } + string_cp(&(sc->cacertificateFile), cacertificateFile); +} + +/* + * Function name: ServerConfiguration_set_cacertificatePath + * Description: Set CA certificate filename. + * Arguments: sc - pointer to ServerConfiguration structure + * cacertificateFile - CA certificate path + */ + +void +ServerConfiguration_set_cacertificatePath(ServerConfiguration* sc, char* cacertificatePath) +{ + assert(sc != NULL); + if (sc == NULL) { + return; + } + string_cp(&(sc->cacertificatePath), cacertificatePath); +} + +void +ServerConfiguration_set_sCertificateDepth(ServerConfiguration* sc, char* sCertificateDepth) +{ + assert(sc != NULL); + if (sc == NULL) { + return; + } + string_cp(&(sc->sCertificateDepth), sCertificateDepth); +} +void +ServerConfiguration_set_certificateDepth(ServerConfiguration* sc, int certificateDepth) +{ + assert(sc != NULL); + if (sc == NULL) { + return; + } + sc->certificateDepth = certificateDepth; +} + +/* * Function name: ServerConfiguration_set_keysFile * Description: Set keys filename. * Arguments: sc - pointer to ServerConfiguration structure @@ -217,6 +282,60 @@ ServerConfiguration_get_certificateFile(ServerConfiguration* sc) } /* + * Function name: ServerConfiguration_get_cacertificateFile + * Description: Get CA certificate filename. + * Arguments: sc - pointer to ServerConfiguration structure + * Returns: CA Certificate filename. + */ + +char* +ServerConfiguration_get_cacertificateFile(ServerConfiguration* sc) +{ + assert(sc != NULL); + if (sc == NULL) { + return NULL; + } + return sc->cacertificateFile; +} + +/* + * Function name: ServerConfiguration_get_cacertificatePath + * Description: Get CA certificate path + * Arguments: sc - pointer to ServerConfiguration structure + * Returns: CA Certificate path. + */ + +char* +ServerConfiguration_get_cacertificatePath(ServerConfiguration* sc) +{ + assert(sc != NULL); + if (sc == NULL) { + return NULL; + } + return sc->cacertificatePath; +} + +char* +ServerConfiguration_get_sCertificateDepth(ServerConfiguration* sc) +{ + assert(sc != NULL); + if (sc == NULL) { + return NULL; + } + return sc->sCertificateDepth; +} + +int +ServerConfiguration_get_certificateDepth(ServerConfiguration* sc) +{ + assert(sc != NULL); + if (sc == NULL) { + return -1; + } + return sc->certificateDepth; +} + +/* * Function name: ServerConfiguration_get_keysFile * Description: Get keys filename. * Arguments: sc - pointer to ServerConfiguration structure diff --git a/src/server_configuration_struct.h b/src/server_configuration_struct.h index b302f53..caf7a9e 100644 --- a/src/server_configuration_struct.h +++ b/src/server_configuration_struct.h @@ -25,6 +25,10 @@ #include "server_realm_struct.h" typedef struct { + char* cacertificateFile; + char* cacertificatePath; + char* sCertificateDepth; + int certificateDepth; char* certificateFile; char* keysFile; char* dateFormat; @@ -39,6 +43,10 @@ ServerConfiguration* ServerConfiguration_new(); void ServerConfiguration_free(ServerConfiguration** sc); /* setters */ void ServerConfiguration_set_certificateFile(ServerConfiguration* sc, char* certificateFile); +void ServerConfiguration_set_cacertificateFile(ServerConfiguration* sc, char* cacertificateFile); +void ServerConfiguration_set_cacertificatePath(ServerConfiguration* sc, char* cacertificatePath); +void ServerConfiguration_set_sCertificateDepth(ServerConfiguration* sc, char* sCertificateDepth); +void ServerConfiguration_set_certificateDepth(ServerConfiguration* sc, int certificateDepth); void ServerConfiguration_set_keysFile(ServerConfiguration* sc, char* keysFile); void ServerConfiguration_set_dateFormat(ServerConfiguration* sc, char* dateFormat); void ServerConfiguration_set_realmsNumber(ServerConfiguration* sc, int realmsNumber); @@ -46,6 +54,10 @@ void ServerConfiguration_set_startTime(ServerConfiguration* sc, time_t startTime void ServerConfiguration_set_realmsTable(ServerConfiguration* sc, ServerRealm** realmsTable); /* getters */ char* ServerConfiguration_get_certificateFile(ServerConfiguration* sc); +char* ServerConfiguration_get_cacertificateFile(ServerConfiguration* sc); +char* ServerConfiguration_get_cacertificatePath(ServerConfiguration* sc); +char* ServerConfiguration_get_sCertificateDepth(ServerConfiguration* sc); +int ServerConfiguration_get_certificateDepth(ServerConfiguration* sc); char* ServerConfiguration_get_keysFile(ServerConfiguration* sc); char* ServerConfiguration_get_dateFormat(ServerConfiguration* sc); int ServerConfiguration_get_realmsNumber(ServerConfiguration* sc); diff --git a/src/usage.c b/src/usage.c index e3cfeff..08a85b8 100644 --- a/src/usage.c +++ b/src/usage.c @@ -67,7 +67,10 @@ server_long_usage(char* info) printf(" (default: no password)\n\n"); printf(" Configuration:\n\n"); printf(" -c, --cerfile - the name of the file with certificate\n"); - printf(" (default: cacert.pem)\n"); + printf(" (default: server-cert.pem)\n"); + printf(" -A, --cacerfile - the name of the file with CA certificates\n"); + printf(" (if used, require clients to have valid certificates)\n"); + printf(" -d, --cerdepth - the maximum depth of valid certificate-chains\n"); printf(" -k, --keyfile - the name of the file with RSA key (default: server.rsa)\n"); printf(" -f, --cfgfile - the name of the file with the configuration for the\n"); printf(" active forwarder (server)\n"); @@ -170,6 +173,8 @@ client_long_usage(char* info) printf(" --ignorepkeys - ignore invalid server's public keys\n\n"); printf(" Configuration:\n\n"); printf(" -k, --keyfile - the name of the file with RSA key (default: client.rsa)\n"); + printf(" -c, --cerfile - the name of the file with certificate\n"); + printf(" (default: no certificate used)\n"); printf(" -f, --cfgfile - the name of the file with the configuration for the\n"); printf(" active forwarder (client)\n"); printf(" -s, --storefile - the name of the file with stored public keys\n"); -- cgit v1.1