Compare commits

...

2 Commits

Author SHA1 Message Date
Vladimir Dubrovin
d014bb1149 Use SSL_connect / SSL_accept in non-blocking mode
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
2025-12-30 17:57:23 +03:00
Vladimir Dubrovin
730fd96fb0 Fixed: allow ssl server and client on the same service 2025-12-30 15:40:03 +03:00
3 changed files with 96 additions and 112 deletions

View File

@ -196,14 +196,6 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config,
*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));
if ( conn == NULL ){
return NULL;
@ -227,8 +219,28 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config,
return NULL;
}
if(hostname && *hostname)SSL_set_tlsext_host_name(conn->ssl, hostname);
do {
struct pollfd fds[1] = {{}};
int sslerr;
err = SSL_connect(conn->ssl);
if ( err == -1 ) {
if (err != -1) break;
sslerr = SSL_get_error(conn->ssl, err);
if(sslerr == SSL_ERROR_WANT_READ){
fds[0].fd = s;
fds[0].events = POLLIN;
}
else if(sslerr == SSL_ERROR_WANT_WRITE){
fds[0].fd = s;
fds[0].events = POLLOUT;
}
else break;
if(sso._poll(sso.state, fds, 1, CONNECT_TO*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break;
} while (err == -1);
if ( err != 1 ) {
*errSSL = getSSLErr();
ssl_conn_free(conn);
return NULL;
@ -245,12 +257,6 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config,
*server_cert = cert;
}
#ifdef _WIN32
ul = 1;
ioctlsocket(s, FIONBIO, &ul);
#else
fcntl(s,F_SETFL,O_NONBLOCK);
#endif
return conn;
}
@ -261,15 +267,6 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert
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;
@ -296,28 +293,38 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert
}
SSL_set_fd(conn->ssl, s);
do {
struct pollfd fds[1] = {{}};
int sslerr;
err = SSL_accept(conn->ssl);
if ( err <= 0 ) {
if (err != -1) break;
sslerr = SSL_get_error(conn->ssl, err);
if(sslerr == SSL_ERROR_WANT_READ){
fds[0].fd = s;
fds[0].events = POLLIN;
}
else if(sslerr == SSL_ERROR_WANT_WRITE){
fds[0].fd = s;
fds[0].events = POLLOUT;
}
else break;
if(sso._poll(sso.state, fds, 1, CONNECT_TO*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break;
} while (err == -1);
if ( err != 1 ) {
*errSSL = getSSLErr();
ssl_conn_free(conn);
return NULL;
}
//
// client certificate
// TODO: is it required?
//
cert = SSL_get_peer_certificate(conn->ssl);
if ( cert != NULL )
X509_free(cert);
#ifdef _WIN32
ul = 1;
ioctlsocket(s, FIONBIO, &ul);
#else
fcntl(s,F_SETFL,O_NONBLOCK);
#endif
return conn;
}

View File

@ -77,5 +77,5 @@ void _ssl_cert_free(SSL_CERT cert);
void ssl_init(void);
char * getSSLErr(void);
extern struct sockfuncs sso;
#endif // __my_ssl_h__

View File

@ -99,10 +99,14 @@ static void addSSL(
SOCKET srv_s, SSL_CONN srv_conn,
struct clientparam* param){
if(!param->sostate) return;
if (cli_s != INVALID_SOCKET){
SOSTATE->cli.s = cli_s;
SOSTATE->cli.conn = cli_conn;
}
if (srv_s != INVALID_SOCKET){
SOSTATE->srv.s = srv_s;
SOSTATE->srv.conn = srv_conn;
}
}
void delSSL(void *state, SOCKET s){
@ -271,7 +275,6 @@ SSL_CONN dosrvcon(struct clientparam* param, SSL_CERT* cert){
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;
}
@ -648,10 +651,10 @@ static void ssl_filter_close(void *fo){
free(fo);
}
static struct filter ssl_filter_mitm = {
static struct filter ssl_filter = {
NULL,
"ssl filter",
"mitm",
"ssl_filter",
ssl_filter_open,
ssl_filter_client,
NULL, NULL, NULL, ssl_filter_predata, NULL, NULL,
@ -659,100 +662,73 @@ static struct filter ssl_filter_mitm = {
ssl_filter_close
};
int filterset = 0;
static void setfilters(){
filterset++;
if(filterset > 1) return;
ssl_filter.next = pl->conf->filters;
pl->conf->filters = &ssl_filter;
sso = *pl->so;
}
static void unsetfilters(){
struct filter * sf;
if(!filterset) return;
filterset--;
if(filterset > 0) return;
if(pl->conf->filters == &ssl_filter) pl->conf->filters = ssl_filter.next;
else for(sf = pl->conf->filters; sf && sf->next; sf=sf->next){
if(sf->next == &ssl_filter) {
sf->next = ssl_filter.next;
break;
}
}
}
static int h_mitm(int argc, unsigned char **argv){
if(mitm) return 1;
if(mitm) return 0;
if(serv) return 2;
ssl_filter_mitm.next = pl->conf->filters;
pl->conf->filters = &ssl_filter_mitm;
sso = *pl->so;
mitm = 1;
setfilters();
return 0;
}
static int h_nomitm(int argc, unsigned char **argv){
struct filter * sf;
if(!mitm) return 1;
if(pl->conf->filters == &ssl_filter_mitm) pl->conf->filters = ssl_filter_mitm.next;
else for(sf = pl->conf->filters; sf && sf->next; sf=sf->next){
if(sf->next == &ssl_filter_mitm) {
sf->next = ssl_filter_mitm.next;
break;
}
}
if(!mitm) return 0;
mitm = 0;
unsetfilters();
return 0;
}
static struct filter ssl_filter_serv = {
NULL,
"ssl filter",
"serv",
ssl_filter_open,
ssl_filter_client,
NULL, NULL, NULL, NULL, NULL, NULL,
ssl_filter_clear,
ssl_filter_close
};
static int h_serv(int argc, unsigned char **argv){
if(serv) return 1;
if(serv) return 0;
if(mitm) return 2;
ssl_filter_serv.next = pl->conf->filters;
pl->conf->filters = &ssl_filter_serv;
sso = *pl->so;
serv = 1;
setfilters();
return 0;
}
static int h_noserv(int argc, unsigned char **argv){
struct filter * sf;
if(!serv) return 1;
if(!serv) return 0;
serv = 0;
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){
if(sf->next == &ssl_filter_serv) {
sf->next = ssl_filter_serv.next;
break;
}
}
unsetfilters();
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;
if(cli) return 0;
if(mitm) return 2;
cli = 1;
setfilters();
return 0;
}
static int h_nocli(int argc, unsigned char **argv){
struct filter * sf;
if(!cli) return 1;
if(!cli) return 0;
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;
}
}
unsetfilters();
return 0;
}
@ -993,9 +969,10 @@ static struct commands ssl_commandhandlers[] = {
PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink,
int argc, char** argv){
mitm = 0;
serv = 0;
cli = 0;
h_nomitm(0, NULL);
h_noserv(0, NULL);
h_nocli(0, NULL);
pl = pluginlink;