Skip to content

Commit

Permalink
Handle IPv6 literal [] in connection, accept https:// URL for server
Browse files Browse the repository at this point in the history
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jan 1, 2010
1 parent dd4e643 commit 024e59a
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 30 deletions.
49 changes: 26 additions & 23 deletions http.c
Expand Up @@ -445,28 +445,36 @@ char *local_strcasestr(const char *haystack, const char *needle)
#define strcasestr local_strcasestr
#endif

int parse_url(char *url, char **res_proto, char **res_host, int *res_port, char **res_path)
int parse_url(char *url, char **res_proto, char **res_host, int *res_port,
char **res_path, int default_port)
{
char *proto = url;
char *host, *path, *port_str;
int port;

host = strstr(url, "://");
if (!host)
return -EINVAL;
*host = 0;
host += 3;

if (!strcasecmp(proto, "https"))
port = 443;
else if (!strcasecmp(proto, "http"))
port = 80;
else if (!strcasecmp(proto, "socks") ||
!strcasecmp(proto, "socks4") ||
!strcasecmp(proto, "socks5"))
port = 1080;
else
return -EPROTONOSUPPORT;
if (host) {
*host = 0;
host += 3;

if (!strcasecmp(proto, "https"))
port = 443;
else if (!strcasecmp(proto, "http"))
port = 80;
else if (!strcasecmp(proto, "socks") ||
!strcasecmp(proto, "socks4") ||
!strcasecmp(proto, "socks5"))
port = 1080;
else
return -EPROTONOSUPPORT;
} else {
if (default_port) {
proto = NULL;
port = default_port;
host = url;
} else
return -EINVAL;
}

path = strchr(host, '/');
if (path) {
Expand All @@ -485,14 +493,9 @@ int parse_url(char *url, char **res_proto, char **res_host, int *res_port, char
port = new_port;
}
}
/* Check for IPv6 literal (RFC2732) */
if (host[0] == '[' && host[strlen(host)-1] == ']') {
host[strlen(host)-1] = 0;
host++;
}

if (res_proto)
*res_proto = strdup(proto);
*res_proto = proto ? strdup(proto) : NULL;
if (res_host)
*res_host = strdup(host);
if (res_port)
Expand Down Expand Up @@ -582,7 +585,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
free(vpninfo->urlpath);
vpninfo->urlpath = NULL;

ret = parse_url(vpninfo->redirect_url, NULL, &host, &port, &vpninfo->urlpath);
ret = parse_url(vpninfo->redirect_url, NULL, &host, &port, &vpninfo->urlpath, 0);
if (ret) {
vpninfo->progress(vpninfo, PRG_ERR, "Failed to parse redirected URL '%s': %s\n",
vpninfo->redirect_url, strerror(-ret));
Expand Down
25 changes: 22 additions & 3 deletions main.c
Expand Up @@ -305,7 +305,7 @@ int main(int argc, char **argv)
case 'P': {
char *url = strdup(optarg);
char *scheme;
parse_url(url, &scheme, &vpninfo->proxy, &vpninfo->proxy_port, NULL);
parse_url(url, &scheme, &vpninfo->proxy, &vpninfo->proxy_port, NULL, 80);
if (scheme && strcmp(scheme, "http")) {
fprintf(stderr, "Non-http proxy not supported\n");
exit(1);
Expand Down Expand Up @@ -416,8 +416,27 @@ int main(int argc, char **argv)
if (config_lookup_host(vpninfo, argv[optind]))
exit(1);

if (!vpninfo->hostname)
vpninfo->hostname = strdup(argv[optind]);
if (!vpninfo->hostname) {
char *url = strdup(argv[optind]);
char *scheme;
char *group;

if (parse_url(url, &scheme, &vpninfo->hostname, &vpninfo->port,
&group, 443)) {
fprintf(stderr, "Failed to parse server URL '%s'\n",
url);
exit(1);
}
if (scheme && strcmp(scheme, "https")) {
fprintf(stderr, "Only https:// permitted for server URL\n");
exit(1);
}
if (group) {
free(vpninfo->urlpath);
vpninfo->urlpath = group;
}
free(scheme);
}

#ifdef SSL_UI
set_openssl_ui();
Expand Down
2 changes: 1 addition & 1 deletion openconnect.8
Expand Up @@ -147,7 +147,7 @@ openconnect \- Connect to Cisco AnyConnect VPN
.B --useragent
.I STRING
]
\fIserver\fR
[https://]\fIserver\fR[:\fIport\fR][/\fIgroup\fR]

.SH DESCRIPTION
The program
Expand Down
3 changes: 2 additions & 1 deletion openconnect.h
Expand Up @@ -324,7 +324,8 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response,
int openconnect_obtain_cookie(struct openconnect_info *vpninfo);
char *openconnect_create_useragent(char *base);
int process_http_proxy(struct openconnect_info *vpninfo, int ssl_sock);
int parse_url(char *url, char **res_proto, char **res_host, int *res_port, char **res_path);
int parse_url(char *url, char **res_proto, char **res_host, int *res_port,
char **res_path, int default_port);

/* ssl_ui.c */
int set_openssl_ui(void);
Expand Down
3 changes: 2 additions & 1 deletion openconnect.html
Expand Up @@ -173,6 +173,7 @@ <H2>Release Notes / Changelog</H2>
<UL>
<LI><B>OpenConnect HEAD</B><BR>
<UL>
<LI>Allow server to be specified with <TT>https://</TT> URL, including port and pathname (which Cisco calls 'UserGroup')</LI>
<LI>Support connection through HTTP proxy.</LI>
<LI>Handle HTTP redirection with port numbers.</LI>
<LI>Handle HTTP redirection with IPv6 literal addresses.</LI>
Expand Down Expand Up @@ -387,6 +388,6 @@ <H3>FreeBSD</H3>
<hr>
<address>David Woodhouse &lt;<A HREF="mailto:dwmw2@infradead.org">dwmw2@infradead.org</A>&gt;</address>
<!-- hhmts start -->
Last modified: Fri Jan 1 22:08:53 GMT 2010
Last modified: Fri Jan 1 22:50:54 GMT 2010
<!-- hhmts end -->
</body> </html>
13 changes: 12 additions & 1 deletion ssl.c
Expand Up @@ -518,7 +518,17 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
snprintf(port, 5, "%d", vpninfo->port);
}

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

err = getaddrinfo(hostname, port, &hints, &result);
if (hints.ai_flags & AI_NUMERICHOST)
free(hostname);

if (err) {
vpninfo->progress(vpninfo, PRG_ERR, "getaddrinfo failed: %s\n",
gai_strerror(err));
Expand Down Expand Up @@ -560,7 +570,8 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
freeaddrinfo(result);

if (ssl_sock < 0) {
vpninfo->progress(vpninfo, PRG_ERR, "Failed to connect to host %s\n", hostname);
vpninfo->progress(vpninfo, PRG_ERR, "Failed to connect to host %s\n",
vpninfo->proxy?:vpninfo->hostname);
return -EINVAL;
}
}
Expand Down

0 comments on commit 024e59a

Please sign in to comment.