#include "config.h" #include #include /* for close() */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_SYS_TYPES_H #include /* for timeval */ #endif /* HAVE_SYS_TYPES_H */ #include /* SSLeay */ #ifndef NO_SSL #include #include #endif /* !NO_SSL */ #include "common.h" #include "parse.h" #include "Config.h" #ifndef NO_SSL #include "dynassl.h" #endif #include "sig.h" #include "log.h" #include "util.h" #include "servicetype.h" /* ================================================================= */ #define PUTACCESSLOG(body) (alogp ? alogp->put body,0 : 0) #define SADDRBUF 64 /* ================================================================= */ #ifndef NO_SSL int BjorbSSLVerifyCallback(int ok, X509_STORE_CTX *ctx); static RSA *rsa_tmp = 0; #endif /* !NO_SSL */ /* ================================================================= */ /* ================================================================= */ #ifndef NO_SSL /* ----------------------------------------------------------------- * =NAME= PUTSSLERR - output SSL error strings * ----------------------------------------------------------------- */ void Config::PUTSSLERR() { FILE *fp = elogp->fp; char buf[200]; unsigned long err; while (err = _ERR_get_error(), err) { PUTERR(0, ("%s\n", _ERR_error_string(err, buf))); } /* _ERR_print_errors_fp(fp);*/ } #endif /* !NO_SSL */ /* ----------------------------------------------------------------- * =NAME= Config::Config - initialize =SYNOPSIS= Config::Config(char *name = 0) name : servicename * ----------------------------------------------------------------- */ Config::Config(char *name) { parent = next = 0; log_level = -1; read_timeout = -1; max_connection = -1; deny_wait = -1; spare_servers = -1; do_fork = -1; *access_log = *error_log = 0; #ifndef NO_SSL *CA_cert_file = *CA_cert_path = *client_cert_file = 0; CA_X509 = 0; CA_RSA = 0; ctx_accept = ctx_connect = 0; #endif /* !NO_SSL */ service_type = 0; /* */ soc_accept = -1; connectp = 0; alogp = 0; elogp = ::elogp; f_open_access_log = FALSE; f_open_error_log = FALSE; if (name) STRNCPY(servicename, name, 80); else *servicename = 0; } Config::~Config() { } /* ----------------------------------------------------------------- * =NAME= Config::createAcceptSocket =RETURN= TRUE or FALSE * ----------------------------------------------------------------- */ int Config::createAcceptSocket() { int enable = 1; int ret; SOCKADDR_IN *sa = accept_port.getSockAddrIn(); /* If accept interface is 'localhost', accept on 0.0.0.0 */ if (htonl(sa->sin_addr.s_addr) == 0x7f000001l) { sa->sin_addr.s_addr = 0; } /* create socket */ soc_accept = ::socket(PF_INET, SOCK_STREAM, 0); if (soc_accept < 0) { PUTERR(0, ("Can't create socket: %s\n", strerror(errno))); return FALSE; } #if defined(SO_REUSEADDR) setsockopt(soc_accept, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(enable)); #endif /* SO_REUSEADDR */ #if defined(SO_REUSEPORT) setsockopt(soc_accept, SOL_SOCKET, SO_REUSEPORT, (char *)&enable, sizeof(enable)); #endif /* SO_REUSEPORT */ /* bind interface */ ret = ::bind(soc_accept, (struct sockaddr *)sa, sizeof(SOCKADDR_IN)); if (ret < 0) { char buf[SADDRBUF]; PUTERR(0, ("Can't bind to `%s:%d' : %s\n", addr2str(sa->sin_addr.s_addr, buf), ntohs(sa->sin_port), strerror(errno))); } char buf[SADDRBUF]; #ifndef NO_DEBUG PUTERR(2, ("bind to `%s:%d'\n", addr2str(sa->sin_addr.s_addr, buf), ntohs(sa->sin_port))); #endif return TRUE; } /* ----------------------------------------------------------------- * =NAME= Config::createConnectSocket =RETURN= -1 : error else : connected socket * ----------------------------------------------------------------- */ int Config::createConnectSocket() { int enable = 1; int ret; /* create socket */ int ssoc = ::socket(PF_INET, SOCK_STREAM, 0); if (ssoc < 0) { PUTERR(0, ("Can't create socket: %s\n", strerror(errno))); return -1; } #if defined(SO_REUSEADDR) setsockopt(ssoc, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(enable)); #endif /* SO_REUSEADDR */ #if defined(SO_REUSEPORT) setsockopt(ssoc, SOL_SOCKET, SO_REUSEPORT, (char *)&enable, sizeof(enable)); #endif /* SO_REUSEPORT */ SOCKADDR_IN *sa = connectp->getSockAddrIn(); SOCKADDR_IN *sa_from_if = connectp->getSockAddrIn_from_if(); if ( (DWORD*)&sa_from_if->sin_addr.s_addr != 0 ) { ret = ::bind(ssoc, (struct sockaddr *)sa_from_if, sizeof(SOCKADDR_IN)); if (ret < 0) { char buf[SADDRBUF]; PUTERR(0, ("Can't bind to `%s:%d' : %s\n", addr2str(sa_from_if->sin_addr.s_addr, buf), ntohs(sa_from_if->sin_port), strerror(errno))); } char buf[SADDRBUF]; #ifndef NO_DEBUG PUTERR(2, ("bind to `%s:%d'\n", addr2str(sa_from_if->sin_addr.s_addr, buf), ntohs(sa_from_if->sin_port))); #endif } ret = ::connect(ssoc, (SOCKADDR *)sa, sizeof(SOCKADDR_IN)); if (ret < 0) { /* Can't connect to ... */ PUTERR(0, ("Can't connect : %s\n", strerror(errno))); return -1; } return ssoc; } /* ----------------------------------------------------------------- * =NAME= Config::start =RETURN= TRUE or FALSE * ----------------------------------------------------------------- */ int Config::start() { #ifndef NO_SSL if (accept_port.getPortinfo()->isSSL()) { if (!initAccept()) return FALSE; } /* */ int use_ssl_on_connect = 0; Portinfo *cp = connect_port.top; while (cp) { if (cp->isSSL()) { use_ssl_on_connect = 1; break; } cp = cp->next; } if (use_ssl_on_connect) { if (!initConnect(cp)) return FALSE; } #endif /* !NO_SSL */ /* */ for(int i = 0; i < spare_servers; i++) { createSpareServer(); } return TRUE; } /* ----------------------------------------------------------------- * =NAME= Config::listen =SIGNAL= SIGHUP - finish (send same signal to parent process) SIGINT - finish (send same signal to parent process) SIGSTOP, SIGCONT - ignore SIGTERM - finish (send same signal to parent process) SIGCHLD - ignore (kill zonbie) SIGUSR1 - finish SIGUSR2 - output debug message, ignore * ----------------------------------------------------------------- */ void Config::listen() { fd_set rmask; fd_set fds; int n; int max = 64; FD_ZERO(&fds); FD_SET(soc_accept, &fds); #ifndef NO_DEBUG PUTERR(2, ("Config::listen() begin\n")); #endif while (1) { memcpy(&rmask, &fds, sizeof(fd_set)); n = ::select(max, &rmask, 0, 0, 0); if (n < 0) { /* select error */ if (errno == EINTR) { /* caught signal */ int sigtype = get_caught_sig_type(); #ifndef NO_DEBUG PUTERR(2, ("caught signal = %d\n", sigtype)); #endif if (sigtype == SIGTSTP || sigtype == SIGCONT || sigtype == SIGCHLD) { continue; } if (sigtype == SIGUSR2) { #ifndef NO_SIGUSR2 debug(); #endif continue; } if (sigtype == SIGHUP || sigtype == SIGINT || sigtype == SIGTERM) { pid_t ppid = getppid(); if (ppid != 1) kill(ppid, sigtype); else terminate_all_process(); } } else { PUTERR(0, ("select() error : %s\n", strerror(errno))); } return; } if (!n) continue; if (FD_ISSET(soc_accept, &rmask)) { int ret = _accept(); if (!ret) break; if (ret == 2) _exit(0); } } #ifndef NO_DEBUG PUTERR(2, ("Config::listen() end\n")); #endif } /* ----------------------------------------------------------------- * =NAME= Config::_accept() =RETURN 0 : finish all process 1 : continue 2 : finish child process * ----------------------------------------------------------------- */ int Config::_accept(int flag) { int csoc; /* client socket */ int ssoc; /* server socket */ int fval; int retval = 1; SOCKADDR_IN sa_client; unsigned int addr_len = sizeof(SOCKADDR_IN); #ifndef NO_DEBUG PUTERR(2, ("::accept() begin\n")); #endif csoc = ::accept(soc_accept, (SOCKADDR *)&sa_client, &addr_len); if (csoc < 0) { /* accept error */ PUTERR(0, ("::accept() error : %s\n", strerror(errno))); return retval; } #ifndef NO_DEBUG PUTERR(2, ("::accept() end\n")); #endif DWORD addr_client = sa_client.sin_addr.s_addr; char saddr_client[SADDRBUF]; UINT port_client = ntohs(sa_client.sin_port); addr2str(addr_client, saddr_client); connectp = connect_port.getPortinfo(); if (do_fork || flag) { #ifndef NO_DEBUG PUTERR(2, ("fork() begin\n")); #endif fval = fork(); if (fval == -1) { /* can't fork */ PUTERR(0, ("Can't fork()\n")); PUTACCESSLOG(("[%s] Accepted connection from client `%s:%d'\n", servicename, saddr_client, port_client)); closeClientSocket(csoc, &sa_client); return retval; } if (fval) { #ifndef NO_DEBUG PUTERR(2, ("fork() end\n")); #endif ::CLOSE(csoc); return retval; } retval = 2; /* exit at after the end of accept() */ } /* end of do_fork */ #ifndef NO_DEBUG PUTERR(2, ("ACL check begin\n")); #endif /* access check */ { int ret; ACL *ap = acl.top; while (ap) { ret = ap->isMatch(addr_client); if (ret < 0) { if (deny_wait) sleep(deny_wait); PUTACCESSLOG(("[%s] Access denied `%s': matched 'deny' entry\n", servicename, saddr_client)); PUTERR(0, ("Access denied `%s': matched 'deny' entry\n", saddr_client)); closeClientSocket(csoc, &sa_client); return retval; } if (ret > 0) break; ap = ap->next; } if (!ap) { if (deny_wait) sleep(deny_wait); PUTACCESSLOG(("[%s] Access denied `%s' : no match 'allow' entries\n", servicename, saddr_client)); PUTERR(0, ("Access denied `%s' : no match 'allow' entries\n", saddr_client)); closeClientSocket(csoc, &sa_client); return retval; } } #ifndef NO_DEBUG PUTERR(2, ("ACL check end\n")); #endif /****************************************************************** * service specific process *******************************************************************/ if (service_type) { int ret; #ifndef NO_DEBUG PUTERR(2, ("service_type = '%s'\n", serviceTypeFunc[service_type].name)); #endif ret = serviceTypeFunc[service_type].init(this); if (ret) { closeClientSocket(csoc, &sa_client); PUTERR(0, ("failed in initializing for session(%s), error No. = %d\n", serviceTypeFunc[service_type].name, ret)); return retval; } ret = serviceTypeFunc[service_type].func(this, csoc); if (ret) { PUTERR(0, ("failed in session (%s)\n", serviceTypeFunc[service_type].name)); if (ret == 2) { closeClientSocket(csoc, &sa_client); return retval; } } } #ifndef NO_SSL SSL *cssl = 0; SSL *sssl = 0; if (accept_port.getPortinfo()->isSSL()) { #ifndef NO_DEBUG PUTERR(2, ("acceptSSL\n")); #endif cssl = acceptSSL(csoc); if (!cssl) { PUTACCESSLOG(("[%s] Accepted connection from client `%s:%d'\n", servicename, saddr_client, port_client)); PUTERR(0, ("Failed in accepting from client `%s:%d' with SSL\n", saddr_client, port_client)); closeClientSocket(csoc, &sa_client); return retval; } PUTACCESSLOG(("[%s] Accepted connection from client `%s:%d' with SSL\n", servicename, saddr_client, port_client)); } else { #endif /* !NO_SSL */ PUTACCESSLOG(("[%s] Accepted connection from client `%s:%d'\n", servicename, saddr_client, port_client)); #ifndef NO_SSL } #endif #ifndef NO_DEBUG PUTERR(2, ("connect begin\n")); #endif ssoc = createConnectSocket(); #ifndef NO_DEBUG PUTERR(2, ("connect end\n")); #endif SOCKADDR_IN *sa = connectp->getSockAddrIn(); char saddr_server[SADDRBUF]; addr2str(sa->sin_addr.s_addr, saddr_server); UINT port_server = ntohs(sa->sin_port); if (ssoc < 0) { /* connect error */ PUTERR(0, ("failed in connecting to server `%s:%d' : %s\n", saddr_server, port_server, strerror(errno))); #ifndef NO_SSL if (cssl) _SSL_free(cssl); #endif closeClientSocket(csoc, &sa_client); return retval; } #ifndef NO_SSL if (connectp->isSSL()) { #ifndef NO_DEBUG PUTERR(2, ("connectSSL\n")); #endif sssl = connectSSL(ssoc); if (!sssl) { PUTERR(0, ("failed n connecting to `%s:%d' with SSL\n", saddr_server, port_server)); closeServerSocket(ssoc, sa); if (cssl) { _SSL_free(cssl); } closeClientSocket(csoc, &sa_client); return retval; } PUTACCESSLOG(("[%s] Connect to server `%s:%d' with SSL\n", servicename, saddr_server, port_server)); } else { #endif /* !NO_SSL */ PUTACCESSLOG(("[%s] Connect to server `%s:%d'\n", servicename, saddr_server, port_server)); #ifndef NO_SSL } #endif /* begin relaying */ { #ifndef NO_DEBUG PUTERR(2, ("relay() begin\n")); #endif #ifndef NO_SSL Socket c(csoc, cssl); Socket s(ssoc, sssl); #else Socket c(csoc); Socket s(ssoc); #endif int ret = relay(&c, &s); #ifndef NO_DEBUG PUTERR(2, ("relay() end\n")); #endif if (ret == FALSE) { retval = 0; } } #ifndef NO_SSL if (sssl) _SSL_free(sssl); if (cssl) _SSL_free(cssl); #endif /* NO_SSL */ ::CLOSE(ssoc); ::CLOSE(csoc); PUTACCESSLOG(("[%s] Closed connection from client `%s:%d' normally\n", servicename, saddr_client, port_client)); PUTACCESSLOG(("[%s] Closed connection from server `%s:%d' normally\n", servicename, saddr_server, port_server)); return retval; } #ifndef NO_SSL SSL *Config::acceptSSL(SOCKET csoc) { SSL *ssl; ssl = _SSL_new(ctx_accept); if (!ssl) { /* SSL_new() error */ PUTERR(0, ("SSL_new() error\n")); PUTSSLERR(); return NULL; } if (accept_port.getPortinfo()->isVerify()) { _SSL_set_verify(ssl, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, BjorbSSLVerifyCallback); } else { _SSL_set_verify(ssl, SSL_VERIFY_NONE, 0); } _SSL_set_fd(ssl, csoc); if (_SSL_accept(ssl) <= 0) { /* SSL_accept() error */ PUTERR(0, ("SSL_accept() error\n")); int verify_error = _SSL_get_verify_result(ssl); if (verify_error != X509_V_OK) { PUTERR(0, ("verify error : %s\n", X509_verify_cert_error_string(verify_error))); } else { PUTSSLERR(); } _SSL_free(ssl); return NULL; } X509 *peer = _SSL_get_peer_certificate(ssl); if (peer) { char buf[256]; _X509_NAME_oneline(_X509_get_subject_name(peer),buf,256); PUTACCESSLOG(("[%s] client info: subject = %s\n", servicename, buf)); _X509_NAME_oneline(_X509_get_issuer_name(peer),buf,256); PUTACCESSLOG(("[%s] client info: issuer = %s\n", servicename, buf)); X509_free(peer); } else { PUTERR(1, ("warning: Can't get client certificate information\n")); /* return NULL;*/ } return ssl; } SSL *Config::connectSSL(SOCKET ssoc) { SSL *ssl; if (!connectp->isVerify()) { _SSL_CTX_set_verify(ctx_connect, SSL_VERIFY_NONE, 0); } else { _SSL_CTX_set_verify(ctx_connect, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, BjorbSSLVerifyCallback); } ssl = _SSL_new(ctx_connect); if (!ssl) { /* SSL_new() error */ PUTERR(0, ("SSL_new() error\n")); PUTSSLERR(); return NULL; } _SSL_set_fd(ssl, ssoc); if (_SSL_connect(ssl) <= 0) { /* SSL_connect error */ PUTERR(0, ("SSL_connect() error\n")); int verify_error = _SSL_get_verify_result(ssl); if (verify_error != X509_V_OK) { PUTERR(0, ("verify error : %s\n", X509_verify_cert_error_string(verify_error))); } else { PUTSSLERR(); } _SSL_free(ssl); return NULL; } X509 *peer = _SSL_get_peer_certificate(ssl); if (peer) { char buf[256]; _X509_NAME_oneline(_X509_get_subject_name(peer),buf,256); PUTACCESSLOG(("[%s] server info: subject = %s\n", servicename, buf)); _X509_NAME_oneline(_X509_get_issuer_name(peer),buf,256); PUTACCESSLOG(("[%s] server info: issuer = %s\n", servicename, buf)); X509_free(peer); } return ssl; } #endif /* !NO_SSL */ /* ----------------------------------------------------------------- * =NAME= Config::relay =SIGNAL= SIGHUP, SIGINT, SIGTERM : finish, send same signal to parent process SIGSTOP, SIGCONT : ignore SIGUSR1 : finish SIGUSR2 : put debug message, ignore =RETURN= TRUE or FALSE * ----------------------------------------------------------------- */ int Config::relay(Socket *c, Socket *s) { fd_set fds, rmask, emask; SOCKET csoc = c->getSocket(); SOCKET ssoc = s->getSocket(); int max = csoc > ssoc ? csoc + 1 : ssoc + 1; int cerror, serror; int ret; char buf[SOCK_BUFSIZ]; struct timeval tval, *tvalp = 0; int retval = TRUE; FD_ZERO(&fds); FD_SET(csoc, &fds); FD_SET(ssoc, &fds); if (read_timeout) { tvalp = &tval; tval.tv_sec = read_timeout; tval.tv_usec = 0; } while (1) { memcpy(&rmask, &fds, sizeof(fd_set)); memcpy(&emask, &fds, sizeof(fd_set)); cerror = serror = 0; ret = select(max, &rmask, 0, &emask, tvalp); if (ret < 0) { /* select error */ if (errno == EINTR) { int sigtype = get_caught_sig_type(); #ifndef NO_DEBUG PUTERR(2, ("caught signal = %d\n", sigtype)); #endif if (sigtype == SIGTSTP || sigtype == SIGCONT) { continue; } if (sigtype == SIGUSR2) { #ifndef NO_SIGUSR2 debug(); #endif continue; } if (sigtype == SIGHUP || sigtype == SIGINT || sigtype == SIGTERM) { pid_t ppid = getppid(); if (ppid != 1) kill(ppid, sigtype); else terminate_all_process(); return FALSE; } return FALSE; } else { PUTERR(0, ("select() error : %s\n", strerror(errno))); return FALSE; } break; } if (!ret) { /* timeout */ PUTACCESSLOG(("[%s] timeout (%d sec)\n", servicename, read_timeout)); PUTERR(1, ("timeout (%d sec)\n", read_timeout)); break; } if (FD_ISSET(csoc, &emask)) { /* error at client */ cerror = 1; } if (FD_ISSET(ssoc, &emask)) { /* error at server */ serror = 1; } if (FD_ISSET(csoc, &rmask)) { ret = c->read(buf, SOCK_BUFSIZ); if (ret < 0) { /* receive error from client */ PUTERR(0, ("receive error from client: %s\n", strerror(errno))); #ifndef NO_SSL if (c->isSSL()) { PUTSSLERR(); } #endif break; } if (!ret) { /* EOF */ #ifndef NO_DEBUG PUTERR(2, ("connection closed from client\n")); #endif break; } #ifndef NO_DEBUG PUTERR(3, ("%d byte read from client\n", ret)); #endif if (ret > 0 && !cerror) { ret = s->write(buf, ret); if (ret < 0) { /* send error to server */ PUTERR(0, ("send error to server: %s\n", strerror(errno))); #ifndef NO_SSL if (s->isSSL()) { PUTSSLERR(); } #endif break; } #ifndef NO_DEBUG PUTERR(3, ("%d byte write to server\n", ret)); #endif } } /* end of read from client */ if (FD_ISSET(ssoc, &rmask)) { ret = s->read(buf, SOCK_BUFSIZ); if (ret < 0) { /* receive error from server */ PUTERR(0, ("receive error from server: %s\n", strerror(errno))); #ifndef NO_SSL if (s->isSSL()) { PUTSSLERR(); } #endif break; } if (!ret) { /* EOF */ #ifndef NO_DEBUG PUTERR(2, ("connection closed from server\n")); #endif break; } #ifndef NO_DEBUG PUTERR(3, ("%d byte read from server\n", ret)); #endif if (ret > 0 && !serror) { ret = c->write(buf, ret); if (ret < 0) { /* send error to client */ PUTERR(0, ("send error to client: %s\n", strerror(errno))); #ifndef NO_SSL if (c->isSSL()) { PUTSSLERR(); } #endif break; } #ifndef NO_DEBUG PUTERR(3, ("%d byte write to client\n", ret)); #endif } } /* end of read from server */ } /* end of while */ return retval; } int Config::openAccessLog() { alogp = new Logger(access_log); alogp->setAppendMode(); if (alogp->open()) { f_open_access_log = TRUE; #ifndef NO_SYSLOG alogp->setFacilityInfo(); #endif /* !NO_SYSLOG */ return TRUE; } PUTERR(0, ("Can't open access log file `%s'\n", access_log)); return FALSE; } int Config::openErrorLog() { elogp = new Logger(error_log); elogp->setAppendMode(); if (elogp->open()) { f_open_error_log = TRUE; return TRUE; } PUTERR(0, ("Can't open error log file `%s'\n", error_log)); return FALSE; } void Config::stop() { if (soc_accept >= 0) ::CLOSE(soc_accept); if (f_open_access_log) { alogp->close(); delete alogp; } if (f_open_error_log) { elogp->close(); delete elogp; } #ifndef NO_SSL if (ctx_accept) { _SSL_CTX_free(ctx_accept); ctx_accept = 0; } if (ctx_connect) { _SSL_CTX_free(ctx_connect); ctx_connect = 0; } #endif /* !NO_SSL */ } void Config::closeClientSocket(int csoc, SOCKADDR_IN *sap) { char buf[SADDRBUF]; ::CLOSE(csoc); PUTACCESSLOG(("[%s] Closed connection to client `%s:%d'\n", servicename, addr2str(sap->sin_addr.s_addr, buf), ntohs(sap->sin_port))); } void Config::closeServerSocket(int ssoc, SOCKADDR_IN *sap) { char buf[SADDRBUF]; ::CLOSE(ssoc); PUTACCESSLOG(("[%s] Closed connection to server `%s:%d'\n", servicename, addr2str(sap->sin_addr.s_addr, buf), ntohs(sap->sin_port))); } int Config::createSpareServer() { pid_t pid = fork(); if (pid < 0) { PUTERR(0, ("Can't fork()\n")); return FALSE; } if (!pid) { close(0); close(1); close(2); if (!createAcceptSocket()) return FALSE; if (::listen(soc_accept, max_connection) < 0) { PUTERR(0, ("Can't listen() : %s\n", strerror(errno))); return FALSE; } ::elogp = elogp; ::log_level = log_level; listen(); _exit(0); } return TRUE; } int Config::initAccept() { #ifndef NO_SSL ctx_accept = _SSL_CTX_new(SSLv23_method()); if (!ctx_accept) { /* Can't create SSL context */ PUTERR(0, ("SSL_CTX_new() error\n")); return FALSE; } if (!*CA_cert_file) { if (!CA_X509 || !CA_RSA) { PUTERR(0, ("No specified either SSL_CA_file or SSL_make\n")); return FALSE; } if (!SSL_CTX_use_certificate(ctx_accept, CA_X509)) { PUTERR(0, ("SSL_CTX_use_certificate() error\n")); PUTSSLERR(); return FALSE; } if (!SSL_CTX_use_RSAPrivateKey(ctx_accept, CA_RSA)) { PUTERR(0, ("SSL_CTX_use_RSAPrivateKey() error\n")); PUTSSLERR(); return FALSE; } } else { if (!_SSL_CTX_use_RSAPrivateKey_file(ctx_accept, CA_cert_file, X509_FILETYPE_PEM)) { PUTERR(0, ("SSL_CTX_use_RSAPrivateKey_file() error\n")); PUTSSLERR(); return FALSE; } if (!_SSL_CTX_use_certificate_file(ctx_accept, CA_cert_file, X509_FILETYPE_PEM)) { PUTERR(0, ("SSL_CTX_use_certificate_file() error\n")); PUTSSLERR(); return FALSE; } } if (accept_port.getPortinfo()->isVerify()) { if (!*CA_cert_path) { PUTERR(0, ("No specified CA_cert_path\n")); return FALSE; } if (!SSL_CTX_load_verify_locations(ctx_accept, CA_cert_file, CA_cert_path)) { PUTERR(0, ("SSL_CTX_load_verify_locations() error\n")); PUTSSLERR(); return FALSE; } if (!SSL_CTX_set_default_verify_paths(ctx_accept)) { PUTERR(0, ("SSL_CTX_set_default_verify_paths() error\n")); PUTSSLERR(); return FALSE; } _SSL_CTX_set_client_CA_list(ctx_accept, _SSL_load_client_CA_file(CA_cert_file)); } if (SSL_CTX_need_tmp_RSA(ctx_accept)) { if (!rsa_tmp) rsa_tmp = _RSA_generate_key(512, RSA_F4, 0); SSL_CTX_set_tmp_rsa(ctx_accept, rsa_tmp); } #endif /* !NO_SSL */ } int Config::initConnect(Portinfo *cp) { #ifndef NO_SSL if (cp->isVerify() && !*client_cert_file) { PUTERR(0, ("No specified client_cert_file\n")); return FALSE; } ctx_connect = _SSL_CTX_new(_SSLv23_method()); if (!ctx_connect) { /* Can't create SSL context */ PUTERR(0, ("SSL_CTX_new() error\n")); return FALSE; } if (*client_cert_file) { if (!SSL_CTX_use_RSAPrivateKey_file(ctx_connect, client_cert_file, X509_FILETYPE_PEM)) { PUTERR(0, ("SSL_CTX_use_RSAPrivateKey_file() error\n")); PUTSSLERR(); return FALSE; } if (!SSL_CTX_use_certificate_file(ctx_connect, client_cert_file, X509_FILETYPE_PEM)) { PUTERR(0, ("SSL_CTX_use_certificate_file() error\n")); PUTSSLERR(); return FALSE; } } if (SSL_CTX_need_tmp_RSA(ctx_connect)) { if (!rsa_tmp) rsa_tmp = _RSA_generate_key(512, RSA_F4, 0); SSL_CTX_set_tmp_rsa(ctx_connect, rsa_tmp); } #endif /* !NO_SSL */ }