mirror of
https://github.com/moparisthebest/curl
synced 2025-01-11 05:58:01 -05:00
gskit: use the generic Curl_socketpair
This commit is contained in:
parent
9c76f694de
commit
1b843bb5ed
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user