ssl_client_mode added, code cleanup
Some checks failed
C/C++ CI / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (windows-2022) (push) Has been cancelled

ssl_client_mode
0 (default) - handshake immediately after connect() (with first parent or with destination if there is no parent)
1 - handshake with destination server (handshake after connection via parents is established)
2 - handshake after data channel is established (e.g. after CONNECT)
This commit is contained in:
Vladimir Dubrovin 2025-12-31 19:56:52 +03:00
parent aab8531072
commit fdeee233de
13 changed files with 155 additions and 107 deletions

View File

@ -895,9 +895,16 @@ int doauth(struct clientparam * param){
if(ret > 9) return ret;
}
if(!res){
return alwaysauth(param);
ret = alwaysauth(param);
if (param->afterauthfilters){
FILTER_ACTION action;
action = handleafterauthflt(param);
if(action != PASS) return 19;
}
}
return ret;
}

View File

@ -578,6 +578,13 @@ int doconnect(struct clientparam * param){
size = sizeof(param->sinsl);
if(param->srv->so._getsockname(param->sostate, param->remsock, (struct sockaddr *)&param->sinsl, &size)==-1) {return (15);}
}
if (param->nconnectfilters){
FILTER_ACTION action;
action = handleconnectflt(param);
if(action != PASS) return 19;
}
return 0;
}

View File

@ -749,7 +749,7 @@ static struct property prop_server[] = {
static struct property prop_client[] = {
{prop_client + 1, "servicetype", ef_client_type, TYPE_STRING, "type of the client"},
{prop_client + 2, "threadid", ef_client_threadid, TYPE_INTEGER, "process thread id"},
{prop_client + 2, "threadid", ef_client_threadid, TYPE_UNSIGNED64, "process thread id"},
{prop_client + 3, "starttime", ef_client_starttime, TYPE_DATETIME, "client started seconds"},
{prop_client + 4, "starttime_msec", ef_client_starttime_msec, TYPE_UNSIGNED, "client started milliseconds"},
{prop_client + 5, "redirected", ef_client_redirected, TYPE_INTEGER, "number of redirections"},

View File

@ -80,10 +80,7 @@ static unsigned char PADDING[64] = {
(a) = ROTATE_LEFT ((a), (s)); \
}
void md4_calc(output, input, inlen)
unsigned char *output;
unsigned char *input; /* input block */
unsigned int inlen; /* length of input block */
void md4_calc(unsigned char *output, unsigned char *input, unsigned inlen)
{
MD4_CTX context;
@ -94,8 +91,7 @@ unsigned int inlen; /* length of input block */
/* MD4 initialization. Begins an MD4 operation, writing a new context.
*/
void MD4Init (context)
MD4_CTX *context; /* context */
void MD4Init ( MD4_CTX *context)
{
context->count[0] = context->count[1] = 0;
@ -111,10 +107,7 @@ MD4_CTX *context; /* context */
operation, processing another message block, and updating the
context.
*/
void MD4Update (context, input, inputLen)
MD4_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
void MD4Update (MD4_CTX *context, unsigned char *input, unsigned inputLen)
{
unsigned int i, index, partLen;
@ -152,9 +145,7 @@ unsigned int inputLen; /* length of input block */
/* MD4 finalization. Ends an MD4 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD4Final (digest, context)
unsigned char digest[16]; /* message digest */
MD4_CTX *context; /* context */
void MD4Final (unsigned char digest[16], MD4_CTX *context)
{
unsigned char bits[8];
unsigned int index, padLen;
@ -180,9 +171,7 @@ MD4_CTX *context; /* context */
/* MD4 basic transformation. Transforms state based on block.
*/
static void MD4Transform (state, block)
UINT4 state[4];
unsigned char block[64];
static void MD4Transform (UINT4 state[4], unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
@ -255,10 +244,7 @@ unsigned char block[64];
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
static void Encode (unsigned char *output, UINT4 *input, unsigned len)
{
unsigned int i, j;
@ -273,11 +259,8 @@ unsigned int len;
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
static void Decode (UINT4 *output, unsigned char *input, unsigned len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
@ -288,10 +271,7 @@ unsigned int len;
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD4_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned int len;
static void MD4_memcpy (POINTER output, POINTER input, unsigned len)
{
unsigned int i;
@ -301,10 +281,7 @@ unsigned int len;
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD4_memset (output, value, len)
POINTER output;
int value;
unsigned int len;
static void MD4_memset (POINTER output, int value, unsigned len)
{
unsigned int i;

View File

@ -107,8 +107,7 @@ void librad_md5_calc(unsigned char *output, unsigned char *input,
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (context)
MD5_CTX *context; /* context */
void MD5Init (MD5_CTX *context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
@ -123,10 +122,7 @@ MD5_CTX *context; /* context */
operation, processing another message block, and updating the
context.
*/
void MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */
const unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
void MD5Update (MD5_CTX *context, const unsigned char *input, unsigned inputLen)
{
unsigned int i, index, partLen;
@ -165,9 +161,7 @@ unsigned int inputLen; /* length of input block */
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
void MD5Final (unsigned char digest[16], MD5_CTX *context)
{
unsigned char bits[8];
unsigned int index, padLen;
@ -194,9 +188,7 @@ MD5_CTX *context; /* context */
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
UINT4 state[4];
const unsigned char block[64];
static void MD5Transform (UINT4 state[4], const unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
@ -287,10 +279,7 @@ const unsigned char block[64];
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
static void Encode (unsigned char *output, UINT4 *input, unsigned len)
{
unsigned int i, j;
@ -305,10 +294,7 @@ unsigned int len;
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
UINT4 *output;
const unsigned char *input;
unsigned int len;
static void Decode (UINT4 *output, const unsigned char *input, unsigned len)
{
unsigned int i, j;
@ -320,10 +306,7 @@ unsigned int len;
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (output, input, len)
POINTER output;
CONSTPOINTER input;
unsigned int len;
static void MD5_memcpy (POINTER output, CONSTPOINTER input, unsigned len)
{
unsigned int i;
@ -333,10 +316,7 @@ unsigned int len;
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned int len;
static void MD5_memset (POINTER output, int value, unsigned len)
{
unsigned int i;

View File

@ -833,6 +833,8 @@ static struct filter fp_filter = {
fp_open,
fp_client,
fp_request,
NULL,
NULL,
fp_hcli,
fp_hsrv,
NULL,

View File

@ -132,7 +132,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, unsigne
if(argc < 2) return 1;
pl = pluginlink;
if(service) free(service);
service=strdup((char *)argv[1]);
service=(unsigned char *)strdup((char *)argv[1]);
if (already_loaded) { return (0); }

View File

@ -46,6 +46,7 @@ struct ssl_config {
int server_max_proto_version;
int client_verify;
int server_verify;
int client_mode;
};
typedef struct ssl_config SSL_CONFIG;

View File

@ -30,37 +30,38 @@ PROXYFUNC tcppmfunc, proxyfunc, smtppfunc, ftpprfunc;
static struct pluginlink * pl;
struct alpn client_alpn_protos;
static struct alpn client_alpn_protos;
static int ssl_loaded = 0;
static int ssl_connect_timeout = 0;
char *certcache = NULL;
char *srvcert = NULL;
char *srvkey = NULL;
char *clicert = NULL;
char *clikey = NULL;
char *server_ca_file = NULL;
char *server_ca_dir = NULL;
char *server_ca_store = NULL;
char *server_ca_key = NULL;
char *client_ca_file = NULL;
char *client_ca_dir = NULL;
char *client_ca_store = NULL;
int mitm = 0;
int serv = 0;
int cli = 0;
int ssl_inited = 0;
int client_min_proto_version = 0;
int client_max_proto_version = 0;
int server_min_proto_version = 0;
int server_max_proto_version = 0;
int client_verify = 0;
int server_verify = 0;
char * client_ciphersuites = NULL;
char * server_ciphersuites = NULL;
char * client_cipher_list = NULL;
char * server_cipher_list = NULL;
char * client_sni = NULL;
static char *certcache = NULL;
static char *srvcert = NULL;
static char *srvkey = NULL;
static char *clicert = NULL;
static char *clikey = NULL;
static char *server_ca_file = NULL;
static char *server_ca_dir = NULL;
static char *server_ca_store = NULL;
static char *server_ca_key = NULL;
static char *client_ca_file = NULL;
static char *client_ca_dir = NULL;
static char *client_ca_store = NULL;
static int mitm = 0;
static int serv = 0;
static int cli = 0;
static int ssl_inited = 0;
static int client_min_proto_version = 0;
static int client_max_proto_version = 0;
static int server_min_proto_version = 0;
static int server_max_proto_version = 0;
static int client_verify = 0;
static int server_verify = 0;
static char * client_ciphersuites = NULL;
static char * server_ciphersuites = NULL;
static char * client_cipher_list = NULL;
static char * server_cipher_list = NULL;
static char * client_sni = NULL;
static int client_mode = 0;
typedef struct _ssl_conn {
struct SSL_CTX *ctx;
@ -80,10 +81,6 @@ struct SSLstate {
};
/*
TO DO: use hashtable
*/
#define STATE ((struct SSLstate *)(state))
static struct SSLsock *searchSSL(void* state, SOCKET s){
@ -424,6 +421,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
sc->client_max_proto_version = client_max_proto_version;
sc->server_min_proto_version = server_min_proto_version;
sc->server_max_proto_version = server_max_proto_version;
sc->client_mode = client_mode;
sc->client_verify = client_verify;
sc->server_verify = server_verify;
if(client_ciphersuites) sc->client_ciphersuites = strdup(client_ciphersuites);
@ -595,6 +593,24 @@ static FILTER_ACTION ssl_filter_client(void *fo, struct clientparam * param, voi
return CONTINUE;
}
static FILTER_ACTION ssl_filter_connect(void *fc, struct clientparam * param){
if(PCONF->cli && !client_mode) {
if(docli(param)) {
return REJECT;
}
}
return PASS;
}
static FILTER_ACTION ssl_filter_afterauth(void *fc, struct clientparam * param){
if(PCONF->cli && client_mode == 1) {
if(docli(param)) {
return REJECT;
}
}
return PASS;
}
static FILTER_ACTION ssl_filter_predata(void *fc, struct clientparam * param){
if(param->operation != HTTP_CONNECT && param->operation != CONNECT) return PASS;
@ -605,7 +621,7 @@ static FILTER_ACTION ssl_filter_predata(void *fc, struct clientparam * param){
if(!param->redirectfunc) param->redirectfunc = proxyfunc;
return CONTINUE;
}
else if(PCONF->cli) {
else if(PCONF->cli && client_mode == 2) {
if(docli(param)) {
return REJECT;
}
@ -668,7 +684,12 @@ static struct filter ssl_filter = {
"ssl_filter",
ssl_filter_open,
ssl_filter_client,
NULL, NULL, NULL, ssl_filter_predata, NULL, NULL,
NULL,
ssl_filter_connect,
ssl_filter_afterauth,
NULL, NULL,
ssl_filter_predata,
NULL, NULL,
ssl_filter_clear,
ssl_filter_close
};
@ -950,6 +971,15 @@ static int h_server_verify(int argc, unsigned char **argv){
server_verify = 1;
return 0;
}
static int h_client_mode(int argc, unsigned char **argv){
client_mode = 0;
if(argc <= 1) return 0;
client_mode = atoi((char *)argv[1]);
return 0;
}
static int h_no_server_verify(int argc, unsigned char **argv){
server_verify = 0;
return 0;
@ -991,6 +1021,7 @@ static struct commands ssl_commandhandlers[] = {
{ssl_commandhandlers+33, "ssl_server_ca_store", h_server_ca_store, 1, 2},
{ssl_commandhandlers+34, "ssl_client_sni", h_client_sni, 1, 2},
{ssl_commandhandlers+35, "ssl_client_alpn", h_client_alpn, 1, 0},
{ssl_commandhandlers+36, "ssl_client_mode", h_client_mode, 1, 2},
{NULL, "ssl_certcache", h_certcache, 2, 2},
};
@ -1029,6 +1060,7 @@ PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink,
server_max_proto_version = 0;
client_verify = 0;
server_verify = 0;
client_mode = 0;
free(client_ciphersuites);
client_ciphersuites = NULL;
free(server_ciphersuites);

View File

@ -63,7 +63,7 @@ static FILTER_ACTION transparent_filter_client(void *fo, struct clientparam * pa
#endif
pl->myinet_ntop(*SAFAMILY(&param->req), SAADDR(&param->req), (char *)addrbuf, sizeof(addrbuf));
if(param->hostname) pl->freefunc(param->hostname);
param->hostname = pl->strdupfunc(addrbuf);
param->hostname = (unsigned char *)pl->strdupfunc(addrbuf);
param->sinsr = param->req;
return PASS;
}
@ -81,7 +81,7 @@ static struct filter transparent_filter = {
"Transparent filter",
transparent_filter_open,
transparent_filter_client,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
transparent_filter_clear,
transparent_filter_close
};

View File

@ -266,6 +266,8 @@ void freepwl(struct passwords *pw);
void copyfilter(struct filter *, struct srvparam *srv);
FILTER_ACTION makefilters (struct srvparam *srv, struct clientparam *param);
FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p);
FILTER_ACTION handleconnectflt(struct clientparam *param);
FILTER_ACTION handleafterauthflt(struct clientparam *param);
FILTER_ACTION handlehdrfilterscli(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p);
FILTER_ACTION handlehdrfilterssrv(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p);
FILTER_ACTION handlepredatflt(struct clientparam *param);

View File

@ -718,7 +718,7 @@ int MODULEMAINFUNC (int argc, char** argv){
defparam.clisock = sock;
if(!srv.silent && !iscbc){
sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
sprintf((char *)buf, "Accepting connections [%"PRINTF_INT64_MODIFIER"u/%"PRINTF_INT64_MODIFIER"u]", (uint64_t)getpid(), (uint64_t)pthread_self());
dolog(&defparam, buf);
}
}
@ -916,7 +916,7 @@ int MODULEMAINFUNC (int argc, char** argv){
#endif
srv.childcount++;
if (h) {
newparam->threadid = (unsigned)thread;
newparam->threadid = (uint64_t)thread;
CloseHandle(h);
}
else {
@ -933,7 +933,7 @@ int MODULEMAINFUNC (int argc, char** argv){
if(!srv.silent)dolog(&defparam, buf);
}
else {
newparam->threadid = (unsigned)thread;
newparam->threadid = (uint64_t)thread;
}
#endif
pthread_mutex_unlock(&srv.counter_mutex);
@ -1075,6 +1075,8 @@ void freeparam(struct clientparam * param) {
if(param->datfilterssrv) myfree(param->datfilterssrv);
#ifndef STDMAIN
if(param->reqfilters) myfree(param->reqfilters);
if(param->connectfilters) myfree(param->connectfilters);
if(param->afterauthfilters) myfree(param->afterauthfilters);
if(param->hdrfilterscli) myfree(param->hdrfilterscli);
if(param->hdrfilterssrv) myfree(param->hdrfilterssrv);
if(param->predatfilters) myfree(param->predatfilters);
@ -1128,6 +1130,19 @@ void freeparam(struct clientparam * param) {
myfree(param);
}
FILTER_ACTION handleconnectflt(struct clientparam *cparam){
#ifndef STDMAIN
FILTER_ACTION action;
int i;
for(i=0; i<cparam->nconnectfilters ;i++){
action = (*cparam->connectfilters[i]->filter->filter_connect)(cparam->connectfilters[i]->data, cparam);
if(action!=CONTINUE) return action;
}
#endif
return PASS;
}
#ifndef STDMAIN
static void * itcopy (void * from, size_t size){
@ -1313,6 +1328,8 @@ void copyfilter (struct filter *filter, struct srvparam *srv){
if(srv->nfilters>0)srv->filter[srv->nfilters - 1].next = srv->filter + srv->nfilters;
srv->nfilters++;
if(filter->filter_request)srv->nreqfilters++;
if(filter->filter_connect)srv->nconnectfilters++;
if(filter->filter_afterauth)srv->nafterauthfilters++;
if(filter->filter_header_srv)srv->nhdrfilterssrv++;
if(filter->filter_header_cli)srv->nhdrfilterscli++;
if(filter->filter_predata)srv->npredatfilters++;
@ -1330,6 +1347,8 @@ FILTER_ACTION makefilters (struct srvparam *srv, struct clientparam *param){
if(!(param->filters = myalloc(sizeof(struct filterp) * srv->nfilters)) ||
(srv->nreqfilters && !(param->reqfilters = myalloc(sizeof(struct filterp *) * srv->nreqfilters))) ||
(srv->nconnectfilters && !(param->connectfilters = myalloc(sizeof(struct filterp *) * srv->nconnectfilters))) ||
(srv->nafterauthfilters && !(param->afterauthfilters = myalloc(sizeof(struct filterp *) * srv->nafterauthfilters))) ||
(srv->nhdrfilterssrv && !(param->hdrfilterssrv = myalloc(sizeof(struct filterp *) * srv->nhdrfilterssrv))) ||
(srv->nhdrfilterscli && !(param->hdrfilterscli = myalloc(sizeof(struct filterp *) * srv->nhdrfilterscli))) ||
(srv->npredatfilters && !(param->predatfilters = myalloc(sizeof(struct filterp *) * srv->npredatfilters))) ||
@ -1347,6 +1366,8 @@ FILTER_ACTION makefilters (struct srvparam *srv, struct clientparam *param){
if(action > CONTINUE) return action;
param->filters[param->nfilters].filter = srv->filter + i;
if(srv->filter[i].filter_request)param->reqfilters[param->nreqfilters++] = param->filters + param->nfilters;
if(srv->filter[i].filter_connect)param->connectfilters[param->nconnectfilters++] = param->filters + param->nfilters;
if(srv->filter[i].filter_afterauth)param->afterauthfilters[param->nafterauthfilters++] = param->filters + param->nfilters;
if(srv->filter[i].filter_header_cli)param->hdrfilterscli[param->nhdrfilterscli++] = param->filters + param->nfilters;
if(srv->filter[i].filter_header_srv)param->hdrfilterssrv[param->nhdrfilterssrv++] = param->filters + param->nfilters;
if(srv->filter[i].filter_predata)param->predatfilters[param->npredatfilters++] = param->filters + param->nfilters;
@ -1392,6 +1413,20 @@ void freeacl(struct ace *ac){
}
}
FILTER_ACTION handleafterauthflt(struct clientparam *cparam){
#ifndef STDMAIN
FILTER_ACTION action;
int i;
for(i=0; i<cparam->nafterauthfilters ;i++){
action = (*cparam->afterauthfilters[i]->filter->filter_afterauth)(cparam->afterauthfilters[i]->data, cparam);
if(action!=CONTINUE) return action;
}
#endif
return PASS;
}
FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
FILTER_ACTION action;
int i;

View File

@ -416,6 +416,8 @@ struct filter {
FILTER_OPEN *filter_open;
FILTER_CLIENT *filter_client;
FILTER_BUFFER *filter_request;
FILTER_PREDATA *filter_connect;
FILTER_PREDATA *filter_afterauth;
FILTER_BUFFER *filter_header_cli;
FILTER_BUFFER *filter_header_srv;
FILTER_PREDATA *filter_predata;
@ -494,7 +496,7 @@ struct srvparam {
int needuser;
int silent;
int transparent;
int nfilters, nreqfilters, nhdrfilterscli, nhdrfilterssrv, npredatfilters, ndatfilterscli, ndatfilterssrv;
int nfilters, nreqfilters, nconnectfilters, nafterauthfilters, nhdrfilterscli, nhdrfilterssrv, npredatfilters, ndatfilterscli, ndatfilterssrv;
int family;
int stacksize;
int noforce;
@ -550,7 +552,7 @@ struct clientparam {
struct filterp *filters,
**reqfilters,
**reqfilters, **connectfilters, **afterauthfilters,
**hdrfilterscli, **hdrfilterssrv,
**predatfilters, **datfilterscli, **datfilterssrv;
@ -565,18 +567,21 @@ struct clientparam {
uint64_t waitclient64,
waitserver64,
cycles;
cycles,
threadid;
int redirected,
operation,
nfilters, nreqfilters, nhdrfilterscli, nhdrfilterssrv, npredatfilters, ndatfilterscli, ndatfilterssrv,
nfilters,
nreqfilters, nconnectfilters, nafterauthfilters,
nhdrfilterscli, nhdrfilterssrv,
npredatfilters, ndatfilterscli, ndatfilterssrv,
unsafefilter,
bandlimver;
int res,
status;
int pwtype,
threadid,
weight,
nolog,
nolongdatfilter,