Compare commits

..

No commits in common. "d014bb114956c849438a69e20b1af60554682776" and "b5ab5b890676c0c93f65286179ffec375bc459f9" have entirely different histories.

3 changed files with 112 additions and 96 deletions

View File

@ -196,6 +196,14 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config,
*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;
@ -219,28 +227,8 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config,
return NULL; return NULL;
} }
if(hostname && *hostname)SSL_set_tlsext_host_name(conn->ssl, hostname); if(hostname && *hostname)SSL_set_tlsext_host_name(conn->ssl, hostname);
do {
struct pollfd fds[1] = {{}};
int sslerr;
err = SSL_connect(conn->ssl); err = SSL_connect(conn->ssl);
if (err != -1) break; if ( err == -1 ) {
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(); *errSSL = getSSLErr();
ssl_conn_free(conn); ssl_conn_free(conn);
return NULL; return NULL;
@ -257,6 +245,12 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config,
*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;
} }
@ -267,6 +261,15 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert
ssl_conn *conn; ssl_conn *conn;
unsigned long ul; 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;
@ -293,38 +296,28 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert
} }
SSL_set_fd(conn->ssl, s); SSL_set_fd(conn->ssl, s);
do {
struct pollfd fds[1] = {{}};
int sslerr;
err = SSL_accept(conn->ssl); err = SSL_accept(conn->ssl);
if (err != -1) break; if ( err <= 0 ) {
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(); *errSSL = getSSLErr();
ssl_conn_free(conn); ssl_conn_free(conn);
return NULL; return NULL;
} }
//
// client certificate
// TODO: is it required?
//
cert = SSL_get_peer_certificate(conn->ssl); cert = SSL_get_peer_certificate(conn->ssl);
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

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

View File

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