From fe9bda8d2aad33e0f71d5699bcf90fb78b3fb5bb Mon Sep 17 00:00:00 2001 From: Joshua Judson Rosen Date: Tue, 18 Nov 2014 23:16:55 -0500 Subject: afserver: support per-realm CA-certificate settings This makes it possible to have different CA certificates for different realms, or certificate auth for only some realms and password auth for others. --- src/afserver.c | 119 ++++++++++++++++------------- src/file_server.c | 8 +- src/server_configuration_struct.c | 119 ----------------------------- src/server_configuration_struct.h | 12 --- src/server_realm_struct.c | 153 ++++++++++++++++++++++++++++++++++++++ src/server_realm_struct.h | 15 ++++ 6 files changed, 241 insertions(+), 185 deletions(-) diff --git a/src/afserver.c b/src/afserver.c index 1e7c9d2..461f476 100644 --- a/src/afserver.c +++ b/src/afserver.c @@ -119,7 +119,6 @@ main(int argc, char **argv) static char* stemp = NULL; const SSL_METHOD* method; - SSL_CTX* ctx; SSL* tmp_ssl; sigfillset(&(act.sa_mask)); @@ -349,12 +348,6 @@ main(int argc, char **argv) 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"); @@ -395,8 +388,6 @@ 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); @@ -475,6 +466,9 @@ main(int argc, char **argv) ServerRealm_set_dnsLookupsOn(pointer, dnslookups); ServerRealm_set_realmName(pointer, realmname); ServerRealm_set_password(pointer, pass); + ServerRealm_set_cacertificateFile(pointer, cacertif); + ServerRealm_set_sCertificateDepth(pointer, cerdepth); + if (strcmp(type, "tcp") == 0) { temp = ServerRealm_get_realmType(pointer); TYPE_SET_TCP(temp); @@ -524,13 +518,7 @@ main(int argc, char **argv) the latest APF/OpenSSL versions used on the server. */ method = SSLv23_server_method(); - ctx = SSL_CTX_new(method); - if (SSL_CTX_set_cipher_list(ctx, "ALL:@STRENGTH") == 0) { - aflog(LOG_T_INIT, LOG_I_CRIT, - "Setting ciphers list failed... exiting"); - exit(1); - } if ((flags = create_apf_dir(0))) { aflog(LOG_T_INIT, LOG_I_WARNING, "Warning: Creating ~/.apf directory failed (%d)", flags); @@ -545,45 +533,12 @@ main(int argc, char **argv) "Warning: Something bad happened when generating rsa keys... (%d)", flags); } ServerConfiguration_set_keysFile(config, keys); - if (SSL_CTX_use_RSAPrivateKey_file(ctx, ServerConfiguration_get_keysFile(config), SSL_FILETYPE_PEM) != 1) { - aflog(LOG_T_INIT, LOG_I_CRIT, - "Setting rsa key failed (%s)... exiting", ServerConfiguration_get_keysFile(config)); - exit(1); - } certif = ServerConfiguration_get_certificateFile(config); if ((flags = generate_certificate(&certif, ServerConfiguration_get_keysFile(config)))) { aflog(LOG_T_INIT, LOG_I_WARNING, "Warning: Something bad happened when generating certificate... (%d)", flags); } ServerConfiguration_set_certificateFile(config, certif); - if (SSL_CTX_use_certificate_file(ctx, - ServerConfiguration_get_certificateFile(config), SSL_FILETYPE_PEM) != 1) { - aflog(LOG_T_INIT, LOG_I_CRIT, - "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, @@ -622,6 +577,64 @@ main(int argc, char **argv) exit(1); } } + + + /* Set up an SSL context for this realm, which may or may not use + a realm-specific CA to authenticate clients: + */ + ServerRealm_set_SslCtx(scRealmsTable[i], SSL_CTX_new(method)); + if (SSL_CTX_set_cipher_list(ServerRealm_get_SslCtx (scRealmsTable[i]), + "ALL:@STRENGTH") + == 0) + { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Setting ciphers list failed... exiting"); + exit(1); + } + + if (SSL_CTX_use_RSAPrivateKey_file(ServerRealm_get_SslCtx (scRealmsTable[i]), + ServerConfiguration_get_keysFile(config), + SSL_FILETYPE_PEM) + != 1) + { + aflog(LOG_T_INIT, LOG_I_CRIT, "Setting rsa key failed (%s)... exiting", + ServerConfiguration_get_keysFile(config)); + exit(1); + } + if (SSL_CTX_use_certificate_file(ServerRealm_get_SslCtx (scRealmsTable[i]), + ServerConfiguration_get_certificateFile(config), + SSL_FILETYPE_PEM) + != 1) + { + aflog(LOG_T_INIT, LOG_I_CRIT, "Setting certificate failed (%s)... exiting", + ServerConfiguration_get_certificateFile(config)); + exit(1); + } + + cacertif = ServerRealm_get_cacertificateFile(scRealmsTable[i]); + if (cacertif) { + if (SSL_CTX_load_verify_locations(ServerRealm_get_SslCtx (scRealmsTable[i]), + cacertif, NULL) + != 1) + { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Setting CA certificate failed (%s)... exiting", cacertif); + exit(1); + } + + SSL_CTX_set_verify (ServerRealm_get_SslCtx (scRealmsTable[i]), + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + NULL); + + cerdepth = ServerRealm_get_sCertificateDepth (scRealmsTable[i]); + if (cerdepth == NULL) { + cerdepth = "9"; + } + SSL_CTX_set_verify_depth(ServerRealm_get_SslCtx (scRealmsTable[i]), + check_value_liberal (cerdepth, "Invalid max certificate-depth")); + } + + /* checking type of the realm */ if (!TYPE_IS_SET(ServerRealm_get_realmType(scRealmsTable[i]))) { if (type != NULL) { @@ -881,7 +894,7 @@ main(int argc, char **argv) ServerRealm_get_clientsLimit(scRealmsTable[i]) + ServerRealm_get_raClientsLimit(scRealmsTable[i]), (ServerRealm_get_tunnelType(scRealmsTable[i]) - 1), - ctx)) { + ServerRealm_get_SslCtx(scRealmsTable[i]))) { aflog(LOG_T_INIT, LOG_I_CRIT, #ifdef AF_INET6 "http%s_proxy_listen_%s error for %s, %s", @@ -925,7 +938,8 @@ main(int argc, char **argv) } for (j = 0; j < ServerRealm_get_clientsLimit(scRealmsTable[i]); ++j) { - SslFd_set_ssl(ConnectClient_get_sslFd(srClientsTable[j]), SSL_new(ctx)); + SslFd_set_ssl(ConnectClient_get_sslFd(srClientsTable[j]), + SSL_new(ServerRealm_get_SslCtx(scRealmsTable[i]))); if (SslFd_get_ssl(ConnectClient_get_sslFd(srClientsTable[j])) == NULL) { aflog(LOG_T_INIT, LOG_I_CRIT, "Creation of ssl object failed... exiting"); @@ -934,7 +948,8 @@ main(int argc, char **argv) } for (j = 0; j < ServerRealm_get_raClientsLimit(scRealmsTable[i]); ++j) { - SslFd_set_ssl(ConnectClient_get_sslFd(srRaClientsTable[j]), SSL_new(ctx)); + SslFd_set_ssl(ConnectClient_get_sslFd(srRaClientsTable[j]), + SSL_new(ServerRealm_get_SslCtx(scRealmsTable[i]))); if (SslFd_get_ssl(ConnectClient_get_sslFd(srRaClientsTable[j])) == NULL) { aflog(LOG_T_INIT, LOG_I_CRIT, "Creation of ssl object failed... exiting"); @@ -1449,7 +1464,7 @@ main(int argc, char **argv) /* 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)); + SSL_new (ServerRealm_get_SslCtx(pointer))); ConnectClient_set_state(srClientsTable[k], CONNECTCLIENT_STATE_FREE); if ((task = ConnectClient_get_task(srClientsTable[k]))) { diff --git a/src/file_server.c b/src/file_server.c index 3abfc57..35ed235 100644 --- a/src/file_server.c +++ b/src/file_server.c @@ -270,10 +270,14 @@ parsefile(char* name, int* status) ServerConfiguration_set_certificateFile(cfg, helpbuf2); } else if (strcmp(helpbuf1, "cacerfile") == 0) { - ServerConfiguration_set_cacertificateFile(cfg, helpbuf2); + ServerRealm_set_cacertificateFile( + ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1], + helpbuf2); } else if (strcmp(helpbuf1, "cerdepth") == 0) { - ServerConfiguration_set_sCertificateDepth(cfg, helpbuf2); + ServerRealm_set_sCertificateDepth( + ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1], + 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 7f88275..9170a0c 100644 --- a/src/server_configuration_struct.c +++ b/src/server_configuration_struct.c @@ -66,18 +66,6 @@ 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; @@ -117,59 +105,6 @@ 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 @@ -282,60 +217,6 @@ 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 caf7a9e..b302f53 100644 --- a/src/server_configuration_struct.h +++ b/src/server_configuration_struct.h @@ -25,10 +25,6 @@ #include "server_realm_struct.h" typedef struct { - char* cacertificateFile; - char* cacertificatePath; - char* sCertificateDepth; - int certificateDepth; char* certificateFile; char* keysFile; char* dateFormat; @@ -43,10 +39,6 @@ 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); @@ -54,10 +46,6 @@ 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/server_realm_struct.c b/src/server_realm_struct.c index c816ae3..4c55245 100644 --- a/src/server_realm_struct.c +++ b/src/server_realm_struct.c @@ -98,6 +98,18 @@ ServerRealm_free(ServerRealm** sr) free((*sr)->realmName); (*sr)->realmName = NULL; } + if ((*sr)->cacertificateFile) { + free((*sr)->cacertificateFile); + (*sr)->cacertificateFile = NULL; + } + if ((*sr)->cacertificatePath) { + free((*sr)->cacertificatePath); + (*sr)->cacertificatePath = NULL; + } + if ((*sr)->sCertificateDepth) { + free((*sr)->sCertificateDepth); + (*sr)->sCertificateDepth = NULL; + } if ((*sr)->clientAddress) { free((*sr)->clientAddress); (*sr)->clientAddress = NULL; @@ -313,6 +325,76 @@ ServerRealm_set_password(ServerRealm* sr, unsigned char* password) } /* + * Function name: ServerRealm_set_SslCtx + * Description: Set SSL context + * Arguments: sr - pointer to ServerRealm structure + * ctx - pointer to SSL_CTX object + */ +void +ServerRealm_set_SslCtx(ServerRealm* sr, SSL_CTX* ctx) +{ + assert(sr != NULL); + if (sr == NULL) { + return; + } + + sr->sslCtx = ctx; +} + +/* + * Function name: ServerRealm_set_cacertificateFile + * Description: Set CA certificate filename. + * Arguments: sr - pointer to ServerRealm structure + * certificateFile - CA certificate filename + */ + +void +ServerRealm_set_cacertificateFile(ServerRealm* sr, char* cacertificateFile) +{ + assert(sr != NULL); + if (sr == NULL) { + return; + } + string_cp(&(sr->cacertificateFile), cacertificateFile); +} + +/* + * Function name: ServerRealm_set_cacertificatePath + * Description: Set CA certificate filename. + * Arguments: sr - pointer to ServerRealm structure + * cacertificateFile - CA certificate path + */ + +void +ServerRealm_set_cacertificatePath(ServerRealm* sr, char* cacertificatePath) +{ + assert(sr != NULL); + if (sr == NULL) { + return; + } + string_cp(&(sr->cacertificatePath), cacertificatePath); +} + +void +ServerRealm_set_sCertificateDepth(ServerRealm* sr, char* sCertificateDepth) +{ + assert(sr != NULL); + if (sr == NULL) { + return; + } + string_cp(&(sr->sCertificateDepth), sCertificateDepth); +} +void +ServerRealm_set_certificateDepth(ServerRealm* sr, int certificateDepth) +{ + assert(sr != NULL); + if (sr == NULL) { + return; + } + sr->certificateDepth = certificateDepth; +} + +/* * Function name: ServerRealm_set_connectedUsers * Description: Set number of connected users. * Arguments: sr - pointer to ServerRealm structure @@ -935,6 +1017,77 @@ ServerRealm_get_password(ServerRealm* sr) } /* + * Function name: ServerRealm_get_SslCtx + * Description: Get SSL context + * Arguments: sr - pointer to ServerRealm structure + * Returns: pointer to SSL_CTX object + */ +SSL_CTX* +ServerRealm_get_SslCtx(ServerRealm* sr) +{ + assert(sr != NULL); + if (sr == NULL) { + return NULL; + } + + return sr->sslCtx; +} + +/* + * Function name: ServerRealm_get_cacertificateFile + * Description: Get CA certificate filename. + * Arguments: sc - pointer to ServerRealm structure + * Returns: CA Certificate filename. + */ + +char* +ServerRealm_get_cacertificateFile(ServerRealm* sr) +{ + assert(sr != NULL); + if (sr == NULL) { + return NULL; + } + return sr->cacertificateFile; +} + +/* + * Function name: ServerRealm_get_cacertificatePath + * Description: Get CA certificate path + * Arguments: sr - pointer to ServerRealm structure + * Returns: CA Certificate path. + */ + +char* +ServerRealm_get_cacertificatePath(ServerRealm* sr) +{ + assert(sr != NULL); + if (sr == NULL) { + return NULL; + } + return sr->cacertificatePath; +} + +char* +ServerRealm_get_sCertificateDepth(ServerRealm* sr) +{ + assert(sr != NULL); + if (sr == NULL) { + return NULL; + } + return sr->sCertificateDepth; +} + +int +ServerRealm_get_certificateDepth(ServerRealm* sr) +{ + assert(sr != NULL); + if (sr == NULL) { + return -1; + } + return sr->certificateDepth; +} + +/* * Function name: ServerRealm_get_connectedUsers * Description: Get number of connected users. * Arguments: sr - pointer to ServerRealm structure diff --git a/src/server_realm_struct.h b/src/server_realm_struct.h index e057c99..cbaa7e6 100644 --- a/src/server_realm_struct.h +++ b/src/server_realm_struct.h @@ -34,6 +34,11 @@ typedef struct { char* sMaxIdle; char* realmName; unsigned char password[4]; + SSL_CTX* sslCtx; + char* cacertificateFile; + char* cacertificatePath; + char* sCertificateDepth; + int certificateDepth; int connectedUsers; int usersLimit; int connectedClients; @@ -75,6 +80,11 @@ void ServerRealm_set_sTimeout(ServerRealm* sr, char* sTimeout); void ServerRealm_set_sMaxIdle(ServerRealm* sr, char* sMaxIdle); void ServerRealm_set_realmName(ServerRealm* sr, char* realmName); void ServerRealm_set_password(ServerRealm* sr, unsigned char* password); +void ServerRealm_set_SslCtx(ServerRealm* sr, SSL_CTX* ctx); +void ServerRealm_set_cacertificateFile(ServerRealm* sr, char* cacertificateFile); +void ServerRealm_set_cacertificatePath(ServerRealm* sr, char* cacertificatePath); +void ServerRealm_set_sCertificateDepth(ServerRealm* sr, char* sCertificateDepth); +void ServerRealm_set_certificateDepth(ServerRealm* sr, int certificateDepth); void ServerRealm_set_connectedUsers(ServerRealm* sr, int connectedUsers); void ServerRealm_set_usersLimit(ServerRealm* sr, int usersLimit); void ServerRealm_set_connectedClients(ServerRealm* sr, int connectedClients); @@ -110,6 +120,11 @@ char* ServerRealm_get_sTimeout(ServerRealm* sr); char* ServerRealm_get_sMaxIdle(ServerRealm* sr); char* ServerRealm_get_realmName(ServerRealm* sr); unsigned char* ServerRealm_get_password(ServerRealm* sr); +SSL_CTX* ServerRealm_get_SslCtx(ServerRealm* sr); +char* ServerRealm_get_cacertificateFile(ServerRealm* sr); +char* ServerRealm_get_cacertificatePath(ServerRealm* sr); +char* ServerRealm_get_sCertificateDepth(ServerRealm* sr); +int ServerRealm_get_certificateDepth(ServerRealm* sr); int ServerRealm_get_connectedUsers(ServerRealm* sr); int ServerRealm_get_usersLimit(ServerRealm* sr); int ServerRealm_get_connectedClients(ServerRealm* sr); -- cgit v1.1