ssl_noserv fixed, ssl_cli/ssl_nocli/ssl_client_cert/ssl_client_key added
Some checks are pending
C/C++ CI / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI / ${{ matrix.target }} (windows-2022) (push) Waiting to run

This commit is contained in:
Vladimir Dubrovin 2025-04-14 21:40:59 +03:00
parent 7aad0205e1
commit 6355f9659b
5 changed files with 196 additions and 77 deletions

View File

@ -186,11 +186,19 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config)
SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, SSL_CERT *server_cert, char **errSSL) SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, SSL_CERT *server_cert, char **errSSL)
{ {
int err = 0; int err = 0;
X509 *cert;
ssl_conn *conn; ssl_conn *conn;
unsigned long ul;
*errSSL = NULL; *errSSL = NULL;
/*FIXME: support SSL_ERROR_WANT_(READ|WRITE) */
#ifdef _WIN32
ul = 0;
ioctlsocket(s, FIONBIO, &ul);
#else
fcntl(s,F_SETFL,0);
#endif
conn = (ssl_conn *)malloc(sizeof(ssl_conn)); conn = (ssl_conn *)malloc(sizeof(ssl_conn));
if ( conn == NULL ){ if ( conn == NULL ){
return NULL; return NULL;
@ -201,7 +209,7 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config,
free(conn); free(conn);
return NULL; return NULL;
} }
if(config->client_verify){ if(hostname && *hostname && config->client_verify){
X509_VERIFY_PARAM *param; X509_VERIFY_PARAM *param;
param = SSL_get0_param(conn->ssl); param = SSL_get0_param(conn->ssl);
@ -221,16 +229,23 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config,
return NULL; return NULL;
} }
if(server_cert){
X509 *cert;
cert = SSL_get_peer_certificate(conn->ssl); cert = SSL_get_peer_certificate(conn->ssl);
if(!cert) { if(!cert) {
ssl_conn_free(conn); ssl_conn_free(conn);
return NULL; return NULL;
} }
/* TODO: Verify certificate */
*server_cert = cert; *server_cert = cert;
}
#ifdef _WIN32
ul = 1;
ioctlsocket(s, FIONBIO, &ul);
#else
fcntl(s,F_SETFL,O_NONBLOCK);
#endif
return conn; return conn;
} }
@ -245,6 +260,7 @@ SSL_CTX * ssl_cli_ctx(SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_ke
#else #else
ctx = SSL_CTX_new(TLS_server_method()); ctx = SSL_CTX_new(TLS_server_method());
#endif #endif
if (!ctx) { if (!ctx) {
*errSSL = ERR_error_string(ERR_get_error(), errbuf); *errSSL = ERR_error_string(ERR_get_error(), errbuf);
return NULL; return NULL;
@ -274,6 +290,17 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert
int err = 0; int err = 0;
X509 *cert; X509 *cert;
ssl_conn *conn; ssl_conn *conn;
unsigned long ul;
/*FIXME: support SSL_ERROR_WANT_(READ|WRITE)*/
#ifdef _WIN32
ul = 0;
ioctlsocket(s, FIONBIO, &ul);
#else
fcntl(s,F_SETFL,0);
#endif
*errSSL = NULL; *errSSL = NULL;
@ -316,6 +343,12 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert
if ( cert != NULL ) if ( cert != NULL )
X509_free(cert); X509_free(cert);
#ifdef _WIN32
ul = 1;
ioctlsocket(s, FIONBIO, &ul);
#else
fcntl(s,F_SETFL,O_NONBLOCK);
#endif
return conn; return conn;
} }

View File

@ -13,11 +13,14 @@ typedef void *SSL_CERT;
struct ssl_config { struct ssl_config {
int mitm; int mitm;
int serv; int serv;
int cli;
char *certcache; char *certcache;
X509 *CA_cert; X509 *CA_cert;
X509 *server_cert; X509 *server_cert;
X509 *client_cert;
EVP_PKEY *CA_key; EVP_PKEY *CA_key;
EVP_PKEY *server_key; EVP_PKEY *server_key;
EVP_PKEY *client_key;
SSL_CTX *cli_ctx; SSL_CTX *cli_ctx;
SSL_CTX *srv_ctx; SSL_CTX *srv_ctx;
int client_min_proto_version; int client_min_proto_version;

View File

@ -35,6 +35,8 @@ static int ssl_connect_timeout = 0;
char *certcache = NULL; char *certcache = NULL;
char *srvcert = NULL; char *srvcert = NULL;
char *srvkey = NULL; char *srvkey = NULL;
char *clicert = NULL;
char *clikey = NULL;
char *server_ca_file = NULL; char *server_ca_file = NULL;
char *server_ca_key = NULL; char *server_ca_key = NULL;
char *client_ca_file = NULL; char *client_ca_file = NULL;
@ -42,6 +44,7 @@ char *client_ca_dir = NULL;
char *client_ca_store = NULL; char *client_ca_store = NULL;
int mitm = 0; int mitm = 0;
int serv = 0; int serv = 0;
int cli = 0;
int ssl_inited = 0; int ssl_inited = 0;
int client_min_proto_version = 0; int client_min_proto_version = 0;
int client_max_proto_version = 0; int client_max_proto_version = 0;
@ -233,38 +236,42 @@ static int ssl_poll(void *state, struct pollfd *fds, nfds_t nfds, int timeout){
#define PCONF (((struct SSLstate *)param->sostate)->config) #define PCONF (((struct SSLstate *)param->sostate)->config)
int domitm(struct clientparam* param){ SSL_CONN dosrvcon(struct clientparam* param, SSL_CERT* cert){
SSL_CERT ServerCert=NULL, FakeCert=NULL; SSL_CONN ServerConn;
SSL_CONN ServerConn, ClientConn;
char *errSSL=NULL; char *errSSL=NULL;
unsigned long ul; unsigned long ul;
#ifdef _WIN32
ul = 0;
ioctlsocket(param->remsock, FIONBIO, &ul);
ul = 0;
ioctlsocket(param->clisock, FIONBIO, &ul);
#else
fcntl(param->remsock,F_SETFL,0);
fcntl(param->clisock,F_SETFL,0);
#endif
if(ssl_connect_timeout){ if(ssl_connect_timeout){
ul = ((unsigned long)ssl_connect_timeout)*1000; ul = ((unsigned long)ssl_connect_timeout)*1000;
setsockopt(param->remsock, SOL_SOCKET, SO_RCVTIMEO, (char *)&ul, 4); setsockopt(param->remsock, SOL_SOCKET, SO_RCVTIMEO, (char *)&ul, 4);
ul = ((unsigned long)ssl_connect_timeout)*1000; ul = ((unsigned long)ssl_connect_timeout)*1000;
setsockopt(param->remsock, SOL_SOCKET, SO_SNDTIMEO, (char *)&ul, 4); setsockopt(param->remsock, SOL_SOCKET, SO_SNDTIMEO, (char *)&ul, 4);
} }
ServerConn = ssl_handshake_to_server(param->remsock, (char *)param->hostname, PCONF, &ServerCert, &errSSL); ServerConn = ssl_handshake_to_server(param->remsock, (char *)param->hostname, PCONF, cert, &errSSL);
if ( ServerConn == NULL || ServerCert == NULL ) { if ( ServerConn == NULL) {
if(ServerConn) ssl_conn_free(ServerConn); if(ServerConn) ssl_conn_free(ServerConn);
param->res = 8011; param->res = 8011;
param->srv->logfunc(param, (unsigned char *)"SSL handshake to server failed"); param->srv->logfunc(param, (unsigned char *)"SSL handshake to server failed");
if(ServerConn == NULL) param->srv->logfunc(param, (unsigned char *)"ServerConn is NULL"); if(ServerConn == NULL) param->srv->logfunc(param, (unsigned char *)"ServerConn is NULL");
if(ServerCert == NULL) param->srv->logfunc(param, (unsigned char *)"ServerCert is NULL"); if(cert && *cert == NULL) param->srv->logfunc(param, (unsigned char *)"ServerCert is NULL");
if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL); if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL);
return 1; return NULL;
} }
SSL_set_mode((SSL *)((ssl_conn *)ServerConn)->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_AUTO_RETRY);
SSL_set_read_ahead((SSL *)((ssl_conn *)ServerConn)->ssl, 0);
return ServerConn;
}
int domitm(struct clientparam* param){
SSL_CERT ServerCert=NULL, FakeCert=NULL;
SSL_CONN ServerConn, ClientConn;
char *errSSL=NULL;
ServerConn = dosrvcon(param, &ServerCert);
if(!ServerConn) return 1;
FakeCert = ssl_copy_cert(ServerCert, PCONF); FakeCert = ssl_copy_cert(ServerCert, PCONF);
_ssl_cert_free(ServerCert); _ssl_cert_free(ServerCert);
if ( FakeCert == NULL ) { if ( FakeCert == NULL ) {
@ -285,26 +292,28 @@ int domitm(struct clientparam* param){
return 3; return 3;
} }
#ifdef _WIN32
ul = 1;
ioctlsocket(param->remsock, FIONBIO, &ul);
ul = 1;
ioctlsocket(param->clisock, FIONBIO, &ul);
#else
fcntl(param->remsock,F_SETFL,O_NONBLOCK);
fcntl(param->clisock,F_SETFL,O_NONBLOCK);
#endif
SSL_set_mode((SSL *)((ssl_conn *)ServerConn)->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_AUTO_RETRY);
SSL_set_mode((SSL *)((ssl_conn *)ClientConn)->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_AUTO_RETRY); SSL_set_mode((SSL *)((ssl_conn *)ClientConn)->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_AUTO_RETRY);
SSL_set_read_ahead((SSL *)((ssl_conn *)ServerConn)->ssl, 0);
SSL_set_read_ahead((SSL *)((ssl_conn *)ClientConn)->ssl, 0); SSL_set_read_ahead((SSL *)((ssl_conn *)ClientConn)->ssl, 0);
addSSL(param->clisock, ClientConn, param->remsock, ServerConn, param); addSSL(param->clisock, ClientConn, param->remsock, ServerConn, param);
return 0; return 0;
} }
int docli(struct clientparam* param){
SSL_CONN ServerConn;
SSL_CERT ServerCert=NULL;
ServerConn = dosrvcon(param, &ServerCert);
_ssl_cert_free(ServerCert);
if(!ServerConn) return 1;
addSSL(INVALID_SOCKET, NULL, param->remsock, ServerConn, param);
return 0;
}
X509 * getCert (const char *fname){ X509 * getCert (const char *fname){
BIO *f; BIO *f;
X509 *CA_cert; X509 *CA_cert;
@ -336,6 +345,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
char fname[256]; char fname[256];
char *errSSL; char *errSSL;
struct ssl_config *sc; struct ssl_config *sc;
sc = malloc(sizeof(struct ssl_config)); sc = malloc(sizeof(struct ssl_config));
if(!sc) return NULL; if(!sc) return NULL;
memset(sc, 0, sizeof(struct ssl_config)); memset(sc, 0, sizeof(struct ssl_config));
@ -356,6 +366,13 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
return sc; return sc;
} }
} }
if(clikey){
sc->client_key = getKey(clikey);
if(!sc->client_key){
fprintf(stderr, "failed to read: %s\n", clikey);
return sc;
}
}
if(client_ca_file)sc->client_ca_file=client_ca_file; if(client_ca_file)sc->client_ca_file=client_ca_file;
if(client_ca_dir)sc->client_ca_dir=client_ca_dir; if(client_ca_dir)sc->client_ca_dir=client_ca_dir;
if(client_ca_store)sc->client_ca_dir=client_ca_store; if(client_ca_store)sc->client_ca_dir=client_ca_store;
@ -389,15 +406,20 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
sc->server_key = getKey(fname); sc->server_key = getKey(fname);
} }
sc->mitm = 1; sc->mitm = 1;
srv->so._send = ssl_send; }
srv->so._recv = ssl_recv; if(cli){
srv->so._sendto = ssl_sendto; if(clicert){
srv->so._recvfrom = ssl_recvfrom; sc->client_cert = getCert(clicert);
srv->so._closesocket = ssl_closesocket; if(!sc->client_cert){
srv->so._poll = ssl_poll; fprintf(stderr, "failed to read client cert from: %s\n", clicert);
#ifdef WIWHSPLICE return sc;
srv->usesplice = 0; }
#endif if(!sc->client_key){
fprintf(stderr, "no client key\n");
return sc;
}
}
sc->cli = 1;
} }
if(serv){ if(serv){
if(!srvcert || !srvkey) return sc; if(!srvcert || !srvkey) return sc;
@ -414,24 +436,28 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
return sc; return sc;
} }
sc->serv = 1; sc->serv = 1;
}
if(mitm || cli || serv){
srv->so._send = ssl_send; srv->so._send = ssl_send;
srv->so._recv = ssl_recv; srv->so._recv = ssl_recv;
srv->so._sendto = ssl_sendto; srv->so._sendto = ssl_sendto;
srv->so._recvfrom = ssl_recvfrom; srv->so._recvfrom = ssl_recvfrom;
srv->so._closesocket = ssl_closesocket; srv->so._closesocket = ssl_closesocket;
srv->so._poll = ssl_poll; srv->so._poll = ssl_poll;
#ifdef WIWHSPLICE
srv->usesplice = 0;
#endif
} }
if(sc && sc->mitm){ if(sc && (sc->mitm || sc->cli)){
#if OPENSSL_VERSION_NUMBER < 0x10100000L #if OPENSSL_VERSION_NUMBER < 0x10100000L
sc->srv_ctx = SSL_CTX_new(SSLv23_client_method()); sc->srv_ctx = SSL_CTX_new(SSLv23_client_method());
#else #else
sc->srv_ctx = SSL_CTX_new(TLS_client_method()); sc->srv_ctx = SSL_CTX_new(TLS_client_method());
#endif #endif
if ( sc->srv_ctx == NULL ) { if ( sc->srv_ctx == NULL ) {
sc->mitm = 0; fprintf(stderr, "failed to set client context\n");
sc->mitm = sc->cli = 0;
}
if(sc->client_cert){
SSL_CTX_use_certificate(sc->srv_ctx, (X509 *) sc->client_cert);
SSL_CTX_use_PrivateKey(sc->srv_ctx, sc->client_key);
} }
if(sc->client_min_proto_version)SSL_CTX_set_min_proto_version(sc->srv_ctx, sc->client_min_proto_version); if(sc->client_min_proto_version)SSL_CTX_set_min_proto_version(sc->srv_ctx, sc->client_min_proto_version);
if(sc->client_max_proto_version)SSL_CTX_set_max_proto_version(sc->srv_ctx, sc->client_max_proto_version); if(sc->client_max_proto_version)SSL_CTX_set_max_proto_version(sc->srv_ctx, sc->client_max_proto_version);
@ -451,6 +477,9 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
SSL_CTX_set_verify(sc->srv_ctx, SSL_VERIFY_PEER, verify_callback); SSL_CTX_set_verify(sc->srv_ctx, SSL_VERIFY_PEER, verify_callback);
} }
} }
#ifdef WIWHSPLICE
srv->usesplice = 0;
#endif
return sc; return sc;
} }
@ -469,13 +498,6 @@ static FILTER_ACTION ssl_filter_client(void *fo, struct clientparam * param, voi
SSL_CONN ClientConn; SSL_CONN ClientConn;
char *err; char *err;
#ifdef _WIN32
unsigned long ul = 0;
ioctlsocket(param->clisock, FIONBIO, &ul);
#else
fcntl(param->clisock,F_SETFL,0);
#endif
ClientConn = ssl_handshake_to_client(param->clisock, ssls->config, NULL, NULL, &err); ClientConn = ssl_handshake_to_client(param->clisock, ssls->config, NULL, NULL, &err);
if ( ClientConn == NULL ) { if ( ClientConn == NULL ) {
param->res = 8013; param->res = 8013;
@ -483,16 +505,6 @@ static FILTER_ACTION ssl_filter_client(void *fo, struct clientparam * param, voi
if(err)param->srv->logfunc(param, (unsigned char *)err); if(err)param->srv->logfunc(param, (unsigned char *)err);
return REJECT; return REJECT;
} }
#ifdef _WIN32
{
unsigned long ul = 1;
ioctlsocket(param->clisock, FIONBIO, &ul);
}
#else
fcntl(param->clisock,F_SETFL,O_NONBLOCK);
#endif
SSL_set_mode((SSL *)((ssl_conn *)ClientConn)->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_AUTO_RETRY); SSL_set_mode((SSL *)((ssl_conn *)ClientConn)->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_AUTO_RETRY);
SSL_set_read_ahead((SSL *)((ssl_conn *)ClientConn)->ssl, 0); SSL_set_read_ahead((SSL *)((ssl_conn *)ClientConn)->ssl, 0);
addSSL(param->clisock, ClientConn, INVALID_SOCKET, NULL, param); addSSL(param->clisock, ClientConn, INVALID_SOCKET, NULL, param);
@ -501,14 +513,22 @@ static FILTER_ACTION ssl_filter_client(void *fo, struct clientparam * param, voi
} }
static FILTER_ACTION ssl_filter_predata(void *fc, struct clientparam * param){ static FILTER_ACTION ssl_filter_predata(void *fc, struct clientparam * param){
if(param->operation != HTTP_CONNECT && param->operation != CONNECT) return PASS; if(param->operation != HTTP_CONNECT && param->operation != CONNECT) return PASS;
if(!PCONF->mitm) return PASS; if(PCONF->mitm){
if(domitm(param)) { if(domitm(param)) {
return REJECT; return REJECT;
} }
if(!param->redirectfunc) param->redirectfunc = proxyfunc; if(!param->redirectfunc) param->redirectfunc = proxyfunc;
return CONTINUE; return CONTINUE;
} }
else if(PCONF->cli) {
if(docli(param)) {
return REJECT;
}
}
return PASS;
}
static void ssl_filter_clear(void *fc){ static void ssl_filter_clear(void *fc){
@ -525,12 +545,18 @@ static void ssl_filter_close(void *fo){
if ( CONFIG->server_cert != NULL ) { if ( CONFIG->server_cert != NULL ) {
X509_free(CONFIG->server_cert); X509_free(CONFIG->server_cert);
} }
if ( CONFIG->client_cert != NULL ) {
X509_free(CONFIG->server_cert);
}
if ( CONFIG->CA_key != NULL ) { if ( CONFIG->CA_key != NULL ) {
EVP_PKEY_free(CONFIG->CA_key); EVP_PKEY_free(CONFIG->CA_key);
} }
if ( CONFIG->server_key != NULL ) { if ( CONFIG->server_key != NULL ) {
EVP_PKEY_free(CONFIG->server_key); EVP_PKEY_free(CONFIG->server_key);
} }
if ( CONFIG->client_key != NULL ) {
EVP_PKEY_free(CONFIG->server_key);
}
if ( CONFIG->srv_ctx != NULL ) { if ( CONFIG->srv_ctx != NULL ) {
SSL_CTX_free(CONFIG->srv_ctx); SSL_CTX_free(CONFIG->srv_ctx);
} }
@ -607,7 +633,8 @@ static int h_serv(int argc, unsigned char **argv){
static int h_noserv(int argc, unsigned char **argv){ static int h_noserv(int argc, unsigned char **argv){
struct filter * sf; struct filter * sf;
if(!mitm) return 1; if(!serv) return 1;
serv = 0;
if(pl->conf->filters == &ssl_filter_serv) pl->conf->filters = ssl_filter_serv.next; if(pl->conf->filters == &ssl_filter_serv) pl->conf->filters = ssl_filter_serv.next;
else for(sf = pl->conf->filters; sf && sf->next; sf=sf->next){ else for(sf = pl->conf->filters; sf && sf->next; sf=sf->next){
if(sf->next == &ssl_filter_serv) { if(sf->next == &ssl_filter_serv) {
@ -615,10 +642,46 @@ static int h_noserv(int argc, unsigned char **argv){
break; break;
} }
} }
serv = 0;
return 0; return 0;
} }
static struct filter ssl_filter_cli = {
NULL,
"ssl filter",
"cli",
ssl_filter_open,
ssl_filter_client,
NULL, NULL, NULL, ssl_filter_predata, NULL, NULL,
ssl_filter_clear,
ssl_filter_close
};
static int h_cli(int argc, unsigned char **argv){
if(mitm) return 1;
if(cli) return 2;
ssl_filter_cli.next = pl->conf->filters;
pl->conf->filters = &ssl_filter_cli;
sso = *pl->so;
cli = 1;
return 0;
}
static int h_nocli(int argc, unsigned char **argv){
struct filter * sf;
if(!cli) return 1;
cli = 0;
if(pl->conf->filters == &ssl_filter_cli) pl->conf->filters = ssl_filter_cli.next;
else for(sf = pl->conf->filters; sf && sf->next; sf=sf->next){
if(sf->next == &ssl_filter_cli) {
sf->next = ssl_filter_cli.next;
break;
}
}
return 0;
}
static int h_certcache(int argc, unsigned char **argv){ static int h_certcache(int argc, unsigned char **argv){
size_t len; size_t len;
len = strlen((char *)argv[1]); len = strlen((char *)argv[1]);
@ -640,6 +703,19 @@ static int h_srvkey(int argc, unsigned char **argv){
return 0; return 0;
} }
static int h_clicert(int argc, unsigned char **argv){
free(clicert);
clicert = argc > 1? strdup((char *)argv[1]) : NULL;
return 0;
}
static int h_clikey(int argc, unsigned char **argv){
free(clikey);
clikey = argc > 1? strdup((char *)argv[1]) : NULL;
return 0;
}
static int h_client_cipher_list(int argc, unsigned char **argv){ static int h_client_cipher_list(int argc, unsigned char **argv){
free(client_cipher_list); free(client_cipher_list);
client_cipher_list = argc > 1? strdup((char *)argv[1]) : NULL; client_cipher_list = argc > 1? strdup((char *)argv[1]) : NULL;
@ -764,7 +840,7 @@ static struct commands ssl_commandhandlers[] = {
{ssl_commandhandlers+1, "ssl_mitm", h_mitm, 1, 1}, {ssl_commandhandlers+1, "ssl_mitm", h_mitm, 1, 1},
{ssl_commandhandlers+2, "ssl_nomitm", h_nomitm, 1, 1}, {ssl_commandhandlers+2, "ssl_nomitm", h_nomitm, 1, 1},
{ssl_commandhandlers+3, "ssl_serv", h_serv, 1, 1}, {ssl_commandhandlers+3, "ssl_serv", h_serv, 1, 1},
{ssl_commandhandlers+4, "ssl_noserv", h_serv, 1, 1}, {ssl_commandhandlers+4, "ssl_noserv", h_noserv, 1, 1},
{ssl_commandhandlers+5, "ssl_server_cert", h_srvcert, 1, 2}, {ssl_commandhandlers+5, "ssl_server_cert", h_srvcert, 1, 2},
{ssl_commandhandlers+6, "ssl_server_key", h_srvkey, 1, 2}, {ssl_commandhandlers+6, "ssl_server_key", h_srvkey, 1, 2},
{ssl_commandhandlers+7, "ssl_server_ca_file", h_server_ca_file, 1, 2}, {ssl_commandhandlers+7, "ssl_server_ca_file", h_server_ca_file, 1, 2},
@ -782,6 +858,10 @@ static struct commands ssl_commandhandlers[] = {
{ssl_commandhandlers+19, "ssl_server_max_proto_version", h_server_max_proto_version, 1, 2}, {ssl_commandhandlers+19, "ssl_server_max_proto_version", h_server_max_proto_version, 1, 2},
{ssl_commandhandlers+20, "ssl_client_verify", h_client_verify, 1, 1}, {ssl_commandhandlers+20, "ssl_client_verify", h_client_verify, 1, 1},
{ssl_commandhandlers+21, "ssl_client_no_verify", h_no_client_verify, 1, 1}, {ssl_commandhandlers+21, "ssl_client_no_verify", h_no_client_verify, 1, 1},
{ssl_commandhandlers+22, "ssl_cli", h_cli, 1, 1},
{ssl_commandhandlers+23, "ssl_nocli", h_nocli, 1, 1},
{ssl_commandhandlers+24, "ssl_client_cert", h_clicert, 1, 2},
{ssl_commandhandlers+25, "ssl_client_key", h_clikey, 1, 2},
{NULL, "ssl_certcache", h_certcache, 2, 2}, {NULL, "ssl_certcache", h_certcache, 2, 2},
}; };

View File

@ -1414,6 +1414,8 @@ FILTER_ACTION handlepredatflt(struct clientparam *cparam){
FILTER_ACTION action; FILTER_ACTION action;
int i; int i;
if(cparam->predatdone) return PASS;
cparam->predatdone = 1;
for(i=0; i<cparam->npredatfilters ;i++){ for(i=0; i<cparam->npredatfilters ;i++){
action = (*cparam->predatfilters[i]->filter->filter_predata)(cparam->predatfilters[i]->data, cparam); action = (*cparam->predatfilters[i]->filter->filter_predata)(cparam->predatfilters[i]->data, cparam);
if(action!=CONTINUE) return action; if(action!=CONTINUE) return action;

View File

@ -584,7 +584,8 @@ struct clientparam {
chunked, chunked,
paused, paused,
version, version,
connlim; connlim,
predatdone;
unsigned char *hostname, unsigned char *hostname,
*username, *username,