Commit cabd010d authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

ssh_connect: tunnel through HTTP proxy if requested

parent c55a0809
Loading
Loading
Loading
Loading
+29 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -90,6 +90,7 @@
#include "multiif.h"
#include "select.h"
#include "warnless.h"
#include "http_proxy.h"

#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -2659,6 +2660,33 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
     sessionhandle, deal with it */
  Curl_reset_reqproto(conn);

  if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
    /* for SSH over HTTP proxy */
    struct HTTP http_proxy;
    struct SSHPROTO *ssh_save;

    /* BLOCKING */
    /* We want "seamless" SSH operations through HTTP proxy tunnel */

    /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member
     * conn->proto.http; we want SSH through HTTP and we have to change the
     * member temporarily for connecting to the HTTP proxy. After
     * Curl_proxyCONNECT we have to set back the member to the original struct
     * SSH pointer
     */
    ssh_save = data->state.proto.ssh;
    memset(&http_proxy, 0, sizeof(http_proxy));
    data->state.proto.http = &http_proxy;

    result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
                               conn->host.name, conn->remote_port);

    data->state.proto.ssh = ssh_save;

    if(CURLE_OK != result)
      return result;
  }

  result = ssh_init(conn);
  if(result)
    return result;