diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/vtls/gskit.c | 98 |
1 files changed, 3 insertions, 95 deletions
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c index 296362e52..32153dd07 100644 --- a/lib/vtls/gskit.c +++ b/lib/vtls/gskit.c @@ -26,6 +26,8 @@ #include <gskssl.h> #include <qsoasync.h> +#undef HAVE_SOCKETPAIR /* because the native one isn't good enough */ +#include "socketpair.h" /* Some symbols are undefined/unsupported on OS400 versions < V7R1. */ #ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST @@ -511,100 +513,6 @@ static void close_async_handshake(struct ssl_connect_data *connssl) BACKEND->iocport = -1; } -/* SSL over SSL - * Problems: - * 1) GSKit can only perform SSL on an AF_INET or AF_INET6 stream socket. To - * pipe an SSL stream into another, it is therefore needed to have a pair - * of such communicating sockets and handle the pipelining explicitly. - * 2) OS/400 socketpair() is only implemented for domain AF_UNIX, thus cannot - * be used to produce the pipeline. - * The solution is to simulate socketpair() for AF_INET with low-level API - * listen(), bind() and connect(). - */ - -static int -inetsocketpair(int sv[2]) -{ - int lfd; /* Listening socket. */ - int sfd; /* Server socket. */ - int cfd; /* Client socket. */ - int len; - struct sockaddr_in addr1; - struct sockaddr_in addr2; - - /* Create listening socket on a local dynamic port. */ - lfd = socket(AF_INET, SOCK_STREAM, 0); - if(lfd < 0) - return -1; - memset((char *) &addr1, 0, sizeof(addr1)); - addr1.sin_family = AF_INET; - addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - addr1.sin_port = 0; - if(bind(lfd, (struct sockaddr *) &addr1, sizeof(addr1)) || - listen(lfd, 2) < 0) { - close(lfd); - return -1; - } - - /* Get the allocated port. */ - len = sizeof(addr1); - if(getsockname(lfd, (struct sockaddr *) &addr1, &len) < 0) { - close(lfd); - return -1; - } - - /* Create the client socket. */ - cfd = socket(AF_INET, SOCK_STREAM, 0); - if(cfd < 0) { - close(lfd); - return -1; - } - - /* Request unblocking connection to the listening socket. */ - curlx_nonblock(cfd, TRUE); - if(connect(cfd, (struct sockaddr *) &addr1, sizeof(addr1)) < 0 && - errno != EINPROGRESS) { - close(lfd); - close(cfd); - return -1; - } - - /* Get the client dynamic port for intrusion check below. */ - len = sizeof(addr2); - if(getsockname(cfd, (struct sockaddr *) &addr2, &len) < 0) { - close(lfd); - close(cfd); - return -1; - } - - /* Accept the incoming connection and get the server socket. */ - curlx_nonblock(lfd, TRUE); - for(;;) { - len = sizeof(addr1); - sfd = accept(lfd, (struct sockaddr *) &addr1, &len); - if(sfd < 0) { - close(lfd); - close(cfd); - return -1; - } - - /* Check for possible intrusion from an external process. */ - if(addr1.sin_addr.s_addr == addr2.sin_addr.s_addr && - addr1.sin_port == addr2.sin_port) - break; - - /* Intrusion: reject incoming connection. */ - close(sfd); - } - - /* Done, return sockets and succeed. */ - close(lfd); - curlx_nonblock(cfd, FALSE); - sv[0] = cfd; - sv[1] = sfd; - return 0; -} - static int pipe_ssloverssl(struct connectdata *conn, int sockindex, int directions) { @@ -855,7 +763,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex) /* Establish a pipelining socket pair for SSL over SSL. */ if(conn->proxy_ssl[sockindex].use) { - if(inetsocketpair(sockpair)) + if(Curl_socketpair(0, 0, 0, sockpair)) return CURLE_SSL_CONNECT_ERROR; BACKEND->localfd = sockpair[0]; BACKEND->remotefd = sockpair[1]; |