2000-11-24 Jochen Eisinger <jochen.eisinger@gmx.net>

* doc/scanimage.man doc/saned.man: updated description of password
	  file
	* sanei/sanei_auth.c frontend/saned.c frontend/scanimage.c: replaced
	  index() by strchr(). Changed style of password file
	* backend/net.c: the net backend now prepends net:host: to the
	  resource before calling the auth_callback function
DEVEL_2_0_BRANCH-1
Jochen Eisinger 2000-11-24 15:05:22 +00:00
rodzic db35b17cde
commit 201b9d662d
5 zmienionych plików z 303 dodań i 254 usunięć

Wyświetl plik

@ -85,23 +85,23 @@ static Net_Scanner *first_handle;
static int saned_port;
static SANE_Status
add_device (const char *name, Net_Device **ndp)
add_device (const char *name, Net_Device ** ndp)
{
struct hostent *he;
Net_Device *nd;
DBG(1, "adding backend %s\n", name);
DBG (1, "adding backend %s\n", name);
he = gethostbyname (name);
if (!he)
{
DBG(1, "can't get address of host %s\n", name);
DBG (1, "can't get address of host %s\n", name);
return SANE_STATUS_IO_ERROR;
}
if (he->h_addrtype != AF_INET)
{
DBG(1, "don't know how to deal with addr family %d\n", he->h_addrtype);
DBG (1, "don't know how to deal with addr family %d\n", he->h_addrtype);
return SANE_STATUS_INVAL;
}
@ -129,7 +129,7 @@ add_device (const char *name, Net_Device **ndp)
}
static SANE_Status
connect_dev (Net_Device *dev)
connect_dev (Net_Device * dev)
{
struct sockaddr_in *sin;
SANE_Word version_code;
@ -143,7 +143,7 @@ connect_dev (Net_Device *dev)
if (dev->addr.sa_family != AF_INET)
{
DBG(1, "connect_dev: don't know how to deal with addr family %d\n",
DBG (1, "connect_dev: don't know how to deal with addr family %d\n",
dev->addr.sa_family);
return SANE_STATUS_IO_ERROR;
}
@ -151,16 +151,17 @@ connect_dev (Net_Device *dev)
dev->ctl = socket (dev->addr.sa_family, SOCK_STREAM, 0);
if (dev->ctl < 0)
{
DBG(1, "connect_dev: failed to obtain socket (%s)\n", strerror (errno));
DBG (1, "connect_dev: failed to obtain socket (%s)\n",
strerror (errno));
dev->ctl = -1;
return SANE_STATUS_IO_ERROR;
}
sin = (struct sockaddr_in*) &dev->addr;
sin = (struct sockaddr_in *) &dev->addr;
sin->sin_port = saned_port;
if (connect (dev->ctl, &dev->addr, sizeof (dev->addr)) < 0)
{
DBG(1, "connect_dev: failed to connect (%s)\n", strerror (errno));
DBG (1, "connect_dev: failed to connect (%s)\n", strerror (errno));
dev->ctl = -1;
return SANE_STATUS_IO_ERROR;
}
@ -174,7 +175,7 @@ connect_dev (Net_Device *dev)
struct protoent *p;
p = getprotobyname ("tcp");
if (p == 0)
DBG(1, "connect_dev: cannot look up `tcp' protocol number");
DBG (1, "connect_dev: cannot look up `tcp' protocol number");
else
level = p->p_proto;
}
@ -182,7 +183,7 @@ connect_dev (Net_Device *dev)
if (level == -1 ||
setsockopt (dev->ctl, level, TCP_NODELAY, &on, sizeof (on)))
DBG(1, "connect_dev: failed to put send socket in TCP_NODELAY mode (%s)",
DBG (1, "connect_dev: failed to put send socket in TCP_NODELAY mode (%s)",
strerror (errno));
#endif /* !TCP_NODELAY */
@ -201,7 +202,7 @@ connect_dev (Net_Device *dev)
if (dev->wire.status != 0)
{
DBG(1, "connect_dev: argument marshalling error (%s)\n",
DBG (1, "connect_dev: argument marshalling error (%s)\n",
strerror (dev->wire.status));
goto fail;
}
@ -211,18 +212,18 @@ connect_dev (Net_Device *dev)
sanei_w_free (&dev->wire, (WireCodecFunc) sanei_w_init_reply, &reply);
if (SANE_VERSION_MAJOR(version_code) != V_MAJOR)
if (SANE_VERSION_MAJOR (version_code) != V_MAJOR)
{
DBG(1, "connect_dev: major version mismatch: got %d, expected %d\n",
SANE_VERSION_MAJOR(version_code), V_MAJOR);
DBG (1, "connect_dev: major version mismatch: got %d, expected %d\n",
SANE_VERSION_MAJOR (version_code), V_MAJOR);
goto fail;
}
if (SANE_VERSION_BUILD(version_code) != SANEI_NET_PROTOCOL_VERSION
&& SANE_VERSION_BUILD(version_code) != 2)
if (SANE_VERSION_BUILD (version_code) != SANEI_NET_PROTOCOL_VERSION
&& SANE_VERSION_BUILD (version_code) != 2)
{
DBG(1, "connect_dev: network protocol version mismatch: "
DBG (1, "connect_dev: network protocol version mismatch: "
"got %d, expected %d\n",
SANE_VERSION_BUILD(version_code), SANEI_NET_PROTOCOL_VERSION);
SANE_VERSION_BUILD (version_code), SANEI_NET_PROTOCOL_VERSION);
goto fail;
}
dev->wire.version = SANE_VERSION_BUILD (version_code);
@ -235,7 +236,7 @@ fail:
}
static SANE_Status
fetch_options (Net_Scanner *s)
fetch_options (Net_Scanner * s)
{
if (s->opt.num_options)
{
@ -256,7 +257,7 @@ fetch_options (Net_Scanner *s)
}
static SANE_Status
do_cancel (Net_Scanner *s)
do_cancel (Net_Scanner * s)
{
s->hw->auth_active = 0;
if (s->data >= 0)
@ -268,18 +269,38 @@ do_cancel (Net_Scanner *s)
}
static void
do_authorization (Net_Device *dev, SANE_String resource)
do_authorization (Net_Device * dev, SANE_String resource)
{
SANE_Authorization_Req req;
SANE_Char username[SANE_MAX_USERNAME_LEN];
SANE_Char password[SANE_MAX_PASSWORD_LEN];
char *net_resource;
dev->auth_active = 1;
memset (&req, 0, sizeof (req));
net_resource = malloc (strlen (resource) + 6 + strlen (dev->name));
if (net_resource != NULL)
sprintf (net_resource, "net:%s:%s", dev->name, resource);
else
{
SANE_Word ack;
DBG (1, "do_authorization: not enough memory\n");
req.resource = resource;
sanei_w_call (&dev->wire, SANE_NET_AUTHORIZE,
(WireCodecFunc) sanei_w_authorization_req, &req,
(WireCodecFunc) sanei_w_word, &ack);
return;
}
if (auth_callback)
(*auth_callback) (resource, username, password);
(*auth_callback) (net_resource, username, password);
free (net_resource);
if (dev->auth_active)
{
@ -294,8 +315,7 @@ do_authorization (Net_Device *dev, SANE_String resource)
}
}
SANE_Status
sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
{
char device_name[PATH_MAX];
struct servent *serv;
@ -303,7 +323,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
size_t len;
FILE *fp;
DBG_INIT();
DBG_INIT ();
auth_callback = authorize;
@ -316,7 +336,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
else
{
saned_port = htons (6566);
DBG(1,
DBG (1,
"init: could not find `sane' service (%s); using default port %d\n",
strerror (errno), htons (saned_port));
}
@ -360,7 +380,7 @@ sane_exit (void)
Net_Scanner *handle, *next_handle;
Net_Device *dev, *next_device;
DBG(1, "exiting\n");
DBG (1, "exiting\n");
/* first, close all handles: */
for (handle = first_handle; handle; handle = next_handle)
@ -375,7 +395,7 @@ sane_exit (void)
{
next_device = dev->next;
DBG(2, "closing dev %p, ctl=%d\n", dev, dev->ctl);
DBG (2, "closing dev %p, ctl=%d\n", dev, dev->ctl);
if (dev->ctl >= 0)
{
@ -399,7 +419,7 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
{
static int devlist_size = 0, devlist_len = 0;
static const SANE_Device **devlist;
static const SANE_Device *empty_devlist[1] = {0};
static const SANE_Device *empty_devlist[1] = { 0 };
SANE_Get_Devices_Reply reply;
SANE_Status status;
Net_Device *dev;
@ -438,7 +458,7 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
status = connect_dev (dev);
if (status != SANE_STATUS_GOOD)
{
DBG(1, "get_devices: ignoring failure to connect to %s\n",
DBG (1, "get_devices: ignoring failure to connect to %s\n",
dev->name);
continue;
}
@ -449,7 +469,7 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
(WireCodecFunc) sanei_w_get_devices_reply, &reply);
if (reply.status != SANE_STATUS_GOOD)
{
DBG(1, "get_devices: ignoring rpc-returned status %s\n",
DBG (1, "get_devices: ignoring rpc-returned status %s\n",
sane_strstatus (reply.status));
sanei_w_free (&dev->wire,
(WireCodecFunc) sanei_w_get_devices_reply, &reply);
@ -500,8 +520,7 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
return SANE_STATUS_GOOD;
}
SANE_Status
sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
{
SANE_Open_Reply reply;
const char *dev_name;
@ -512,7 +531,7 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
Net_Scanner *s;
int need_auth;
DBG(3, "open(\"%s\")\n", full_name);
DBG (3, "open(\"%s\")\n", full_name);
dev_name = strchr (full_name, ':');
if (dev_name)
@ -542,7 +561,7 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
/* Unlike other backends, we never allow an empty backend-name.
Otherwise, it's possible that sane_open("") will result in
endless looping (consider the case where NET is the first
backend...)*/
backend...) */
return SANE_STATUS_INVAL;
else
for (dev = first_device; dev; dev = dev->next)
@ -570,7 +589,7 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
{
if (dev->wire.status != 0)
{
DBG(1, "open rpc call failed (%s)\n", strerror (dev->wire.status));
DBG (1, "open rpc call failed (%s)\n", strerror (dev->wire.status));
return SANE_STATUS_IO_ERROR;
}
@ -582,7 +601,8 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
{
do_authorization (dev, reply.resource_to_authorize);
sanei_w_free (&dev->wire, (WireCodecFunc) sanei_w_open_reply, &reply);
sanei_w_free (&dev->wire, (WireCodecFunc) sanei_w_open_reply,
&reply);
sanei_w_set_dir (&dev->wire, WIRE_DECODE);
sanei_w_open_reply (&dev->wire, &reply);
@ -598,7 +618,7 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
if (status != SANE_STATUS_GOOD)
{
DBG(1, "remote open failed\n");
DBG (1, "remote open failed\n");
return reply.status;
}
}
@ -634,7 +654,7 @@ sane_close (SANE_Handle handle)
}
if (!s)
{
DBG(1, "close: invalid handle %p\n", handle);
DBG (1, "close: invalid handle %p\n", handle);
return; /* oops, not a handle we know about */
}
if (prev)
@ -738,7 +758,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
if (value_size == reply.value_size)
memcpy (value, reply.value, reply.value_size);
else
DBG(1, "control_option: size changed from %d to %d\n",
DBG (1, "control_option: size changed from %d to %d\n",
s->opt.desc[option]->size, reply.value_size);
}
@ -754,8 +774,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
return status;
}
SANE_Status
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
SANE_Status sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
{
Net_Scanner *s = handle;
SANE_Get_Parameters_Reply reply;
@ -776,8 +795,7 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
return status;
}
SANE_Status
sane_start (SANE_Handle handle)
SANE_Status sane_start (SANE_Handle handle)
{
Net_Scanner *s = handle;
SANE_Start_Reply reply;
@ -795,14 +813,14 @@ sane_start (SANE_Handle handle)
len = sizeof (sin);
if (getpeername (s->hw->ctl, (struct sockaddr *) &sin, &len) < 0)
{
DBG(1, "start: getpeername() failed (%s)\n", strerror (errno));
DBG (1, "start: getpeername() failed (%s)\n", strerror (errno));
return SANE_STATUS_IO_ERROR;
}
fd = socket (s->hw->addr.sa_family, SOCK_STREAM, 0);
if (fd < 0)
{
DBG(1, "start: socket() failed (%s)\n", strerror (errno));
DBG (1, "start: socket() failed (%s)\n", strerror (errno));
return SANE_STATUS_IO_ERROR;
}
@ -828,7 +846,8 @@ sane_start (SANE_Handle handle)
continue;
}
sanei_w_free (&s->hw->wire, (WireCodecFunc) sanei_w_start_reply, &reply);
sanei_w_free (&s->hw->wire, (WireCodecFunc) sanei_w_start_reply,
&reply);
if (need_auth && !s->hw->auth_active)
return SANE_STATUS_CANCELLED;
@ -844,7 +863,7 @@ sane_start (SANE_Handle handle)
if (connect (fd, (struct sockaddr *) &sin, len) < 0)
{
DBG(1, "start: connect() failed (%s)\n", strerror (errno));
DBG (1, "start: connect() failed (%s)\n", strerror (errno));
close (fd);
return SANE_STATUS_IO_ERROR;
}
@ -891,13 +910,13 @@ sane_read (SANE_Handle handle, SANE_Byte * data, SANE_Int max_length,
return SANE_STATUS_GOOD;
s->reclen_buf_offset = 0;
s->bytes_remaining = ( ((u_long) s->reclen_buf[0] << 24)
s->bytes_remaining = (((u_long) s->reclen_buf[0] << 24)
| ((u_long) s->reclen_buf[1] << 16)
| ((u_long) s->reclen_buf[2] << 8)
| ((u_long) s->reclen_buf[3] << 0));
DBG(3, "read: next record length=%ld bytes\n",
DBG (3, "read: next record length=%ld bytes\n",
(long) s->bytes_remaining);
if (s->bytes_remaining == (size_t)-1)
if (s->bytes_remaining == (size_t) - 1)
{
char ch;
@ -948,8 +967,7 @@ sane_cancel (SANE_Handle handle)
do_cancel (s);
}
SANE_Status
sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
SANE_Status sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
{
Net_Scanner *s = handle;
@ -962,8 +980,7 @@ sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
return SANE_STATUS_GOOD;
}
SANE_Status
sane_get_select_fd (SANE_Handle handle, SANE_Int *fd)
SANE_Status sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
{
Net_Scanner *s = handle;

Wyświetl plik

@ -114,7 +114,7 @@ below).
If this file contains lines of the form
.PP
.RS
backend:user:password
user:password:backend
.PP
access to the listed backends is restricted. A backend may be listed multiple
times for different user/password combinations. The server uses MD5 encryption

Wyświetl plik

@ -270,12 +270,13 @@ refer to the manual pages listed below.
This file contains a lines of the form
.PP
.RS
backend:user:password
user:password:resource
.PP
scanimage uses this information to answer user authorization requests
automatically. The file must have 0600 permissions or stricter. You should
use this file in conjunction with the --accept-md5-only option to avoid
server-side attacks.
server-side attacks. The resource may contain any character but is limited
to 127 characters.
.SH "SEE ALSO"
xscanimage(1), xcam(1), sane\-dll(5), sane\-dmc(5), sane\-epson(5),
sane\-hp(5), sane\-microtek(5), sane\-mustek(5), sane\-net(5), sane\-pnm(5),

Wyświetl plik

@ -35,11 +35,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef NEED_STRINGS_H
# include <strings.h>
#else
# include <string.h>
#endif
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
@ -745,8 +741,8 @@ process_request (Wire * w)
resource = strdup (name);
if (index (resource, ':'))
*(index (resource, ':')) = 0;
if (strchr (resource, ':'))
*(strchr (resource, ':')) = 0;
if (sanei_authorize (resource, "saned", auth_callback) !=
SANE_STATUS_GOOD)

Wyświetl plik

@ -30,11 +30,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef NEED_STRINGS_H
# include <strings.h>
#else
# include <string.h>
#endif
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
@ -111,7 +107,7 @@ auth_callback (SANE_String_Const resource,
SANE_Char username[SANE_MAX_USERNAME_LEN],
SANE_Char password[SANE_MAX_PASSWORD_LEN])
{
char tmp[512], *wipe;
char tmp[3 + 128 + SANE_MAX_USERNAME_LEN + SANE_MAX_PASSWORD_LEN], *wipe;
unsigned char md5digest[16];
int md5mode = 0, len, query_user = 1;
FILE *pass_file;
@ -148,32 +144,70 @@ auth_callback (SANE_String_Const resource,
while (fgets (tmp, 512, pass_file))
{
if (strncmp (tmp, resource, len) == 0)
if ((strlen (tmp) > 0) && (tmp[strlen (tmp) - 1] == '\n'))
tmp[strlen (tmp) - 1] = 0;
if ((strlen (tmp) > 0) && (tmp[strlen (tmp) - 1] == '\r'))
tmp[strlen (tmp) - 1] = 0;
if (strchr (tmp, ':') != NULL)
{
if ((index (tmp, ':') - tmp) == (signed) len)
if (strchr (strchr (tmp, ':') + 1, ':') != NULL)
{
if (index (index (tmp, ':') + 1, ':') != NULL)
if (
(strncmp
(strchr (strchr (tmp, ':') + 1, ':') + 1,
resource, len) == 0)
&&
(strlen
(strchr (strchr (tmp, ':') + 1, ':') + 1) ==
len))
{
strncpy (username, index (tmp, ':') + 1,
index (index (tmp, ':') + 1, ':') -
(index (tmp, ':') + 1));
username[index (index (tmp, ':') + 1, ':') -
(index (tmp, ':') + 1)] = 0;
strncpy (password, index (tmp, ':') + 2 +
strlen (username), 127);
password[127] = 0;
if (strlen (password) > 0)
if (password[strlen (password) - 1] == '\n')
password[strlen (password) - 1] = 0;
if ((strchr (tmp, ':') - tmp) <
SANE_MAX_USERNAME_LEN)
{
if (
(strchr (strchr (tmp, ':') + 1, ':') -
(strchr (tmp, ':') + 1)) <
SANE_MAX_PASSWORD_LEN)
{
strncpy (username, tmp,
strchr (tmp, ':') - tmp);
username[strchr (tmp, ':') - tmp] = 0;
strncpy (password,
strchr (tmp, ':') + 1,
strchr (strchr (tmp, ':') + 1,
':') -
(strchr (tmp, ':') + 1));
password[strchr
(strchr (tmp, ':') + 1,
':') - (strchr (tmp,
':') + 1)] =
0;
query_user = 0;
break;
}
}
}
}
}
}
@ -227,7 +261,8 @@ auth_callback (SANE_String_Const resource,
if (md5mode)
{
sprintf (tmp, "%.128s%s", (strstr (resource, "$MD5$")) + 5, password);
sprintf (tmp, "%.128s%.*s", (strstr (resource, "$MD5$")) + 5,
SANE_MAX_PASSWORD_LEN - 1, password);
md5_buffer (tmp, strlen (tmp), md5digest);