예제 #1
0
파일: proxy.c 프로젝트: DimStar77/libproxy
int
main(int argc, char **argv)
{
	int i;
	char url[102400]; // Should be plently long for most URLs
	char **proxies;

	/* Create the proxy factory object */
	pxProxyFactory *pf = px_proxy_factory_new();
	if (!pf)
	{
		fprintf(stderr, "An unknown error occurred!\n");
		return 1;
	}
	/* User entered some arguments on startup. skip interactive */
	if (argc > 1)
	{
		for (i=1; i < argc ; i++)
		{
			/*
			 * Get an array of proxies to use. These should be used
			 * in the order returned. Only move on to the next proxy
			 * if the first one fails (etc).
			 */
			proxies = px_proxy_factory_get_proxies(pf, argv[i]);
			print_proxies(proxies);
			px_proxy_factory_free_proxies(proxies);
		}
	}
	/* Interactive mode */
	else
	{
		/* For each URL we read on STDIN, get the proxies to use */
		for (url[0] = '\0' ; fgets(url, 102400, stdin) != NULL ; )
		{
			if (url[strlen(url)-1] == '\n') url[strlen(url)-1] = '\0';

			/*
			 * Get an array of proxies to use. These should be used
			 * in the order returned. Only move on to the next proxy
			 * if the first one fails (etc).
			 */
			proxies = px_proxy_factory_get_proxies(pf, url);
			print_proxies(proxies);
			px_proxy_factory_free_proxies(proxies);
		}
	}
	/* Destroy the proxy factory object */
	px_proxy_factory_free(pf);
	return 0;
}
static void
get_libproxy_proxies (GTask        *task,
		      gpointer      source_object,
		      gpointer      task_data,
		      GCancellable *cancellable)
{
  GLibProxyResolver *resolver = source_object;
  const gchar *uri = task_data;
  GError *error = NULL;
  gchar **proxies;

  if (g_task_return_error_if_cancelled (task))
    return;

  proxies = px_proxy_factory_get_proxies (resolver->factory, uri);
  if (proxies)
    {
      /* We always copy to be able to translate "socks" entry into
       * three entries ("socks5", "socks4a", "socks4").
       */
      g_task_return_pointer (task, copy_proxies (proxies), (GDestroyNotify) g_strfreev);
      free_libproxy_proxies (proxies);
    }
  else
    {
      g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
			   _("Proxy resolver internal error."));
      g_task_return_error (task, error);
    }
}
예제 #3
0
nsresult
nsUnixSystemProxySettings::GetProxyForURI(const nsACString & aSpec,
                                          const nsACString & aScheme,
                                          const nsACString & aHost,
                                          const int32_t      aPort,
                                          nsACString & aResult)
{
  nsresult rv;

  if (!mProxyFactory) {
    mProxyFactory = px_proxy_factory_new();
  }
  NS_ENSURE_TRUE(mProxyFactory, NS_ERROR_NOT_AVAILABLE);

  char **proxyArray = nullptr;
  proxyArray = px_proxy_factory_get_proxies(mProxyFactory,
                                            PromiseFlatCString(aSpec).get());
  NS_ENSURE_TRUE(proxyArray, NS_ERROR_NOT_AVAILABLE);

  // Translate libproxy's output to PAC string as expected
  // libproxy returns an array of proxies in the format:
  // <procotol>://[username:password@]proxy:port
  // or
  // direct://
  //
  // PAC format: "PROXY proxy1.foo.com:8080; PROXY proxy2.foo.com:8080; DIRECT"
  // but nsISystemProxySettings allows "PROXY http://proxy.foo.com:8080" as well.

  int c = 0;
  while (proxyArray[c] != nullptr) {
    if (!aResult.IsEmpty()) {
      aResult.AppendLiteral("; ");
    }

    // figure out the scheme, and we can't use nsIIOService::NewURI because
    // this is not the main thread.
    char *colon = strchr (proxyArray[c], ':');
    uint32_t schemelen = colon ? colon - proxyArray[c] : 0;
    if (schemelen < 1) {
      c++;
      continue;
    }

    if (schemelen == 6 && !strncasecmp(proxyArray[c], "direct", 6)) {
      aResult.AppendLiteral("DIRECT");
    }
    else {
      aResult.AppendLiteral("PROXY ");
      aResult.Append(proxyArray[c]);
    }

    c++;
  }

  PR_Free(proxyArray);
  return NS_OK;
}
예제 #4
0
파일: certs.c 프로젝트: dagwieers/eid-mw
static const void* perform_ocsp_request(char* url, void* data, long datlen, long* retlen, void** handle) {
	CURL *curl;
	CURLcode curl_res;
	struct curl_slist *list = NULL;
	char** proxies = px_proxy_factory_get_proxies(pf, url);
	int i;
	struct recvdata *dat;
	void* retval;

	dat = calloc(sizeof(struct recvdata), 1);
	curl_slist_append(list, "Content-Type: application/ocsp-request");
	curl = curl_easy_init();
	curl_easy_setopt(curl, CURLOPT_URL, url);
	curl_easy_setopt(curl, CURLOPT_POST, (long)1);
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
	curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, datlen);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, appendmem);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, dat);
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
	i=0;
	do {
		if((curl_res = curl_easy_perform(curl)) != CURLE_OK) {
			uilog(EID_VWR_LOG_COARSE, "Could not perform OCSP request (with proxy: %s): %s",
					proxies[i] ? "none" : proxies[i],
					curl_easy_strerror(curl_res));
		}
		if(!strcmp(proxies[i], "direct://")) {
			// skip that
			i++;
		}
		if(proxies[i] == NULL) {
			curl_easy_setopt(curl, CURLOPT_PROXY, "");
		} else {
			curl_easy_setopt(curl, CURLOPT_PROXY, proxies[i]);
		}
	} while(proxies[i++] != NULL && curl_res != CURLE_OK);

	for(i=0; proxies[i]; i++) {
		free(proxies[i]);
	}
	free(proxies);

	if(curl_res != CURLE_OK) {
		free(dat->data);
		dat->len = 0;
		dat->data = NULL;
	}
	retval = dat->data;
	*retlen = dat->len;

	free(dat);
	curl_easy_cleanup(curl);
	curl_slist_free_all(list);

	*handle = retval;
	return retval;
}
static guint
get_proxy_for_uri (SoupURI *uri, SoupURI **proxy_uri)
{
	char *uristr, **proxies;
	gboolean got_proxy;
	int i;

	*proxy_uri = NULL;

	/* resolver_gnome is locked */

	uristr = soup_uri_to_string (uri, FALSE);
	proxies = px_proxy_factory_get_proxies (libproxy_factory, uristr);
	g_free (uristr);

	if (!proxies)
		return SOUP_STATUS_OK;

	got_proxy = FALSE;
	for (i = 0; proxies[i]; i++) {
		if (!strcmp (proxies[i], "direct://")) {
			got_proxy = TRUE;
			break;
		}
		if (strncmp (proxies[i], "http://", 7) == 0) {
			*proxy_uri = soup_uri_new (proxies[i]);
			got_proxy = TRUE;
			break;
		}
	}
	for (i = 0; proxies[i]; i++)
		free (proxies[i]);
	free (proxies);

	if (got_proxy) {
		if (*proxy_uri && proxy_user) {
			soup_uri_set_user (*proxy_uri, proxy_user);
			soup_uri_set_password (*proxy_uri, proxy_password);
		}

		return SOUP_STATUS_OK;
	} else
		return SOUP_STATUS_CANT_RESOLVE_PROXY;
}
예제 #6
0
int main(int argc, char *argv[])
{
	pxProxyFactory *pf;
	int i;

	if (argc < 2) {
		printf("Usage: %s <url> [url*]\n", argv[0]);
		return 1;
	}

	pf = px_proxy_factory_new();
	if (!pf) {
		fprintf(stderr, "Failed to create proxy factory\n");
		return 1;
	}

	for (i = 1; i < argc; i++) {
		char **result;
		int n;

		result = px_proxy_factory_get_proxies(pf, argv[i]);
		if (!result) {
			fprintf(stderr, "Failed to get proxy for %s\n",
								argv[i]);
			continue;
		}

		for (n = 0; result[n]; n++) {
			printf("%s%s", result[n], result[n + 1] ? " " : "\n");
			free(result[n]);
		}

		free(result);
	}

	px_proxy_factory_free(pf);

	return 0;
}
예제 #7
0
파일: ssl.c 프로젝트: neshema/openconnect
int connect_https_socket(struct openconnect_info *vpninfo)
{
    int ssl_sock = -1;
    int err;

    if (!vpninfo->port)
        vpninfo->port = 443;

    if (vpninfo->peer_addr) {
reconnect:
#ifdef SOCK_CLOEXEC
        ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_IP);
        if (ssl_sock < 0)
#endif
        {
            ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM, IPPROTO_IP);
            if (ssl_sock < 0)
                goto reconn_err;
            set_fd_cloexec(ssl_sock);
        }
        if (cancellable_connect(vpninfo, ssl_sock, vpninfo->peer_addr, vpninfo->peer_addrlen)) {
reconn_err:
            if (vpninfo->proxy) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to reconnect to proxy %s\n"),
                             vpninfo->proxy);
            } else {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to reconnect to host %s\n"),
                             vpninfo->hostname);
            }
            if (ssl_sock >= 0)
                closesocket(ssl_sock);
            return -EINVAL;
        }
    } else {
        struct addrinfo hints, *result, *rp;
        char *hostname;
        char port[6];

        memset(&hints, 0, sizeof(struct addrinfo));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
        hints.ai_protocol = 0;
        hints.ai_canonname = NULL;
        hints.ai_addr = NULL;
        hints.ai_next = NULL;

        /* The 'port' variable is a string because it's easier
           this way than if we pass NULL to getaddrinfo() and
           then try to fill in the numeric value into
           different types of returned sockaddr_in{6,}. */
#ifdef LIBPROXY_HDR
        if (vpninfo->proxy_factory) {
            char *url;
            char **proxies;
            int i = 0;

            free(vpninfo->proxy_type);
            vpninfo->proxy_type = NULL;
            free(vpninfo->proxy);
            vpninfo->proxy = NULL;

            if (vpninfo->port == 443)
                i = asprintf(&url, "https://%s/%s", vpninfo->hostname,
                             vpninfo->urlpath?:"");
            else
                i = asprintf(&url, "https://%s:%d/%s", vpninfo->hostname,
                             vpninfo->port, vpninfo->urlpath?:"");
            if (i == -1)
                return -ENOMEM;

            proxies = px_proxy_factory_get_proxies(vpninfo->proxy_factory,
                                                   url);

            i = 0;
            while (proxies && proxies[i]) {
                if (!vpninfo->proxy &&
                        (!strncmp(proxies[i], "http://", 7) ||
                         !strncmp(proxies[i], "socks://", 8) ||
                         !strncmp(proxies[i], "socks5://", 9)))
                    internal_parse_url(proxies[i], &vpninfo->proxy_type,
                                       &vpninfo->proxy, &vpninfo->proxy_port,
                                       NULL, 0);
                i++;
            }
            free(url);
            free(proxies);
            if (vpninfo->proxy)
                vpn_progress(vpninfo, PRG_DEBUG,
                             _("Proxy from libproxy: %s://%s:%d/\n"),
                             vpninfo->proxy_type, vpninfo->proxy, vpninfo->port);
        }
예제 #8
0
void ne_session_system_proxy(ne_session *sess, unsigned int flags)
{
#ifdef HAVE_LIBPROXY
    pxProxyFactory *pxf = px_proxy_factory_new();
    struct host_info *hi, **lasthi;
    char *url, **proxies;
    ne_uri uri;
    unsigned n;

    free_proxies(sess);

    /* Create URI for session to pass off to libproxy */
    memset(&uri, 0, sizeof uri);
    ne_fill_server_uri(sess, &uri);

    uri.path = "/"; /* make valid URI structure. */
    url = ne_uri_unparse(&uri);
    uri.path = NULL;

    /* Get list of pseudo-URIs from libproxy: */
    proxies = px_proxy_factory_get_proxies(pxf, url);
    
    for (n = 0, lasthi = &sess->proxies; proxies[n]; n++) {
        enum proxy_type ptype;

        ne_uri_free(&uri);

        NE_DEBUG(NE_DBG_HTTP, "sess: libproxy #%u=%s\n", 
                 n, proxies[n]);

        if (ne_uri_parse(proxies[n], &uri))
            continue;
        
        if (!uri.scheme) continue;

        if (ne_strcasecmp(uri.scheme, "http") == 0)
            ptype = PROXY_HTTP;
        else if (ne_strcasecmp(uri.scheme, "socks") == 0)
            ptype = PROXY_SOCKS;
        else if (ne_strcasecmp(uri.scheme, "direct") == 0)
            ptype = PROXY_NONE;
        else
            continue;

        /* Hostname/port required for http/socks schemes. */
        if (ptype != PROXY_NONE && !(uri.host && uri.port))
            continue;
        
        /* Do nothing if libproxy returned only a single "direct://"
         * entry -- a single "direct" (noop) proxy is equivalent to
         * having none. */
        if (n == 0 && proxies[1] == NULL && ptype == PROXY_NONE)
            break;

        NE_DEBUG(NE_DBG_HTTP, "sess: Got proxy %s://%s:%d\n",
                 uri.scheme, uri.host ? uri.host : "(none)",
                 uri.port);
        
        hi = *lasthi = ne_calloc(sizeof *hi);
        
        if (ptype == PROXY_NONE) {
            /* A "direct" URI requires an attempt to connect directly to
             * the origin server, so dup the server details. */
            set_hostinfo(hi, ptype, sess->server.hostname,
                         sess->server.port);
        }
        else {
            /* SOCKS/HTTP proxy. */
            set_hostinfo(hi, ptype, uri.host, uri.port);

            if (ptype == PROXY_HTTP)
                sess->any_proxy_http = 1;
            else if (ptype == PROXY_SOCKS)
                sess->socks_ver = NE_SOCK_SOCKSV5;
        }

        lasthi = &hi->next;
    }

    /* Free up the proxies array: */
    for (n = 0; proxies[n]; n++)
        free(proxies[n]);
    free(proxies[n]);

    ne_free(url);
    ne_uri_free(&uri);
    px_proxy_factory_free(pxf);
#endif
}
int trg_client_populate_with_settings(TrgClient * tc)
{
    TrgClientPrivate *priv = tc->priv;
    TrgPrefs *prefs = priv->prefs;

    gint port;
    gchar *host, *path;
#ifdef HAVE_LIBPROXY
    pxProxyFactory *pf = NULL;
#endif

    g_mutex_lock(&priv->configMutex);

    trg_prefs_set_connection(prefs, trg_prefs_get_profile(prefs));

    g_free(priv->url);
    priv->url = NULL;

    g_free(priv->username);
    priv->username = NULL;

    g_free(priv->password);
    priv->password = NULL;

    port =
        trg_prefs_get_int(prefs, TRG_PREFS_KEY_PORT, TRG_PREFS_CONNECTION);

    host = trg_prefs_get_string(prefs, TRG_PREFS_KEY_HOSTNAME,
                                TRG_PREFS_CONNECTION);
    path = trg_prefs_get_string(prefs, TRG_PREFS_KEY_RPC_URL_PATH, TRG_PREFS_CONNECTION);

    if (!host || strlen(host) < 1) {
        g_free(host);
        g_mutex_unlock(&priv->configMutex);
        return TRG_NO_HOSTNAME_SET;
    }
#ifndef CURL_NO_SSL
    priv->ssl = trg_prefs_get_bool(prefs, TRG_PREFS_KEY_SSL,
                                   TRG_PREFS_CONNECTION);
    priv->ssl_validate = trg_prefs_get_bool(prefs, TRG_PREFS_KEY_SSL_VALIDATE,
                                   TRG_PREFS_CONNECTION);

#else
    priv->ssl = FALSE;
#endif


    priv->url = g_strdup_printf("%s://%s:%d%s",
                                priv->ssl ? HTTPS_URI_PREFIX :
                                HTTP_URI_PREFIX, host, port, path);
    g_free(host);
    g_free(path);

    priv->username = trg_prefs_get_string(prefs, TRG_PREFS_KEY_USERNAME,
                                          TRG_PREFS_CONNECTION);

    priv->password = trg_prefs_get_string(prefs, TRG_PREFS_KEY_PASSWORD,
                                          TRG_PREFS_CONNECTION);

    g_free(priv->proxy);
    priv->proxy = NULL;

#ifdef HAVE_LIBPROXY
    if ((pf = px_proxy_factory_new())) {
        char **proxies = px_proxy_factory_get_proxies(pf, priv->url);
        int i;

        for (i = 0; proxies[i]; i++) {
            if (g_str_has_prefix(proxies[i], HTTP_URI_PREFIX)
                || g_str_has_prefix(proxies[i], HTTPS_URI_PREFIX)) {
                g_free(priv->proxy);
                priv->proxy = proxies[i];
            } else {
                g_free(proxies[i]);
            }
        }

        g_free(proxies);
        px_proxy_factory_free(pf);
    }
#endif

    priv->configSerial++;
    g_mutex_unlock(&priv->configMutex);
    return 0;
}
예제 #10
0
파일: ssl.c 프로젝트: cernekee/openconnect
int connect_https_socket(struct openconnect_info *vpninfo)
{
	int ssl_sock = -1;
	int err;

	if (!vpninfo->port)
		vpninfo->port = 443;

	/* If we're talking to a server which told us it has dynamic DNS, don't
	   just re-use its previous IP address. If we're talking to a proxy, we
	   can use *its* previous IP address. We expect it'll re-do the DNS
	   lookup for the server anyway. */
	if (vpninfo->peer_addr && (!vpninfo->is_dyndns || vpninfo->proxy)) {
	reconnect:
#ifdef SOCK_CLOEXEC
		ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_IP);
		if (ssl_sock < 0)
#endif
		{
			ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM, IPPROTO_IP);
			if (ssl_sock < 0) {
#ifdef _WIN32
				err = WSAGetLastError();
#else
				err = -errno;
#endif
				goto reconn_err;
			}
			set_fd_cloexec(ssl_sock);
		}
		err = cancellable_connect(vpninfo, ssl_sock, vpninfo->peer_addr, vpninfo->peer_addrlen);
		if (err) {
			char *errstr;
		reconn_err:
#ifdef _WIN32
			if (err > 0)
				errstr = openconnect__win32_strerror(err);
			else
#endif
				errstr = strerror(-err);
			if (vpninfo->proxy) {
				vpn_progress(vpninfo, PRG_ERR,
					     _("Failed to reconnect to proxy %s: %s\n"),
					     vpninfo->proxy, errstr);
			} else {
				vpn_progress(vpninfo, PRG_ERR,
					     _("Failed to reconnect to host %s: %s\n"),
					     vpninfo->hostname, errstr);
			}
#ifdef _WIN32
			if (err > 0)
				free(errstr);
#endif
			if (ssl_sock >= 0)
				closesocket(ssl_sock);
			ssl_sock = -EINVAL;
			goto out;
		}
	} else {
		struct addrinfo hints, *result, *rp;
		char *hostname;
		char port[6];

		memset(&hints, 0, sizeof(struct addrinfo));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
		hints.ai_protocol = 0;
		hints.ai_canonname = NULL;
		hints.ai_addr = NULL;
		hints.ai_next = NULL;

		/* The 'port' variable is a string because it's easier
		   this way than if we pass NULL to getaddrinfo() and
		   then try to fill in the numeric value into
		   different types of returned sockaddr_in{6,}. */
#ifdef LIBPROXY_HDR
		if (vpninfo->proxy_factory) {
			struct oc_text_buf *url_buf = buf_alloc();
			char **proxies;
			int i = 0;

			free(vpninfo->proxy_type);
			vpninfo->proxy_type = NULL;
			free(vpninfo->proxy);
			vpninfo->proxy = NULL;

			buf_append(url_buf, "https://%s", vpninfo->hostname);
			if (vpninfo->port != 443)
				buf_append(url_buf, ":%d", vpninfo->port);
			buf_append(url_buf, "/%s", vpninfo->urlpath?:"");
			if (buf_error(url_buf)) {
				buf_free(url_buf);
				ssl_sock = -ENOMEM;
				goto out;
			}

			proxies = px_proxy_factory_get_proxies(vpninfo->proxy_factory,
							       url_buf->data);
			i = 0;
			while (proxies && proxies[i]) {
				if (!vpninfo->proxy &&
				    (!strncmp(proxies[i], "http://", 7) ||
				     !strncmp(proxies[i], "socks://", 8) ||
				     !strncmp(proxies[i], "socks5://", 9)))
					internal_parse_url(proxies[i], &vpninfo->proxy_type,
						  &vpninfo->proxy, &vpninfo->proxy_port,
						  NULL, 0);
				i++;
			}
			buf_free(url_buf);
			free(proxies);
			if (vpninfo->proxy)
				vpn_progress(vpninfo, PRG_DEBUG,
					     _("Proxy from libproxy: %s://%s:%d/\n"),
					     vpninfo->proxy_type, vpninfo->proxy, vpninfo->port);
		}
#endif
		if (vpninfo->proxy) {
			hostname = vpninfo->proxy;
			snprintf(port, 6, "%d", vpninfo->proxy_port);
		} else {
			hostname = vpninfo->hostname;
			snprintf(port, 6, "%d", vpninfo->port);
		}

		if (hostname[0] == '[' && hostname[strlen(hostname)-1] == ']') {
			hostname = strndup(hostname + 1, strlen(hostname) - 2);
			if (!hostname) {
				ssl_sock = -ENOMEM;
				goto out;
			}
			hints.ai_flags |= AI_NUMERICHOST;
		}

		if (vpninfo->getaddrinfo_override)
			err = vpninfo->getaddrinfo_override(vpninfo->cbdata, hostname, port, &hints, &result);
		else
			err = getaddrinfo(hostname, port, &hints, &result);

		if (err) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("getaddrinfo failed for host '%s': %s\n"),
				     hostname, gai_strerror(err));
			if (hints.ai_flags & AI_NUMERICHOST)
				free(hostname);
			ssl_sock = -EINVAL;
			/* If we were just retrying for dynamic DNS, reconnct using
			   the previously-known IP address */
			if (vpninfo->peer_addr) {
				vpn_progress(vpninfo, PRG_ERR,
					     _("Reconnecting to DynDNS server using previously cached IP address\n"));
				goto reconnect;
			}
			goto out;
		}
		if (hints.ai_flags & AI_NUMERICHOST)
			free(hostname);

		for (rp = result; rp ; rp = rp->ai_next) {
			char host[80];

			host[0] = 0;
			if (!getnameinfo(rp->ai_addr, rp->ai_addrlen, host,
					 sizeof(host), NULL, 0, NI_NUMERICHOST))
				vpn_progress(vpninfo, PRG_DEBUG, vpninfo->proxy_type ?
						     _("Attempting to connect to proxy %s%s%s:%s\n") :
						     _("Attempting to connect to server %s%s%s:%s\n"),
					     rp->ai_family == AF_INET6 ? "[" : "",
					     host,
					     rp->ai_family == AF_INET6 ? "]" : "",
					     port);

			ssl_sock = socket(rp->ai_family, rp->ai_socktype,
					  rp->ai_protocol);
			if (ssl_sock < 0)
				continue;
			set_fd_cloexec(ssl_sock);
			err = cancellable_connect(vpninfo, ssl_sock, rp->ai_addr, rp->ai_addrlen);
			if (!err) {
				/* Store the peer address we actually used, so that DTLS can
				   use it again later */
				free(vpninfo->ip_info.gateway_addr);
				vpninfo->ip_info.gateway_addr = NULL;

				if (host[0]) {
					vpninfo->ip_info.gateway_addr = strdup(host);
					vpn_progress(vpninfo, PRG_INFO, _("Connected to %s%s%s:%s\n"),
						     rp->ai_family == AF_INET6 ? "[" : "",
						     host,
						     rp->ai_family == AF_INET6 ? "]" : "",
						     port);
				}

				free(vpninfo->peer_addr);
				vpninfo->peer_addrlen = 0;
				vpninfo->peer_addr = malloc(rp->ai_addrlen);
				if (!vpninfo->peer_addr) {
					vpn_progress(vpninfo, PRG_ERR,
						     _("Failed to allocate sockaddr storage\n"));
					closesocket(ssl_sock);
					ssl_sock = -ENOMEM;
					goto out;
				}
				vpninfo->peer_addrlen = rp->ai_addrlen;
				memcpy(vpninfo->peer_addr, rp->ai_addr, rp->ai_addrlen);
				/* If no proxy, ensure that we output *this* IP address in
				 * authentication results because we're going to need to
				 * reconnect to the *same* server from the rotation. And with
				 * some trick DNS setups, it might possibly be a "rotation"
				 * even if we only got one result from getaddrinfo() this
				 * time.
				 *
				 * If there's a proxy, we're kind of screwed; we can't know
				 * which IP address we connected to. Perhaps we ought to do
				 * the DNS lookup locally and connect to a specific IP? */
				if (!vpninfo->proxy && host[0]) {
					char *p = malloc(strlen(host) + 3);
					if (p) {
						free(vpninfo->unique_hostname);
						vpninfo->unique_hostname = p;
						if (rp->ai_family == AF_INET6)
							*p++ = '[';
						memcpy(p, host, strlen(host));
						p += strlen(host);
						if (rp->ai_family == AF_INET6)
							*p++ = ']';
						*p = 0;
					}
				}
				break;
			}
			if (host[0]) {
				char *errstr;
#ifdef _WIN32
				if (err > 0)
					errstr = openconnect__win32_strerror(err);
				else
#endif
					errstr = strerror(-err);

				vpn_progress(vpninfo, PRG_INFO, _("Failed to connect to %s%s%s:%s: %s\n"),
					     rp->ai_family == AF_INET6 ? "[" : "",
					     host,
					     rp->ai_family == AF_INET6 ? "]" : "",
					     port, errstr);
#ifdef _WIN32
				if (err > 0)
					free(errstr);
#endif
			}
			closesocket(ssl_sock);
			ssl_sock = -1;

			/* If we're in DynDNS mode but this *was* the cached IP address,
			 * don't bother falling back to it if it didn't work. */
			if (vpninfo->peer_addr && vpninfo->peer_addrlen == rp->ai_addrlen &&
			    match_sockaddr(vpninfo->peer_addr, rp->ai_addr)) {
				vpn_progress(vpninfo, PRG_TRACE,
					     _("Forgetting non-functional previous peer address\n"));
				free(vpninfo->peer_addr);
				vpninfo->peer_addr = 0;
				vpninfo->peer_addrlen = 0;
				free(vpninfo->ip_info.gateway_addr);
				vpninfo->ip_info.gateway_addr = NULL;
			}
		}
		freeaddrinfo(result);

		if (ssl_sock < 0) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to connect to host %s\n"),
				     vpninfo->proxy?:vpninfo->hostname);
			ssl_sock = -EINVAL;
			if (vpninfo->peer_addr) {
				vpn_progress(vpninfo, PRG_ERR,
					     _("Reconnecting to DynDNS server using previously cached IP address\n"));
				goto reconnect;
			}
			goto out;
		}
	}
예제 #11
0
nsresult
nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult)
{
  nsresult rv;

  if (!mProxyFactory) {
    mProxyFactory = px_proxy_factory_new();
  }
  NS_ENSURE_TRUE(mProxyFactory, NS_ERROR_NOT_AVAILABLE);

  nsCOMPtr<nsIIOService> ios = do_GetIOService(&rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCAutoString spec;
  rv = aURI->GetSpec(spec);
  NS_ENSURE_SUCCESS(rv, rv);

  char **proxyArray = nsnull;
  proxyArray = px_proxy_factory_get_proxies(mProxyFactory, (char*)(spec.get()));
  NS_ENSURE_TRUE(proxyArray, NS_ERROR_NOT_AVAILABLE);

  // Translate libproxy's output to PAC string as expected
  // libproxy returns an array of proxies in the format:
  // <procotol>://[username:password@]proxy:port
  // or
  // direct://
  //
  // PAC format: "PROXY proxy1.foo.com:8080; PROXY proxy2.foo.com:8080; DIRECT"
  int c = 0;
  while (proxyArray[c] != NULL) {
    if (!aResult.IsEmpty()) {
      aResult.AppendLiteral("; ");
    }

    bool isScheme = false;
    nsXPIDLCString schemeString;
    nsXPIDLCString hostPortString;
    nsCOMPtr<nsIURI> proxyURI;

    rv = ios->NewURI(nsDependentCString(proxyArray[c]),
                                        nsnull,
                                        nsnull,
                                        getter_AddRefs(proxyURI));
    if (NS_FAILED(rv)) {
      c++;
      continue;
    }

    proxyURI->GetScheme(schemeString);
    if (NS_SUCCEEDED(proxyURI->SchemeIs("http", &isScheme)) && isScheme) {
      schemeString.AssignLiteral("proxy");
    }
    aResult.Append(schemeString);
    if (NS_SUCCEEDED(proxyURI->SchemeIs("direct", &isScheme)) && !isScheme) {
      // Add the proxy URI only if it's not DIRECT
      proxyURI->GetHostPort(hostPortString);
      aResult.AppendLiteral(" ");
      aResult.Append(hostPortString);
    }

    c++;
  }

#ifdef DEBUG
  printf("returned PAC proxy string: %s\n", PromiseFlatCString(aResult).get());
#endif

  PR_Free(proxyArray);
  return NS_OK;
}