]> granicus.if.org Git - curl/commitdiff
gskit: use the generic Curl_socketpair
authorDaniel Stenberg <daniel@haxx.se>
Mon, 7 Oct 2019 06:25:53 +0000 (08:25 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 10 Oct 2019 09:04:38 +0000 (11:04 +0200)
lib/vtls/gskit.c

index 296362e52bcab6a9a0236756617e25ab9dc85140..32153dd0710c1da16400cf1d821fc093bc76cce0 100644 (file)
@@ -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];