kopia lustrzana https://gitlab.com/sane-project/backends
DNS queries for remote hosts are only done if necessary. It's now possible
to use "+" without hosts/DNS entries for the connecting host. Henning Meier-Geinitz <henning@meier-geinitz.de>DEVEL_2_0_BRANCH-1
rodzic
a38aa93608
commit
2e3dc0b7b2
141
frontend/saned.c
141
frontend/saned.c
|
@ -1,5 +1,6 @@
|
||||||
/* sane - Scanner Access Now Easy.
|
/* sane - Scanner Access Now Easy.
|
||||||
Copyright (C) 1997 Andreas Beck
|
Copyright (C) 1997 Andreas Beck
|
||||||
|
Copyright (C) 2001, 2002 Henning Meier-Geinitz
|
||||||
This file is part of the SANE package.
|
This file is part of the SANE package.
|
||||||
|
|
||||||
SANE is free software; you can redistribute it and/or modify it under
|
SANE is free software; you can redistribute it and/or modify it under
|
||||||
|
@ -106,7 +107,6 @@ byte_order;
|
||||||
it does is save a remote user some work by reducing the amount of
|
it does is save a remote user some work by reducing the amount of
|
||||||
text s/he has to type when authentication is requested. */
|
text s/he has to type when authentication is requested. */
|
||||||
static const char *default_username = "saned-user";
|
static const char *default_username = "saned-user";
|
||||||
static char hostname[MAXHOSTNAMELEN];
|
|
||||||
static char *remote_hostname;
|
static char *remote_hostname;
|
||||||
static struct in_addr remote_address;
|
static struct in_addr remote_address;
|
||||||
|
|
||||||
|
@ -344,19 +344,19 @@ decode_handle (Wire * w, const char *op)
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check hostnames ignoring case as DNS should. */
|
/* Access control */
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
check_host (int fd)
|
check_host (int fd)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
int j, access_ok = 0;
|
int j, access_ok = 0;
|
||||||
struct hostent *he;
|
struct hostent *he;
|
||||||
char r_addr[16]; /* 16 = make sure there is room for IPv6 addr */
|
|
||||||
char l_addr[16];
|
|
||||||
char text_addr[64];
|
char text_addr[64];
|
||||||
unsigned int r_length;
|
char config_line[1024];
|
||||||
unsigned int l_length;
|
char hostname[MAXHOSTNAMELEN];
|
||||||
char rhost[1024];
|
char *r_hostname;
|
||||||
|
static struct in_addr config_line_address;
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
|
@ -367,48 +367,23 @@ check_host (int fd)
|
||||||
DBG (DBG_ERR, "check_host: getpeername failed: %s\n", strerror (errno));
|
DBG (DBG_ERR, "check_host: getpeername failed: %s\n", strerror (errno));
|
||||||
return SANE_STATUS_INVAL;
|
return SANE_STATUS_INVAL;
|
||||||
}
|
}
|
||||||
|
r_hostname = inet_ntoa (sin.sin_addr);
|
||||||
|
remote_hostname = strdup (r_hostname);
|
||||||
DBG (DBG_WARN, "check_host: access by remote host: %s\n",
|
DBG (DBG_WARN, "check_host: access by remote host: %s\n",
|
||||||
inet_ntoa (sin.sin_addr));
|
remote_hostname);
|
||||||
/* Save remote address for check of data connection */
|
/* Save remote address for check of control and data connections */
|
||||||
memcpy (&remote_address, &sin.sin_addr, sizeof (remote_address));
|
memcpy (&remote_address, &sin.sin_addr, sizeof (remote_address));
|
||||||
|
|
||||||
/* Always allow access from local host. Do it here to avoid DNS lookups. */
|
/* Always allow access from local host. Do it here to avoid DNS lookups
|
||||||
|
and reading saned.conf. */
|
||||||
if (IN_LOOPBACK (ntohl (sin.sin_addr.s_addr)))
|
if (IN_LOOPBACK (ntohl (sin.sin_addr.s_addr)))
|
||||||
{
|
{
|
||||||
DBG (DBG_MSG,
|
DBG (DBG_MSG,
|
||||||
"check_host: remote host is IN_LOOPBACK: access accepted\n");
|
"check_host: remote host is IN_LOOPBACK: access accepted\n");
|
||||||
remote_hostname = "localhost";
|
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
DBG (DBG_DBG, "check_host: remote host is not IN_LOOPBACK\n");
|
DBG (DBG_DBG, "check_host: remote host is not IN_LOOPBACK\n");
|
||||||
|
|
||||||
/* Get remote name and store primary address */
|
|
||||||
he = gethostbyaddr ((const char *) &sin.sin_addr,
|
|
||||||
sizeof (sin.sin_addr), sin.sin_family);
|
|
||||||
if (!he)
|
|
||||||
{
|
|
||||||
DBG (DBG_ERR, "check_host: gethostbyaddr failed: %s\n",
|
|
||||||
strerror (errno));
|
|
||||||
return SANE_STATUS_INVAL;
|
|
||||||
}
|
|
||||||
remote_hostname = strdup (he->h_name);
|
|
||||||
DBG (DBG_DBG, "check_host: remote hostname (from DNS): %s\n",
|
|
||||||
remote_hostname);
|
|
||||||
r_length = he->h_length;
|
|
||||||
if (r_length > sizeof(r_addr))
|
|
||||||
{
|
|
||||||
DBG (DBG_ERR, "check_host: remote address length too long: %d > %d\n",
|
|
||||||
r_length,
|
|
||||||
sizeof(r_addr));
|
|
||||||
return SANE_STATUS_INVAL;
|
|
||||||
}
|
|
||||||
memcpy(&r_addr[0], he->h_addr_list[0], r_length);
|
|
||||||
if (!inet_ntop (he->h_addrtype, he->h_addr_list[0], text_addr,
|
|
||||||
sizeof (text_addr)))
|
|
||||||
strcpy (text_addr, "[error]");
|
|
||||||
DBG (DBG_DBG, "check_host: remote host address (from DNS): %s\n",
|
|
||||||
text_addr);
|
|
||||||
|
|
||||||
/* Get name of local host */
|
/* Get name of local host */
|
||||||
if (gethostname (hostname, sizeof (hostname)) < 0)
|
if (gethostname (hostname, sizeof (hostname)) < 0)
|
||||||
{
|
{
|
||||||
|
@ -427,24 +402,15 @@ check_host (int fd)
|
||||||
}
|
}
|
||||||
DBG (DBG_DBG, "check_host: local hostname (from DNS): %s\n",
|
DBG (DBG_DBG, "check_host: local hostname (from DNS): %s\n",
|
||||||
he->h_name);
|
he->h_name);
|
||||||
l_length = he->h_length;
|
|
||||||
if (l_length > sizeof(l_addr))
|
|
||||||
{
|
|
||||||
DBG (DBG_ERR, "check_host: local address length too long: %d > %d\n",
|
|
||||||
l_length,
|
|
||||||
sizeof(l_addr));
|
|
||||||
return SANE_STATUS_INVAL;
|
|
||||||
}
|
|
||||||
memcpy(&l_addr[0], he->h_addr_list[0], l_length);
|
|
||||||
if (!inet_ntop (he->h_addrtype, he->h_addr_list[0], text_addr,
|
|
||||||
sizeof (text_addr)))
|
|
||||||
strcpy (text_addr, "[error]");
|
|
||||||
DBG (DBG_DBG, "check_host: local host address (from DNS): %s\n",
|
|
||||||
text_addr);
|
|
||||||
|
|
||||||
if (r_length == l_length)
|
if ((he->h_length == 4) || he->h_addrtype == AF_INET)
|
||||||
{
|
{
|
||||||
if (memcmp(l_addr, r_addr, r_length) == 0)
|
if (!inet_ntop (he->h_addrtype, he->h_addr_list[0], text_addr,
|
||||||
|
sizeof (text_addr)))
|
||||||
|
strcpy (text_addr, "[error]");
|
||||||
|
DBG (DBG_DBG, "check_host: local host address (from DNS): %s\n",
|
||||||
|
text_addr);
|
||||||
|
if (memcmp (he->h_addr_list[0], &remote_address.s_addr, 4) == 0)
|
||||||
{
|
{
|
||||||
DBG (DBG_MSG,
|
DBG (DBG_MSG,
|
||||||
"check_host: remote host has same addr as local: "
|
"check_host: remote host has same addr as local: "
|
||||||
|
@ -454,17 +420,15 @@ check_host (int fd)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Ignoring localhost address */
|
DBG (DBG_ERR, "check_host: can't get local address "
|
||||||
DBG (DBG_DBG,
|
"(only IPv4 is supported)\n");
|
||||||
"check_host: remote and local addresses have different "
|
|
||||||
"length %d != %d\n", r_length, l_length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_DBG,
|
DBG (DBG_DBG,
|
||||||
"check_host: remote host doesn't have same addr as local\n");
|
"check_host: remote host doesn't have same addr as local\n");
|
||||||
|
|
||||||
/* must be a remote host: check contents of PATH_NET_CONFIG or
|
/* must be a remote host: check contents of PATH_NET_CONFIG or
|
||||||
/etc/hosts.equiv if former doesn't exist: */
|
/etc/hosts.equiv if former doesn't exist: */
|
||||||
|
|
||||||
for (j = 0; j < NELEMS (config_file_names); ++j)
|
for (j = 0; j < NELEMS (config_file_names); ++j)
|
||||||
{
|
{
|
||||||
DBG (DBG_DBG, "check_host: opening config file: %s\n",
|
DBG (DBG_DBG, "check_host: opening config file: %s\n",
|
||||||
|
@ -481,43 +445,56 @@ check_host (int fd)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!access_ok && sanei_config_read (rhost, sizeof (rhost), fp))
|
while (!access_ok && sanei_config_read (config_line,
|
||||||
|
sizeof (config_line), fp))
|
||||||
{
|
{
|
||||||
if (rhost[0] == '#') /* ignore line comments */
|
DBG (DBG_DBG, "check_host: config file line: `%s'\n", config_line);
|
||||||
|
if (config_line[0] == '#') /* ignore line comments */
|
||||||
continue;
|
continue;
|
||||||
len = strlen (rhost);
|
len = strlen (config_line);
|
||||||
|
|
||||||
if (!len)
|
if (!len)
|
||||||
continue; /* ignore empty lines */
|
continue; /* ignore empty lines */
|
||||||
|
|
||||||
DBG (DBG_DBG, "check_host: config file line: `%s'\n", rhost);
|
if (strcmp (config_line, "+") == 0)
|
||||||
|
|
||||||
if (strcmp (rhost, "+") == 0)
|
|
||||||
{
|
{
|
||||||
access_ok = 1;
|
access_ok = 1;
|
||||||
DBG (DBG_DBG,
|
DBG (DBG_DBG,
|
||||||
"check_host: access accepted from every host (`+')\n");
|
"check_host: access accepted from any host (`+')\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
he = gethostbyname (rhost);
|
if (inet_aton (config_line, &config_line_address))
|
||||||
if (!he)
|
|
||||||
{
|
{
|
||||||
DBG (DBG_WARN,
|
if (memcmp (&remote_address.s_addr,
|
||||||
"check_host: gethostbyname for `%s' failed: %s\n",
|
&config_line_address.s_addr, 4) == 0)
|
||||||
rhost, strerror (errno));
|
access_ok = 1;
|
||||||
continue;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG (DBG_DBG,
|
||||||
|
"check_host: inet_aton for `%s' failed\n",
|
||||||
|
config_line);
|
||||||
|
he = gethostbyname (config_line);
|
||||||
|
if (!he)
|
||||||
|
{
|
||||||
|
DBG (DBG_DBG,
|
||||||
|
"check_host: gethostbyname for `%s' failed: %s\n",
|
||||||
|
config_line, strerror (errno));
|
||||||
|
DBG (DBG_MSG, "check_host: entry isn't an IP address "
|
||||||
|
"and can't be found in DNS\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!inet_ntop (he->h_addrtype, he->h_addr_list[0],
|
||||||
|
text_addr, sizeof (text_addr)))
|
||||||
|
strcpy (text_addr, "[error]");
|
||||||
|
DBG (DBG_MSG,
|
||||||
|
"check_host: DNS lookup returns IP address: %s\n",
|
||||||
|
text_addr);
|
||||||
|
if (memcmp (&remote_address.s_addr,
|
||||||
|
he->h_addr_list[0], 4) == 0)
|
||||||
|
access_ok = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inet_ntop (he->h_addrtype, he->h_addr_list[0], text_addr,
|
|
||||||
sizeof (text_addr)))
|
|
||||||
strcpy (text_addr, "[error]");
|
|
||||||
DBG (DBG_MSG,
|
|
||||||
"check_host: checking for `%s' (%s) (from DNS)\n",
|
|
||||||
he->h_name, text_addr);
|
|
||||||
if (r_length == (unsigned int) he->h_length
|
|
||||||
&& memcmp (&r_addr[0], he->h_addr_list[0], r_length) == 0)
|
|
||||||
access_ok = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
|
|
Ładowanie…
Reference in New Issue