summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lumens <clumens@redhat.com>2006-11-01 22:23:30 +0000
committerChris Lumens <clumens@redhat.com>2006-11-01 22:23:30 +0000
commit6ac6ff032b93a3940e309d72d3862bdaccf11f0c (patch)
treeb6d61319c1de2c585e15a3a2c8fae847a52b6ffb
parentd177872f4862bcbc8872ead57e4e4ce00ab68a6c (diff)
downloadanaconda-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--ChangeLog11
-rw-r--r--loader2/ftp.c43
-rw-r--r--loader2/net.c52
-rw-r--r--loader2/net.h2
-rw-r--r--loader2/urls.c25
5 files changed, 97 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index fb78ebdf1..d903d178d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;
}