diff options
author | Chris Lumens <clumens@redhat.com> | 2006-11-01 22:23:30 +0000 |
---|---|---|
committer | Chris Lumens <clumens@redhat.com> | 2006-11-01 22:23:30 +0000 |
commit | 6ac6ff032b93a3940e309d72d3862bdaccf11f0c (patch) | |
tree | b6d61319c1de2c585e15a3a2c8fae847a52b6ffb | |
parent | d177872f4862bcbc8872ead57e4e4ce00ab68a6c (diff) | |
download | anaconda-6ac6ff032b93a3940e309d72d3862bdaccf11f0c.tar.gz anaconda-6ac6ff032b93a3940e309d72d3862bdaccf11f0c.tar.xz anaconda-6ac6ff032b93a3940e309d72d3862bdaccf11f0c.zip |
Added a function to split hostnames and ports taking into account IPv6
addresses so port numbers work in HTTP URLs again (#212622).
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | loader2/ftp.c | 43 | ||||
-rw-r--r-- | loader2/net.c | 52 | ||||
-rw-r--r-- | loader2/net.h | 2 | ||||
-rw-r--r-- | loader2/urls.c | 25 |
5 files changed, 97 insertions, 36 deletions
@@ -10,6 +10,17 @@ * autopart.py (doClearPartAction): Don't try to clear drives that are in the skippedList either. + * loader2/net.c (splitHostname): Add a function to split + hostname/port number pairs up that takes IPv6 numeric addresses into + account. + * loader2/net.h: Add prototype for splitHostname. Include newt.h. + + * loader2/ftp.c (httpGetFileDesc): If we're not passed a port, use + the default. + (getHostAddress): Use splitHostname so we don't attempt to + gethostbyname on a string containing a port number (#212622). + * loader2/urls.c (urlinstStartTransfer): Likewise. + 2006-10-31 Chris Lumens <clumens@redhat.com> * urlinstall.py (UrlInstallMethod.__checkUrlForIsoMounts): Set diff --git a/loader2/ftp.c b/loader2/ftp.c index e75dcfb82..c6db27e30 100644 --- a/loader2/ftp.c +++ b/loader2/ftp.c @@ -69,6 +69,7 @@ extern int h_errno; #include "ftp.h" #include "log.h" +#include "net.h" static int ftpCheckResponse(int sock, char ** str); static int ftpCommand(int sock, char * command, ...); @@ -208,15 +209,19 @@ int ftpCommand(int sock, char * command, ...) { } static int getHostAddress(const char * host, void * address, int family) { + char *hostname, *port; + + splitHostname((char *) host, &hostname, &port); + if (family == AF_INET) { if (isdigit(host[0])) { - if (inet_pton(AF_INET, host, (struct in_addr *)address) >= 1) { + if (inet_pton(AF_INET, hostname, (struct in_addr *)address) >= 1) { return 0; } else { return FTPERR_BAD_HOST_ADDR; } } else { - if (mygethostbyname((char *) host, (struct in_addr *) address)) { + if (mygethostbyname(hostname, (struct in_addr *) address)) { errno = h_errno; return FTPERR_BAD_HOSTNAME; } else { @@ -224,8 +229,8 @@ static int getHostAddress(const char * host, void * address, int family) { } } } else if (family == AF_INET6) { - if (strchr(host, ':')) { - if (inet_pton(AF_INET6, host, (struct in_addr6 *)address) >= 1) { + if (strchr(hostname, ':')) { + if (inet_pton(AF_INET6, hostname, (struct in_addr6 *)address) >= 1) { return 0; } else return FTPERR_BAD_HOST_ADDR; @@ -660,7 +665,7 @@ static char *find_status_code (char *headers) int httpGetFileDesc(char * hostname, int port, char * remotename, char *extraHeaders) { char * buf, *headers = NULL; - char *realhost, *status; + char *status; char *hstr; int family; struct in_addr addr; @@ -671,30 +676,14 @@ int httpGetFileDesc(char * hostname, int port, char * remotename, struct sockaddr_in6 destPort6; fd_set readSet; - /* XXX: this won't work correctly for IPv6 */ -/* - realhost = hostname; - if (port < 0) { - char *colonptr = strchr(hostname, ':'); - if (colonptr != NULL) { - int realhostlen = colonptr - hostname; - port = atoi(colonptr + 1); - realhost = alloca (realhostlen + 1); - memcpy (realhost, hostname, realhostlen); - realhost[realhostlen] = '\0'; - } else { - port = 80; - } - } -*/ - realhost = hostname; - port = 80; + if (port < 0) + port = 80; family = AF_INET; - rc = getHostAddress(realhost, &addr, family); + rc = getHostAddress(hostname, &addr, family); if (rc) { family = AF_INET6; - rc = getHostAddress(realhost, &addr6, family); + rc = getHostAddress(hostname, &addr6, family); if (rc) return rc; } @@ -729,8 +718,8 @@ int httpGetFileDesc(char * hostname, int port, char * remotename, else hstr = ""; - buf = alloca(strlen(remotename) + strlen(realhost) + strlen(hstr) + 25); - sprintf(buf, "GET %s HTTP/1.0\r\nHost: %s\r\n%s\r\n", remotename, realhost, hstr); + buf = alloca(strlen(remotename) + strlen(hostname) + strlen(hstr) + 25); + sprintf(buf, "GET %s HTTP/1.0\r\nHost: %s\r\n%s\r\n", remotename, hostname, hstr); rc = write(sock, buf, strlen(buf)); rc = read_headers (&headers, &readSet, sock); diff --git a/loader2/net.c b/loader2/net.c index 6bdf664dc..43a939d4b 100644 --- a/loader2/net.c +++ b/loader2/net.c @@ -1777,4 +1777,56 @@ int kickstartNetworkUp(struct loaderData_s * loaderData, return 0; } +static int strcount (char *str, int ch) +{ + int retval = 0; + char *tmp = str; + + do { + if ((tmp = index(tmp, ch)) != NULL) { + tmp++; + retval++; + } + } while (tmp != NULL); + + return retval; +} + +void splitHostname (char *str, char **host, char **port) +{ + char *rightbrack = strchr(str, ']'); + + *host = NULL; + *port = NULL; + + if (*str == '[' && rightbrack) { + /* An IPv6 address surrounded by brackets, optionally with a colon and + * port number. + */ + char *colon = strrchr(rightbrack, ':'); + + if (colon) { + *host = strndup(str+1, rightbrack-1-str); + *port = strdup(colon+1); + } + else + *host = strndup(str+1, rightbrack-1-str); + } else if (strcount(str, ':') > 1) { + /* An IPv6 address without brackets. Don't make the user surround the + * address with brackets if there's no port number. + */ + *host = strdup(str); + } else { + /* An IPv4 address, optionally with a colon and port number. */ + char *colon = strrchr(str, ':'); + + if (colon) { + *host = strndup(str, colon-str); + *port = strdup(colon+1); + } + else + *host = strdup(str); + } +} + /* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/loader2/net.h b/loader2/net.h index a860cfa0c..416e0467f 100644 --- a/loader2/net.h +++ b/loader2/net.h @@ -4,6 +4,7 @@ #include "loader.h" #include <ip_addr.h> #include <libdhcp.h> +#include <newt.h> #include <pump.h> struct networkDeviceConfig { @@ -67,5 +68,6 @@ int kickstartNetworkUp(struct loaderData_s * loaderData, char *doDhcp(struct networkDeviceConfig *dev); void netlogger(void *arg, int priority, char *fmt, va_list va); +void splitHostname (char *str, char **host, char **port); #endif diff --git a/loader2/urls.c b/loader2/urls.c index 0c83aeaf4..9a9ebb716 100644 --- a/loader2/urls.c +++ b/loader2/urls.c @@ -154,11 +154,12 @@ char *convertUIToURL(struct iurlinfo *ui) { int urlinstStartTransfer(struct iurlinfo * ui, char * filename, char *extraHeaders) { char * buf; - int fd; + int fd, port; int family = -1; char * finalPrefix; struct in_addr addr; struct in6_addr addr6; + char *hostname, *portstr; if (!strcmp(ui->prefix, "/")) finalPrefix = ""; @@ -175,28 +176,34 @@ int urlinstStartTransfer(struct iurlinfo * ui, char * filename, ui->protocol == URL_METHOD_FTP ? "ftp" : "http", ui->address, buf); - if (inet_pton(AF_INET, ui->address, &addr) >= 1) + splitHostname(ui->address, &hostname, &portstr); + if (portstr == NULL) + port = -1; + else + port = atoi(portstr); + + if (inet_pton(AF_INET, hostname, &addr) >= 1) family = AF_INET; - else if (inet_pton(AF_INET6, ui->address, &addr6) >= 1) + else if (inet_pton(AF_INET6, hostname, &addr6) >= 1) family = AF_INET6; else { - if (mygethostbyname(ui->address, &addr) == 0) { + if (mygethostbyname(hostname, &addr) == 0) { family = AF_INET; /* - } else if (mygethostbyname(ui->address, &addr6) == 0) { + } else if (mygethostbyname(hostname, &addr6) == 0) { family = AF_INET6; */ } else { logMessage(ERROR, "cannot determine address family of %s", - ui->address); + hostname); } } if (ui->protocol == URL_METHOD_FTP) { - ui->ftpPort = ftpOpen(ui->address, family, + ui->ftpPort = ftpOpen(hostname, family, ui->login ? ui->login : "anonymous", ui->password ? ui->password : "rhinstall@", - NULL, -1); + NULL, port); if (ui->ftpPort < 0) return -2; @@ -206,7 +213,7 @@ int urlinstStartTransfer(struct iurlinfo * ui, char * filename, return -1; } } else { - fd = httpGetFileDesc(ui->address, -1, buf, extraHeaders); + fd = httpGetFileDesc(hostname, port, buf, extraHeaders); if (fd < 0) return -1; } |