Lines 102-107
Link Here
|
102 |
#endif /* HAVE_SSL */ |
102 |
#endif /* HAVE_SSL */ |
103 |
static int pipe_command(cupsd_client_t *con, int infile, int *outfile, |
103 |
static int pipe_command(cupsd_client_t *con, int infile, int *outfile, |
104 |
char *command, char *options, int root); |
104 |
char *command, char *options, int root); |
|
|
105 |
static int valid_host(cupsd_client_t *con); |
105 |
static int write_file(cupsd_client_t *con, http_status_t code, |
106 |
static int write_file(cupsd_client_t *con, http_status_t code, |
106 |
char *filename, char *type, |
107 |
char *filename, char *type, |
107 |
struct stat *filestats); |
108 |
struct stat *filestats); |
Lines 261-276
Link Here
|
261 |
* Map accesses from the same host to the server name. |
262 |
* Map accesses from the same host to the server name. |
262 |
*/ |
263 |
*/ |
263 |
|
264 |
|
264 |
for (addr = ServerAddrs; addr; addr = addr->next) |
265 |
if (HostNameLookups) |
265 |
if (httpAddrEqual(con->http.hostaddr, &(addr->addr))) |
|
|
266 |
break; |
267 |
|
268 |
if (addr) |
269 |
{ |
270 |
strlcpy(con->http.hostname, ServerName, sizeof(con->http.hostname)); |
271 |
hostname = con->http.hostname; |
272 |
} |
273 |
else if (HostNameLookups) |
274 |
hostname = httpAddrLookup(con->http.hostaddr, con->http.hostname, |
266 |
hostname = httpAddrLookup(con->http.hostaddr, con->http.hostname, |
275 |
sizeof(con->http.hostname)); |
267 |
sizeof(con->http.hostname)); |
276 |
else |
268 |
else |
Lines 1078-1083
Link Here
|
1078 |
return; |
1070 |
return; |
1079 |
} |
1071 |
} |
1080 |
} |
1072 |
} |
|
|
1073 |
else if (!valid_host(con)) |
1074 |
{ |
1075 |
/* |
1076 |
* Access to localhost must use "localhost" or the corresponding IPv4 |
1077 |
* or IPv6 values in the Host: field. |
1078 |
*/ |
1079 |
|
1080 |
cupsdLogMessage(CUPSD_LOG_WARN, |
1081 |
"Request from \"%s\" using invalid Host: field \"%s\"", |
1082 |
con->http.hostname, con->http.fields[HTTP_FIELD_HOST]); |
1083 |
|
1084 |
if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE)) |
1085 |
{ |
1086 |
cupsdCloseClient(con); |
1087 |
return; |
1088 |
} |
1089 |
} |
1081 |
else if (con->operation == HTTP_OPTIONS) |
1090 |
else if (con->operation == HTTP_OPTIONS) |
1082 |
{ |
1091 |
{ |
1083 |
/* |
1092 |
/* |
Lines 4805-4810
Link Here
|
4805 |
|
4814 |
|
4806 |
|
4815 |
|
4807 |
/* |
4816 |
/* |
|
|
4817 |
* 'valid_host()' - Is the Host: field valid? |
4818 |
*/ |
4819 |
|
4820 |
static int /* O - 1 if valid, 0 if not */ |
4821 |
valid_host(cupsd_client_t *con) /* I - Client connection */ |
4822 |
{ |
4823 |
cupsd_alias_t *a; /* Current alias */ |
4824 |
cupsd_netif_t *netif; /* Current network interface */ |
4825 |
const char *host, /* Host field */ |
4826 |
*end; /* End character */ |
4827 |
|
4828 |
|
4829 |
host = con->http.fields[HTTP_FIELD_HOST]; |
4830 |
|
4831 |
if (httpAddrLocalhost(con->http.hostaddr)) |
4832 |
{ |
4833 |
/* |
4834 |
* Only allow "localhost" or the equivalent IPv4 or IPv6 numerical |
4835 |
* addresses when accessing CUPS via the loopback interface... |
4836 |
*/ |
4837 |
|
4838 |
return (!strcasecmp(host, "localhost") || |
4839 |
!strncasecmp(host, "localhost:", 10) || |
4840 |
!strcasecmp(host, "localhost.") || |
4841 |
!strncasecmp(host, "localhost.:", 11) || |
4842 |
#ifdef __linux |
4843 |
!strcasecmp(host, "localhost.localdomain") || |
4844 |
!strncasecmp(host, "localhost.localdomain:", 22) || |
4845 |
#endif /* __linux */ |
4846 |
!strcmp(host, "127.0.0.1") || |
4847 |
!strncmp(host, "127.0.0.1:", 10) || |
4848 |
!strcmp(host, "[::1]") || |
4849 |
!strncmp(host, "[::1]:", 6)); |
4850 |
} |
4851 |
|
4852 |
#ifdef HAVE_DNSSD |
4853 |
/* |
4854 |
* Check if the hostname is something.local (Bonjour); if so, allow it. |
4855 |
*/ |
4856 |
|
4857 |
if ((end = strrchr(host, '.')) != NULL && |
4858 |
(!strcasecmp(end, ".local") || !strncasecmp(end, ".local:", 7))) |
4859 |
return (1); |
4860 |
#endif /* HAVE_DNSSD */ |
4861 |
|
4862 |
/* |
4863 |
* Check for (alias) name matches... |
4864 |
*/ |
4865 |
|
4866 |
for (a = (cupsd_alias_t *)cupsArrayFirst(ServerAlias); |
4867 |
a; |
4868 |
a = (cupsd_alias_t *)cupsArrayNext(ServerAlias)) |
4869 |
{ |
4870 |
/* |
4871 |
* "ServerAlias *" allows all host values through... |
4872 |
*/ |
4873 |
|
4874 |
if (!strcmp(a->name, "*")) |
4875 |
return (1); |
4876 |
|
4877 |
if (!strncasecmp(host, a->name, a->namelen)) |
4878 |
{ |
4879 |
/* |
4880 |
* Prefix matches; check the character at the end - it must be either |
4881 |
* ":" or nul... |
4882 |
*/ |
4883 |
|
4884 |
end = host + a->namelen; |
4885 |
|
4886 |
if (!*end || *end == ':') |
4887 |
return (1); |
4888 |
} |
4889 |
} |
4890 |
|
4891 |
/* |
4892 |
* Check for interface hostname matches... |
4893 |
*/ |
4894 |
|
4895 |
for (netif = (cupsd_netif_t *)cupsArrayFirst(NetIFList); |
4896 |
netif; |
4897 |
netif = (cupsd_netif_t *)cupsArrayNext(NetIFList)) |
4898 |
{ |
4899 |
if (!strncasecmp(host, netif->hostname, netif->hostlen)) |
4900 |
{ |
4901 |
/* |
4902 |
* Prefix matches; check the character at the end - it must be either |
4903 |
* ":" or nul... |
4904 |
*/ |
4905 |
|
4906 |
end = host + netif->hostlen; |
4907 |
|
4908 |
if (!*end || *end == ':') |
4909 |
return (1); |
4910 |
} |
4911 |
} |
4912 |
|
4913 |
/* |
4914 |
* Check if the hostname is an IP address... |
4915 |
*/ |
4916 |
|
4917 |
if (isdigit(*host & 255) || *host == '[') |
4918 |
{ |
4919 |
/* |
4920 |
* Possible IPv4/IPv6 address... |
4921 |
*/ |
4922 |
|
4923 |
char temp[1024], /* Temporary string */ |
4924 |
*ptr; /* Pointer into temporary string */ |
4925 |
http_addrlist_t *addrlist; /* List of addresses */ |
4926 |
|
4927 |
|
4928 |
strlcpy(temp, host, sizeof(temp)); |
4929 |
if ((ptr = strrchr(temp, ':')) != NULL && !strchr(ptr, ']')) |
4930 |
*ptr = '\0'; /* Strip :port from host value */ |
4931 |
|
4932 |
if ((addrlist = httpAddrGetList(temp, AF_UNSPEC, NULL)) != NULL) |
4933 |
{ |
4934 |
/* |
4935 |
* Good IPv4/IPv6 address... |
4936 |
*/ |
4937 |
|
4938 |
httpAddrFreeList(addrlist); |
4939 |
return (1); |
4940 |
} |
4941 |
} |
4942 |
|
4943 |
return (0); |
4944 |
} |
4945 |
|
4946 |
|
4947 |
/* |
4808 |
* 'write_file()' - Send a file via HTTP. |
4948 |
* 'write_file()' - Send a file via HTTP. |
4809 |
*/ |
4949 |
*/ |
4810 |
|
4950 |
|