X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=cups%2Fhttp-addr.c;h=12d13a6977736ea833429fcbefb7b6910ef95436;hb=57b7b66b58a66426494ec13ffb18f730afeab8b5;hp=ad74f083fcbc21809e8073b0fc620b24f9d7c413;hpb=48bd1142c9f9b61816e64e76e4671c69208487ce;p=thirdparty%2Fcups.git diff --git a/cups/http-addr.c b/cups/http-addr.c index ad74f083f..12d13a697 100644 --- a/cups/http-addr.c +++ b/cups/http-addr.c @@ -1,16 +1,16 @@ /* - * "$Id$" - * * HTTP address routines for CUPS. * - * Copyright 2007-2013 by Apple Inc. + * Copyright 2007-2014 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright * law. Distribution and use rights are outlined in the file "LICENSE.txt" * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". + * missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. */ /* @@ -18,6 +18,7 @@ */ #include "cups-private.h" +#include #ifdef HAVE_RESOLV_H # include #endif /* HAVE_RESOLV_H */ @@ -30,7 +31,7 @@ /* * 'httpAddrAny()' - Check for the "any" address. * - * @since CUPS 1.2/OS X 10.5@ + * @since CUPS 1.2/macOS 10.5@ */ int /* O - 1 if "any", 0 otherwise */ @@ -53,10 +54,41 @@ httpAddrAny(const http_addr_t *addr) /* I - Address to check */ } +/* + * 'httpAddrClose()' - Close a socket created by @link httpAddrConnect@ or + * @link httpAddrListen@. + * + * Pass @code NULL@ for sockets created with @link httpAddrConnect@ and the + * listen address for sockets created with @link httpAddrListen@. This will + * ensure that domain sockets are removed when closed. + * + * @since CUPS 2.0/OS 10.10@ + */ + +int /* O - 0 on success, -1 on failure */ +httpAddrClose(http_addr_t *addr, /* I - Listen address or @code NULL@ */ + int fd) /* I - Socket file descriptor */ +{ +#ifdef WIN32 + if (closesocket(fd)) +#else + if (close(fd)) +#endif /* WIN32 */ + return (-1); + +#ifdef AF_LOCAL + if (addr && addr->addr.sa_family == AF_LOCAL) + return (unlink(addr->un.sun_path)); +#endif /* AF_LOCAL */ + + return (0); +} + + /* * 'httpAddrEqual()' - Compare two addresses. * - * @since CUPS 1.2/OS X 10.5@ + * @since CUPS 1.2/macOS 10.5@ */ int /* O - 1 if equal, 0 if not */ @@ -89,7 +121,7 @@ httpAddrEqual(const http_addr_t *addr1, /* I - First address */ /* * 'httpAddrLength()' - Return the length of the address in bytes. * - * @since CUPS 1.2/OS X 10.5@ + * @since CUPS 1.2/macOS 10.5@ */ int /* O - Length in bytes */ @@ -105,8 +137,7 @@ httpAddrLength(const http_addr_t *addr) /* I - Address */ #endif /* AF_INET6 */ #ifdef AF_LOCAL if (addr->addr.sa_family == AF_LOCAL) - return (offsetof(struct sockaddr_un, sun_path) + - strlen(addr->un.sun_path) + 1); + return ((int)(offsetof(struct sockaddr_un, sun_path) + strlen(addr->un.sun_path) + 1)); else #endif /* AF_LOCAL */ if (addr->addr.sa_family == AF_INET) @@ -121,7 +152,7 @@ httpAddrLength(const http_addr_t *addr) /* I - Address */ * 'httpAddrListen()' - Create a listening socket bound to the specified * address and port. * - * @since CUPS 1.7/OS X 10.9@ + * @since CUPS 1.7/macOS 10.9@ */ int /* O - Socket or -1 on error */ @@ -129,16 +160,21 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */ int port) /* I - Port number to bind to */ { int fd = -1, /* Socket */ - val; /* Socket value */ + val, /* Socket value */ + status; /* Bind status */ /* * Range check input... */ - if (!addr || port <= 0) + if (!addr || port < 0) return (-1); + /* + * Create the socket and set options... + */ + if ((fd = socket(addr->addr.sa_family, SOCK_STREAM, 0)) < 0) { _cupsSetHTTPError(HTTP_STATUS_ERROR); @@ -153,9 +189,50 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */ setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, CUPS_SOCAST &val, sizeof(val)); #endif /* IPV6_V6ONLY */ - _httpAddrSetPort(addr, port); + /* + * Bind the socket... + */ - if (bind(fd, (struct sockaddr *)addr, httpAddrLength(addr))) +#ifdef AF_LOCAL + if (addr->addr.sa_family == AF_LOCAL) + { + mode_t mask; /* Umask setting */ + + /* + * Remove any existing domain socket file... + */ + + unlink(addr->un.sun_path); + + /* + * Save the current umask and set it to 0 so that all users can access + * the domain socket... + */ + + mask = umask(0); + + /* + * Bind the domain socket... + */ + + status = bind(fd, (struct sockaddr *)addr, (socklen_t)httpAddrLength(addr)); + + /* + * Restore the umask and fix permissions... + */ + + umask(mask); + chmod(addr->un.sun_path, 0140777); + } + else +#endif /* AF_LOCAL */ + { + _httpAddrSetPort(addr, port); + + status = bind(fd, (struct sockaddr *)addr, (socklen_t)httpAddrLength(addr)); + } + + if (status) { _cupsSetHTTPError(HTTP_STATUS_ERROR); @@ -164,6 +241,10 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */ return (-1); } + /* + * Listen... + */ + if (listen(fd, 5)) { _cupsSetHTTPError(HTTP_STATUS_ERROR); @@ -173,6 +254,14 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */ return (-1); } + /* + * Close on exec... + */ + +#ifndef WIN32 + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +#endif /* !WIN32 */ + #ifdef SO_NOSIGPIPE /* * Disable SIGPIPE for this socket. @@ -189,7 +278,7 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */ /* * 'httpAddrLocalhost()' - Check for the local loopback address. * - * @since CUPS 1.2/OS X 10.5@ + * @since CUPS 1.2/macOS 10.5@ */ int /* O - 1 if local host, 0 otherwise */ @@ -221,7 +310,7 @@ httpAddrLocalhost( /* * 'httpAddrLookup()' - Lookup the hostname associated with the address. * - * @since CUPS 1.2/OS X 10.5@ + * @since CUPS 1.2/macOS 10.5@ */ char * /* O - Host name */ @@ -234,8 +323,7 @@ httpAddrLookup( /* Global data */ - DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)", addr, name, - namelen)); + DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)", (void *)addr, (void *)name, namelen)); /* * Range check input... @@ -252,7 +340,7 @@ httpAddrLookup( #ifdef AF_LOCAL if (addr->addr.sa_family == AF_LOCAL) { - strlcpy(name, addr->un.sun_path, namelen); + strlcpy(name, addr->un.sun_path, (size_t)namelen); return (name); } #endif /* AF_LOCAL */ @@ -263,7 +351,7 @@ httpAddrLookup( if (httpAddrLocalhost(addr)) { - strlcpy(name, "localhost", namelen); + strlcpy(name, "localhost", (size_t)namelen); return (name); } @@ -298,8 +386,7 @@ httpAddrLookup( * do... */ - int error = getnameinfo(&addr->addr, httpAddrLength(addr), name, namelen, - NULL, 0, 0); + int error = getnameinfo(&addr->addr, (socklen_t)httpAddrLength(addr), name, (socklen_t)namelen, NULL, 0, 0); if (error) { @@ -335,7 +422,7 @@ httpAddrLookup( return (httpAddrString(addr, name, namelen)); } - strlcpy(name, host->h_name, namelen); + strlcpy(name, host->h_name, (size_t)namelen); } #endif /* HAVE_GETNAMEINFO */ @@ -362,7 +449,7 @@ httpAddrFamily(http_addr_t *addr) /* I - Address */ /* * 'httpAddrPort()' - Get the port number associated with an address. * - * @since CUPS 1.7/OS X 10.9@ + * @since CUPS 1.7/macOS 10.9@ */ int /* O - Port number */ @@ -380,9 +467,6 @@ httpAddrPort(http_addr_t *addr) /* I - Address */ return (0); } -/* For OS X 10.8 and earlier */ -int _httpAddrPort(http_addr_t *addr) { return (httpAddrPort(addr)); } - /* * '_httpAddrSetPort()' - Set the port number associated with an address. @@ -408,7 +492,7 @@ _httpAddrSetPort(http_addr_t *addr, /* I - Address */ /* * 'httpAddrString()' - Convert an address to a numeric string. * - * @since CUPS 1.2/OS X 10.5@ + * @since CUPS 1.2/macOS 10.5@ */ char * /* O - Numeric address string */ @@ -416,7 +500,7 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ char *s, /* I - String buffer */ int slen) /* I - Length of string */ { - DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)", addr, s, slen)); + DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)", (void *)addr, (void *)s, slen)); /* * Range check input... @@ -434,9 +518,9 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ if (addr->addr.sa_family == AF_LOCAL) { if (addr->un.sun_path[0] == '/') - strlcpy(s, addr->un.sun_path, slen); + strlcpy(s, addr->un.sun_path, (size_t)slen); else - strlcpy(s, "localhost", slen); + strlcpy(s, "localhost", (size_t)slen); } else #endif /* AF_LOCAL */ @@ -444,10 +528,9 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ { unsigned temp; /* Temporary address */ - temp = ntohl(addr->ipv4.sin_addr.s_addr); - snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255, + snprintf(s, (size_t)slen, "%d.%d.%d.%d", (temp >> 24) & 255, (temp >> 16) & 255, (temp >> 8) & 255, temp & 255); } #ifdef AF_INET6 @@ -457,8 +540,7 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ temps[64]; /* Temporary string for address */ # ifdef HAVE_GETNAMEINFO - if (getnameinfo(&addr->addr, httpAddrLength(addr), temps, sizeof(temps), - NULL, 0, NI_NUMERICHOST)) + if (getnameinfo(&addr->addr, (socklen_t)httpAddrLength(addr), temps, sizeof(temps), NULL, 0, NI_NUMERICHOST)) { /* * If we get an error back, then the address type is not supported @@ -489,8 +571,7 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ { temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]); - snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix, - (temp >> 16) & 0xffff); + snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, (temp >> 16) & 0xffff); prefix = ":"; sptr += strlen(sptr); @@ -498,7 +579,7 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1]) { - snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix, temp); + snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, temp); sptr += strlen(sptr); } } @@ -510,7 +591,7 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ if (i < 4) { - snprintf(sptr, sizeof(temps) - (sptr - temps), "%s:", prefix); + snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s:", prefix); prefix = ":"; sptr += strlen(sptr); @@ -521,13 +602,11 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ if ((temp & 0xffff0000) || (i > 0 && addr->ipv6.sin6_addr.s6_addr32[i - 1])) { - snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix, - (temp >> 16) & 0xffff); + snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, (temp >> 16) & 0xffff); sptr += strlen(sptr); } - snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix, - temp & 0xffff); + snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, temp & 0xffff); sptr += strlen(sptr); } } @@ -545,7 +624,7 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ * Empty at end... */ - strlcpy(sptr, "::", sizeof(temps) - (sptr - temps)); + strlcpy(sptr, "::", sizeof(temps) - (size_t)(sptr - temps)); } } # endif /* HAVE_GETNAMEINFO */ @@ -554,11 +633,11 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ * Add "[v1." and "]" around IPv6 address to convert to URI form. */ - snprintf(s, slen, "[v1.%s]", temps); + snprintf(s, (size_t)slen, "[v1.%s]", temps); } #endif /* AF_INET6 */ else - strlcpy(s, "UNKNOWN", slen); + strlcpy(s, "UNKNOWN", (size_t)slen); DEBUG_printf(("1httpAddrString: returning \"%s\"...", s)); @@ -571,7 +650,7 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ * * Returns @code NULL@ if the socket is currently unconnected. * - * @since CUPS 2.0@ + * @since CUPS 2.0/OS 10.10@ */ http_addr_t * /* O - Connected address or @code NULL@ */ @@ -633,7 +712,7 @@ httpGetHostByName(const char *name) /* I - Hostname or IP address */ cg->hostent.h_name = (char *)name; cg->hostent.h_aliases = NULL; cg->hostent.h_addrtype = AF_LOCAL; - cg->hostent.h_length = strlen(name) + 1; + cg->hostent.h_length = (int)strlen(name) + 1; cg->hostent.h_addr_list = cg->ip_ptrs; cg->ip_ptrs[0] = (char *)name; cg->ip_ptrs[1] = NULL; @@ -659,8 +738,9 @@ httpGetHostByName(const char *name) /* I - Hostname or IP address */ if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255) return (NULL); /* Invalid byte ranges! */ - cg->ip_addr = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | - ip[3])); + cg->ip_addr = htonl((((((((unsigned)ip[0] << 8) | (unsigned)ip[1]) << 8) | + (unsigned)ip[2]) << 8) | + (unsigned)ip[3])); /* * Fill in the host entry and return it... @@ -701,7 +781,7 @@ httpGetHostByName(const char *name) /* I - Hostname or IP address */ * Otherwise, return the FQDN for the local system using both gethostname() * and gethostbyname() to get the local hostname with domain. * - * @since CUPS 1.2/OS X 10.5@ + * @since CUPS 1.2/macOS 10.5@ */ const char * /* O - FQDN for connection or system */ @@ -719,9 +799,9 @@ httpGetHostname(http_t *http, /* I - HTTP connection or NULL */ return (http->hostname); } else if (http->hostname[0] == '/') - strlcpy(s, "localhost", slen); + strlcpy(s, "localhost", (size_t)slen); else - strlcpy(s, http->hostname, slen); + strlcpy(s, http->hostname, (size_t)slen); } else { @@ -731,9 +811,9 @@ httpGetHostname(http_t *http, /* I - HTTP connection or NULL */ if (!s || slen <= 1) return (NULL); - - if (gethostname(s, slen) < 0) - strlcpy(s, "localhost", slen); + + if (gethostname(s, (size_t)slen) < 0) + strlcpy(s, "localhost", (size_t)slen); if (!strchr(s, '.')) { @@ -757,7 +837,7 @@ httpGetHostname(http_t *http, /* I - HTTP connection or NULL */ * Append ".local." to the hostname we get... */ - snprintf(s, slen, "%s.local.", localStr); + snprintf(s, (size_t)slen, "%s.local.", localStr); } if (local) @@ -778,10 +858,29 @@ httpGetHostname(http_t *http, /* I - HTTP connection or NULL */ * Use the resolved hostname... */ - strlcpy(s, host->h_name, slen); + strlcpy(s, host->h_name, (size_t)slen); } #endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */ } + + /* + * Make sure .local hostnames end with a period... + */ + + if (strlen(s) > 6 && !strcmp(s + strlen(s) - 6, ".local")) + strlcat(s, ".", (size_t)slen); + } + + /* + * Convert the hostname to lowercase as needed... + */ + + if (s[0] != '/') + { + char *ptr; /* Pointer into string */ + + for (ptr = s; *ptr; ptr ++) + *ptr = (char)_cups_tolower((int)*ptr); } /* @@ -796,7 +895,7 @@ httpGetHostname(http_t *http, /* I - HTTP connection or NULL */ * 'httpResolveHostname()' - Resolve the hostname of the HTTP connection * address. * - * @since CUPS 2.0@ + * @since CUPS 2.0/OS 10.10@ */ const char * /* O - Resolved hostname or @code NULL@ */ @@ -831,8 +930,3 @@ httpResolveHostname(http_t *http, /* I - HTTP connection */ else return (http->hostname); } - - -/* - * End of "$Id$". - */