1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 1997 Andreas Beck
3 Copyright (C) 2001 - 2004 Henning Meier-Geinitz
4 Copyright (C) 2003, 2008 Julien BLACHE <jb@jblache.org>
5 AF-independent + IPv6 code, standalone mode
6
7 This file is part of the SANE package.
8
9 SANE is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your
12 option) any later version.
13
14 SANE is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with sane; see the file COPYING.
21 If not, see <https://www.gnu.org/licenses/>.
22
23 The SANE network daemon. This is the counterpart to the NET
24 backend.
25 */
26
27 #ifdef _AIX
28 # include "../include/lalloca.h" /* MUST come first for AIX! */
29 #endif
30
31 #include "../include/sane/config.h"
32 #include "../include/lalloca.h"
33 #include <sys/types.h>
34
35 #if defined(HAVE_GETADDRINFO) && defined (HAVE_GETNAMEINFO)
36 # define SANED_USES_AF_INDEP
37 # ifdef HAS_SS_FAMILY
38 # define SS_FAMILY(ss) ss.ss_family
39 # elif defined(HAS___SS_FAMILY)
40 # define SS_FAMILY(ss) ss.__ss_family
41 # else /* fallback to the old, IPv4-only code */
42 # undef SANED_USES_AF_INDEP
43 # undef ENABLE_IPV6
44 # endif
45 #else
46 # undef ENABLE_IPV6
47 #endif /* HAVE_GETADDRINFO && HAVE_GETNAMEINFO */
48
49 #include <assert.h>
50 #include <errno.h>
51 #include <fcntl.h>
52 #include <netdb.h>
53 #include <signal.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <syslog.h>
58 #include <time.h>
59 #include <unistd.h>
60 #include <limits.h>
61 #ifdef HAVE_LIBC_H
62 # include <libc.h> /* NeXTStep/OpenStep */
63 #endif
64
65 #ifdef HAVE_SYS_SELECT_H
66 # include <sys/select.h>
67 #endif
68
69 #include <netinet/in.h>
70
71 #include <stdarg.h>
72
73 #include <sys/param.h>
74 #include <sys/socket.h>
75
76 #include <sys/time.h>
77 #include <sys/types.h>
78 #include <arpa/inet.h>
79
80 #include <sys/wait.h>
81
82 #include <pwd.h>
83 #include <grp.h>
84
85 #include "lgetopt.h"
86
87 #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
88 # include <poll.h>
89 #else
90 /*
91 * This replacement poll() using select() is only designed to cover
92 * our needs in run_standalone(). It should probably be extended...
93 */
94 struct pollfd
95 {
96 int fd;
97 short events;
98 short revents;
99 };
100
101 #define POLLIN 0x0001
102 #define POLLERR 0x0002
103
104 int
105 poll (struct pollfd *ufds, unsigned int nfds, int timeout);
106
107 int
poll(struct pollfd * ufds,unsigned int nfds,int timeout)108 poll (struct pollfd *ufds, unsigned int nfds, int timeout)
109 {
110 struct pollfd *fdp;
111
112 fd_set rfds;
113 fd_set efds;
114 struct timeval tv;
115 int maxfd = 0;
116 unsigned int i;
117 int ret;
118
119 tv.tv_sec = timeout / 1000;
120 tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
121
122 FD_ZERO (&rfds);
123 FD_ZERO (&efds);
124
125 for (i = 0, fdp = ufds; i < nfds; i++, fdp++)
126 {
127 fdp->revents = 0;
128
129 if (fdp->events & POLLIN)
130 FD_SET (fdp->fd, &rfds);
131
132 FD_SET (fdp->fd, &efds);
133
134 maxfd = (fdp->fd > maxfd) ? fdp->fd : maxfd;
135 }
136
137 maxfd++;
138
139 ret = select (maxfd, &rfds, NULL, &efds, &tv);
140
141 if (ret < 0)
142 return ret;
143
144 for (i = 0, fdp = ufds; i < nfds; i++, fdp++)
145 {
146 if (fdp->events & POLLIN)
147 if (FD_ISSET (fdp->fd, &rfds))
148 fdp->revents |= POLLIN;
149
150 if (FD_ISSET (fdp->fd, &efds))
151 fdp->revents |= POLLERR;
152 }
153
154 return ret;
155 }
156 #endif /* HAVE_SYS_POLL_H && HAVE_POLL */
157
158 #if WITH_AVAHI
159 # include <avahi-client/client.h>
160 # include <avahi-client/publish.h>
161
162 # include <avahi-common/alternative.h>
163 # include <avahi-common/simple-watch.h>
164 # include <avahi-common/malloc.h>
165 # include <avahi-common/error.h>
166
167 # define SANED_SERVICE_DNS "_sane-port._tcp"
168 # define SANED_NAME "saned"
169
170 pid_t avahi_pid = -1;
171
172 char *avahi_svc_name;
173
174 static AvahiClient *avahi_client = NULL;
175 static AvahiSimplePoll *avahi_poll = NULL;
176 static AvahiEntryGroup *avahi_group = NULL;
177 #endif /* WITH_AVAHI */
178
179 #ifdef HAVE_SYSTEMD
180 #include <systemd/sd-daemon.h>
181 #endif
182
183
184 #include "../include/sane/sane.h"
185 #include "../include/sane/sanei.h"
186 #include "../include/sane/sanei_net.h"
187 #include "../include/sane/sanei_codec_bin.h"
188 #include "../include/sane/sanei_config.h"
189
190 #include "../include/sane/sanei_auth.h"
191
192 #ifndef EXIT_SUCCESS
193 # define EXIT_SUCCESS 0
194 #endif
195
196 #ifndef IN_LOOPBACK
197 # define IN_LOOPBACK(addr) (addr == 0x7f000001L)
198 #endif
199
200 #ifdef ENABLE_IPV6
201 # ifndef IN6_IS_ADDR_LOOPBACK
202 # define IN6_IS_ADDR_LOOPBACK(a) \
203 (((const uint32_t *) (a))[0] == 0 \
204 && ((const uint32_t *) (a))[1] == 0 \
205 && ((const uint32_t *) (a))[2] == 0 \
206 && ((const uint32_t *) (a))[3] == htonl (1))
207 # endif
208 # ifndef IN6_IS_ADDR_V4MAPPED
209 # define IN6_IS_ADDR_V4MAPPED(a) \
210 ((((const uint32_t *) (a))[0] == 0) \
211 && (((const uint32_t *) (a))[1] == 0) \
212 && (((const uint32_t *) (a))[2] == htonl (0xffff)))
213 # endif
214 #endif /* ENABLE_IPV6 */
215
216 #ifndef MAXHOSTNAMELEN
217 # define MAXHOSTNAMELEN 120
218 #endif
219
220 #ifndef PATH_MAX
221 # define PATH_MAX 1024
222 #endif
223
224 struct saned_child {
225 pid_t pid;
226 struct saned_child *next;
227 };
228 struct saned_child *children;
229 int numchildren;
230
231 #define SANED_CONFIG_FILE "saned.conf"
232 #define SANED_PID_FILE "/var/run/saned.pid"
233
234 #define SANED_SERVICE_NAME "sane-port"
235 #define SANED_SERVICE_PORT 6566
236 #define SANED_SERVICE_PORT_S "6566"
237
238 typedef struct
239 {
240 u_int inuse:1; /* is this handle in use? */
241 u_int scanning:1; /* are we scanning? */
242 u_int docancel:1; /* cancel the current scan */
243 SANE_Handle handle; /* backends handle */
244 }
245 Handle;
246
247 static SANE_Net_Procedure_Number current_request;
248 static const char *prog_name;
249 static int can_authorize;
250 static Wire wire;
251 static int num_handles;
252 static int debug;
253 static int run_mode;
254 static int run_foreground;
255 static int run_once;
256 static int data_connect_timeout = 4000;
257 static Handle *handle;
258 static char *bind_addr;
259 static short bind_port = -1;
260 static union
261 {
262 int w;
263 u_char ch;
264 }
265 byte_order;
266
267 /* The default-user name. This is not used to imply any rights. All
268 it does is save a remote user some work by reducing the amount of
269 text s/he has to type when authentication is requested. */
270 static const char *default_username = "saned-user";
271 static char *remote_ip;
272
273 /* data port range */
274 static in_port_t data_port_lo;
275 static in_port_t data_port_hi;
276
277 #ifdef SANED_USES_AF_INDEP
278 static union {
279 struct sockaddr_storage ss;
280 struct sockaddr sa;
281 struct sockaddr_in sin;
282 #ifdef ENABLE_IPV6
283 struct sockaddr_in6 sin6;
284 #endif
285 } remote_address;
286 static int remote_address_len;
287 #else
288 static struct in_addr remote_address;
289 #endif /* SANED_USES_AF_INDEP */
290
291 #ifndef _PATH_HEQUIV
292 # define _PATH_HEQUIV "/etc/hosts.equiv"
293 #endif
294
295 static const char *config_file_names[] = {
296 _PATH_HEQUIV, SANED_CONFIG_FILE
297 };
298
299 static SANE_Bool log_to_syslog = SANE_TRUE;
300
301 /* forward declarations: */
302 static int process_request (Wire * w);
303
304 #define SANED_RUN_INETD 0
305 #define SANED_RUN_ALONE 1
306
307 #define DBG_ERR 1
308 #define DBG_WARN 2
309 #define DBG_MSG 3
310 #define DBG_INFO 4
311 #define DBG_DBG 5
312
313 #define DBG saned_debug_call
314
315 static void
saned_debug_call(int level,const char * fmt,...)316 saned_debug_call (int level, const char *fmt, ...)
317 {
318 #ifndef NDEBUG
319 va_list ap;
320 va_start (ap, fmt);
321 if (debug >= level)
322 {
323 if (log_to_syslog)
324 {
325 /* print to syslog */
326 vsyslog (LOG_DEBUG, fmt, ap);
327 }
328 else
329 {
330 /* print to stderr */
331 fprintf (stderr, "[saned] ");
332 vfprintf (stderr, fmt, ap);
333 }
334 }
335 va_end (ap);
336 #endif
337 }
338
339
340 static void
reset_watchdog(void)341 reset_watchdog (void)
342 {
343 if (!debug)
344 alarm (3600);
345 }
346
347 static void
auth_callback(SANE_String_Const res,SANE_Char * username,SANE_Char * password)348 auth_callback (SANE_String_Const res,
349 SANE_Char *username,
350 SANE_Char *password)
351 {
352 SANE_Net_Procedure_Number procnum;
353 SANE_Authorization_Req req;
354 SANE_Word word, ack = 0;
355
356 memset (username, 0, SANE_MAX_USERNAME_LEN);
357 memset (password, 0, SANE_MAX_PASSWORD_LEN);
358
359 if (!can_authorize)
360 {
361 DBG (DBG_WARN,
362 "auth_callback: called during non-authorizable RPC (resource=%s)\n",
363 res);
364 return;
365 }
366
367 if (wire.status)
368 {
369 DBG(DBG_ERR, "auth_callback: bad status %d\n", wire.status);
370 return;
371 }
372
373 switch (current_request)
374 {
375 case SANE_NET_OPEN:
376 {
377 SANE_Open_Reply reply;
378
379 memset (&reply, 0, sizeof (reply));
380 reply.resource_to_authorize = (char *) res;
381 sanei_w_reply (&wire, (WireCodecFunc) sanei_w_open_reply, &reply);
382 }
383 break;
384
385 case SANE_NET_CONTROL_OPTION:
386 {
387 SANE_Control_Option_Reply reply;
388
389 memset (&reply, 0, sizeof (reply));
390 reply.resource_to_authorize = (char *) res;
391 sanei_w_reply (&wire,
392 (WireCodecFunc) sanei_w_control_option_reply, &reply);
393 }
394 break;
395
396 case SANE_NET_START:
397 {
398 SANE_Start_Reply reply;
399
400 memset (&reply, 0, sizeof (reply));
401 reply.resource_to_authorize = (char *) res;
402 sanei_w_reply (&wire, (WireCodecFunc) sanei_w_start_reply, &reply);
403 }
404 break;
405
406 default:
407 DBG (DBG_WARN,
408 "auth_callback: called for unexpected request %d (resource=%s)\n",
409 current_request, res);
410 break;
411 }
412
413 if (wire.status)
414 {
415 DBG(DBG_ERR, "auth_callback: bad status %d\n", wire.status);
416 return;
417 }
418
419 reset_watchdog ();
420
421 sanei_w_set_dir (&wire, WIRE_DECODE);
422 sanei_w_word (&wire, &word);
423
424 if (wire.status)
425 {
426 DBG(DBG_ERR, "auth_callback: bad status %d\n", wire.status);
427 return;
428 }
429
430 procnum = word;
431 if (procnum != SANE_NET_AUTHORIZE)
432 {
433 DBG (DBG_WARN,
434 "auth_callback: bad procedure number %d "
435 "(expected: %d, resource=%s)\n", procnum, SANE_NET_AUTHORIZE,
436 res);
437 return;
438 }
439
440 sanei_w_authorization_req (&wire, &req);
441 if (wire.status)
442 {
443 DBG(DBG_ERR, "auth_callback: bad status %d\n", wire.status);
444 return;
445 }
446
447 if (req.username)
448 strcpy (username, req.username);
449 if (req.password)
450 strcpy (password, req.password);
451 if (!req.resource || strcmp (req.resource, res) != 0)
452 {
453 DBG (DBG_MSG,
454 "auth_callback: got auth for resource %s (expected resource=%s)\n",
455 res, req.resource);
456 }
457 sanei_w_free (&wire, (WireCodecFunc) sanei_w_authorization_req, &req);
458 sanei_w_reply (&wire, (WireCodecFunc) sanei_w_word, &ack);
459 }
460
461 static void
quit(int signum)462 quit (int signum)
463 {
464 static int running = 0;
465 int i;
466
467 if (signum)
468 DBG (DBG_ERR, "quit: received signal %d\n", signum);
469
470 if (running)
471 {
472 DBG (DBG_ERR, "quit: already active, returning\n");
473 return;
474 }
475 running = 1;
476
477 for (i = 0; i < num_handles; ++i)
478 if (handle[i].inuse)
479 sane_close (handle[i].handle);
480
481 sane_exit ();
482 sanei_w_exit (&wire);
483 if (handle)
484 free (handle);
485 DBG (DBG_WARN, "quit: exiting\n");
486 if (log_to_syslog)
487 closelog ();
488 exit (EXIT_SUCCESS); /* This is a nowait-daemon. */
489 }
490
491 static SANE_Word
get_free_handle(void)492 get_free_handle (void)
493 {
494 # define ALLOC_INCREMENT 16
495 static int h, last_handle_checked = -1;
496
497 if (num_handles > 0)
498 {
499 h = last_handle_checked + 1;
500 do
501 {
502 if (h >= num_handles)
503 h = 0;
504 if (!handle[h].inuse)
505 {
506 last_handle_checked = h;
507 memset (handle + h, 0, sizeof (handle[0]));
508 handle[h].inuse = 1;
509 return h;
510 }
511 ++h;
512 }
513 while (h != last_handle_checked);
514 }
515
516 /* we're out of handles---alloc some more: */
517 last_handle_checked = num_handles - 1;
518 num_handles += ALLOC_INCREMENT;
519 if (handle)
520 handle = realloc (handle, num_handles * sizeof (handle[0]));
521 else
522 handle = malloc (num_handles * sizeof (handle[0]));
523 if (!handle)
524 return -1;
525 memset (handle + last_handle_checked + 1, 0,
526 ALLOC_INCREMENT * sizeof (handle[0]));
527 return get_free_handle ();
528 # undef ALLOC_INCREMENT
529 }
530
531 static void
close_handle(int h)532 close_handle (int h)
533 {
534 if (h >= 0 && handle[h].inuse)
535 {
536 sane_close (handle[h].handle);
537 handle[h].inuse = 0;
538 }
539 }
540
541 static SANE_Word
decode_handle(Wire * w,const char * op)542 decode_handle (Wire * w, const char *op)
543 {
544 SANE_Word h;
545
546 sanei_w_word (w, &h);
547 if (w->status || (unsigned) h >= (unsigned) num_handles || !handle[h].inuse)
548 {
549 DBG (DBG_ERR,
550 "decode_handle: %s: error while decoding handle argument "
551 "(h=%d, %s)\n", op, h, strerror (w->status));
552 return -1;
553 }
554 return h;
555 }
556
557
558
559 /* Convert a number of bits to an 8-bit bitmask */
560 static unsigned int cidrtomask[9] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0,
561 0xF8, 0xFC, 0xFE, 0xFF };
562
563 #ifdef SANED_USES_AF_INDEP
564 static SANE_Bool
check_v4_in_range(struct sockaddr_in * sin,char * base_ip,char * netmask)565 check_v4_in_range (struct sockaddr_in *sin, char *base_ip, char *netmask)
566 {
567 int cidr;
568 int i, err;
569 char *end;
570 uint32_t mask;
571 struct sockaddr_in *base;
572 struct addrinfo hints;
573 struct addrinfo *res;
574 SANE_Bool ret = SANE_FALSE;
575
576 cidr = -1;
577 cidr = strtol (netmask, &end, 10);
578
579 /* Sanity check on the cidr value */
580 if ((cidr < 0) || (cidr > 32) || (end == netmask))
581 {
582 DBG (DBG_ERR, "check_v4_in_range: invalid CIDR value (%s) !\n", netmask);
583 return SANE_FALSE;
584 }
585
586 mask = 0;
587 cidr -= 8;
588
589 /* Build a bitmask out of the CIDR value */
590 for (i = 3; cidr >= 0; i--)
591 {
592 mask |= (0xff << (8 * i));
593 cidr -= 8;
594 }
595
596 if (cidr < 0)
597 mask |= (cidrtomask[cidr + 8] << (8 * i));
598
599 mask = htonl (mask);
600
601 /* get a sockaddr_in representing the base IP address */
602 memset (&hints, 0, sizeof (struct addrinfo));
603 hints.ai_flags = AI_NUMERICHOST;
604 hints.ai_family = PF_INET;
605
606 err = getaddrinfo (base_ip, NULL, &hints, &res);
607 if (err)
608 {
609 DBG (DBG_DBG, "check_v4_in_range: getaddrinfo() failed: %s\n", gai_strerror (err));
610 return SANE_FALSE;
611 }
612
613 base = (struct sockaddr_in *) res->ai_addr;
614
615 /*
616 * Check that the address belongs to the specified subnet, using the bitmask.
617 * The address is represented by a 32bit integer.
618 */
619 if ((base->sin_addr.s_addr & mask) == (sin->sin_addr.s_addr & mask))
620 ret = SANE_TRUE;
621
622 freeaddrinfo (res);
623
624 return ret;
625 }
626
627
628 # ifdef ENABLE_IPV6
629
630 static SANE_Bool
check_v6_in_range(struct sockaddr_in6 * sin6,char * base_ip,char * netmask)631 check_v6_in_range (struct sockaddr_in6 *sin6, char *base_ip, char *netmask)
632 {
633 int cidr;
634 int i, err;
635 unsigned int mask[16];
636 char *end;
637 struct sockaddr_in6 *base;
638 struct addrinfo hints;
639 struct addrinfo *res;
640 SANE_Bool ret = SANE_TRUE;
641
642 cidr = -1;
643 cidr = strtol (netmask, &end, 10);
644
645 /* Sanity check on the cidr value */
646 if ((cidr < 0) || (cidr > 128) || (end == netmask))
647 {
648 DBG (DBG_ERR, "check_v6_in_range: invalid CIDR value (%s) !\n", netmask);
649 return SANE_FALSE;
650 }
651
652 memset (mask, 0, (16 * sizeof (unsigned int)));
653 cidr -= 8;
654
655 /* Build a bitmask out of the CIDR value */
656 for (i = 0; cidr >= 0; i++)
657 {
658 mask[i] = 0xff;
659 cidr -= 8;
660 }
661
662 if (cidr < 0)
663 mask[i] = cidrtomask[cidr + 8];
664
665 /* get a sockaddr_in6 representing the base IP address */
666 memset (&hints, 0, sizeof (struct addrinfo));
667 hints.ai_flags = AI_NUMERICHOST;
668 hints.ai_family = PF_INET6;
669
670 err = getaddrinfo (base_ip, NULL, &hints, &res);
671 if (err)
672 {
673 DBG (DBG_DBG, "check_v6_in_range: getaddrinfo() failed: %s\n", gai_strerror (err));
674 return SANE_FALSE;
675 }
676
677 base = (struct sockaddr_in6 *) res->ai_addr;
678
679 /*
680 * Check that the address belongs to the specified subnet.
681 * The address is reprensented by an array of 16 8bit integers.
682 */
683 for (i = 0; i < 16; i++)
684 {
685 if ((base->sin6_addr.s6_addr[i] & mask[i]) != (sin6->sin6_addr.s6_addr[i] & mask[i]))
686 {
687 ret = SANE_FALSE;
688 break;
689 }
690 }
691
692 freeaddrinfo (res);
693
694 return ret;
695 }
696 # endif /* ENABLE_IPV6 */
697 #else /* !SANED_USES_AF_INDEP */
698 static SANE_Bool
check_v4_in_range(struct in_addr * inaddr,struct in_addr * base,char * netmask)699 check_v4_in_range (struct in_addr *inaddr, struct in_addr *base, char *netmask)
700 {
701 int cidr;
702 int i;
703 char *end;
704 uint32_t mask;
705 SANE_Bool ret = SANE_FALSE;
706
707 cidr = -1;
708 cidr = strtol (netmask, &end, 10);
709
710 /* sanity check on the cidr value */
711 if ((cidr < 0) || (cidr > 32) || (end == netmask))
712 {
713 DBG (DBG_ERR, "check_v4_in_range: invalid CIDR value (%s) !\n", netmask);
714 return SANE_FALSE;
715 }
716
717 mask = 0;
718 cidr -= 8;
719
720 /* Build a bitmask out of the CIDR value */
721 for (i = 3; cidr >= 0; i--)
722 {
723 mask |= (0xff << (8 * i));
724 cidr -= 8;
725 }
726
727 if (cidr < 0)
728 mask |= (cidrtomask[cidr + 8] << (8 * i));
729
730 mask = htonl (mask);
731
732 /*
733 * Check that the address belongs to the specified subnet, using the bitmask.
734 * The address is represented by a 32bit integer.
735 */
736 if ((base->s_addr & mask) == (inaddr->s_addr & mask))
737 ret = SANE_TRUE;
738
739 return ret;
740 }
741 #endif /* SANED_USES_AF_INDEP */
742
743
744
745 /* Access control */
746 #ifdef SANED_USES_AF_INDEP
747 static SANE_Status
check_host(int fd)748 check_host (int fd)
749 {
750 struct sockaddr_in *sin = NULL;
751 #ifdef ENABLE_IPV6
752 struct sockaddr_in6 *sin6;
753 #endif /* ENABLE_IPV6 */
754 struct addrinfo hints;
755 struct addrinfo *res;
756 struct addrinfo *resp;
757 int j, access_ok = 0;
758 int err;
759 char text_addr[64];
760 #ifdef ENABLE_IPV6
761 SANE_Bool IPv4map = SANE_FALSE;
762 char *remote_ipv4 = NULL; /* in case we have an IPv4-mapped address (eg ::ffff:127.0.0.1) */
763 char *tmp;
764 struct addrinfo *remote_ipv4_addr = NULL;
765 #endif /* ENABLE_IPV6 */
766 char config_line_buf[1024];
767 char *config_line;
768 char *netmask;
769 char hostname[MAXHOSTNAMELEN];
770
771 int len;
772 FILE *fp;
773
774 /* Get address of remote host */
775 remote_address_len = sizeof (remote_address.ss);
776 if (getpeername (fd, &remote_address.sa, (socklen_t *) &remote_address_len) < 0)
777 {
778 DBG (DBG_ERR, "check_host: getpeername failed: %s\n", strerror (errno));
779 remote_ip = strdup ("[error]");
780 return SANE_STATUS_INVAL;
781 }
782
783 err = getnameinfo (&remote_address.sa, remote_address_len,
784 hostname, sizeof (hostname), NULL, 0, NI_NUMERICHOST);
785 if (err)
786 {
787 DBG (DBG_DBG, "check_host: getnameinfo failed: %s\n", gai_strerror(err));
788 remote_ip = strdup ("[error]");
789 return SANE_STATUS_INVAL;
790 }
791 else
792 remote_ip = strdup (hostname);
793
794 #ifdef ENABLE_IPV6
795 sin6 = &remote_address.sin6;
796
797 if (IN6_IS_ADDR_V4MAPPED ((struct in6_addr *)sin6->sin6_addr.s6_addr))
798 {
799 DBG (DBG_DBG, "check_host: detected an IPv4-mapped address\n");
800 remote_ipv4 = remote_ip + 7;
801 IPv4map = SANE_TRUE;
802
803 memset (&hints, 0, sizeof (struct addrinfo));
804 hints.ai_flags = AI_NUMERICHOST;
805 hints.ai_family = PF_INET;
806
807 err = getaddrinfo (remote_ipv4, NULL, &hints, &res);
808 if (err)
809 {
810 DBG (DBG_DBG, "check_host: getaddrinfo() failed: %s\n", gai_strerror (err));
811 IPv4map = SANE_FALSE; /* we failed, remote_ipv4_addr points to nothing */
812 }
813 else
814 {
815 remote_ipv4_addr = res;
816 sin = (struct sockaddr_in *)res->ai_addr;
817 }
818 }
819 #endif /* ENABLE_IPV6 */
820
821 DBG (DBG_WARN, "check_host: access by remote host: %s\n", remote_ip);
822
823 /* Always allow access from local host. Do it here to avoid DNS lookups
824 and reading saned.conf. */
825
826 #ifdef ENABLE_IPV6
827 if (IPv4map == SANE_TRUE)
828 {
829 if (IN_LOOPBACK (ntohl (sin->sin_addr.s_addr)))
830 {
831 DBG (DBG_MSG,
832 "check_host: remote host is IN_LOOPBACK: access granted\n");
833 freeaddrinfo (remote_ipv4_addr);
834 return SANE_STATUS_GOOD;
835 }
836 freeaddrinfo (remote_ipv4_addr);
837 }
838 #endif /* ENABLE_IPV6 */
839
840 sin = &remote_address.sin;
841
842 switch (SS_FAMILY(remote_address.ss))
843 {
844 case AF_INET:
845 if (IN_LOOPBACK (ntohl (sin->sin_addr.s_addr)))
846 {
847 DBG (DBG_MSG,
848 "check_host: remote host is IN_LOOPBACK: access granted\n");
849 return SANE_STATUS_GOOD;
850 }
851 break;
852 #ifdef ENABLE_IPV6
853 case AF_INET6:
854 if (IN6_IS_ADDR_LOOPBACK ((struct in6_addr *)sin6->sin6_addr.s6_addr))
855 {
856 DBG (DBG_MSG,
857 "check_host: remote host is IN6_LOOPBACK: access granted\n");
858 return SANE_STATUS_GOOD;
859 }
860 break;
861 #endif /* ENABLE_IPV6 */
862 default:
863 break;
864 }
865
866 DBG (DBG_DBG, "check_host: remote host is not IN_LOOPBACK"
867 #ifdef ENABLE_IPV6
868 " nor IN6_LOOPBACK"
869 #endif /* ENABLE_IPV6 */
870 "\n");
871
872
873 /* Get name of local host */
874 if (gethostname (hostname, sizeof (hostname)) < 0)
875 {
876 DBG (DBG_ERR, "check_host: gethostname failed: %s\n", strerror (errno));
877 return SANE_STATUS_INVAL;
878 }
879 DBG (DBG_DBG, "check_host: local hostname: %s\n", hostname);
880
881 /* Get local addresses */
882 memset (&hints, 0, sizeof (hints));
883 hints.ai_flags = AI_CANONNAME;
884 #ifdef ENABLE_IPV6
885 hints.ai_family = PF_UNSPEC;
886 #else
887 hints.ai_family = PF_INET;
888 #endif /* ENABLE_IPV6 */
889
890 err = getaddrinfo (hostname, NULL, &hints, &res);
891 if (err)
892 {
893 DBG (DBG_ERR, "check_host: getaddrinfo for local hostname failed: %s\n",
894 gai_strerror (err));
895
896 /* Proceed even if the local hostname does not resolve */
897 if (err != EAI_NONAME)
898 return SANE_STATUS_INVAL;
899 }
900 else
901 {
902 for (resp = res; resp != NULL; resp = resp->ai_next)
903 {
904 DBG (DBG_DBG, "check_host: local hostname(s) (from DNS): %s\n",
905 resp->ai_canonname);
906
907 err = getnameinfo (resp->ai_addr, resp->ai_addrlen, text_addr,
908 sizeof (text_addr), NULL, 0, NI_NUMERICHOST);
909 if (err)
910 strncpy (text_addr, "[error]", 8);
911
912 #ifdef ENABLE_IPV6
913 if ((strcasecmp (text_addr, remote_ip) == 0) ||
914 ((IPv4map == SANE_TRUE) && (strcmp (text_addr, remote_ipv4) == 0)))
915 #else
916 if (strcmp (text_addr, remote_ip) == 0)
917 #endif /* ENABLE_IPV6 */
918 {
919 DBG (DBG_MSG, "check_host: remote host has same addr as local: access granted\n");
920
921 freeaddrinfo (res);
922 res = NULL;
923
924 return SANE_STATUS_GOOD;
925 }
926 }
927
928 freeaddrinfo (res);
929 res = NULL;
930
931 DBG (DBG_DBG,
932 "check_host: remote host doesn't have same addr as local\n");
933 }
934
935 /* must be a remote host: check contents of PATH_NET_CONFIG or
936 /etc/hosts.equiv if former doesn't exist: */
937 for (j = 0; j < NELEMS (config_file_names); ++j)
938 {
939 DBG (DBG_DBG, "check_host: opening config file: %s\n",
940 config_file_names[j]);
941 if (config_file_names[j][0] == '/')
942 fp = fopen (config_file_names[j], "r");
943 else
944 fp = sanei_config_open (config_file_names[j]);
945 if (!fp)
946 {
947 DBG (DBG_MSG,
948 "check_host: can't open config file: %s (%s)\n",
949 config_file_names[j], strerror (errno));
950 continue;
951 }
952
953 while (!access_ok && sanei_config_read (config_line_buf,
954 sizeof (config_line_buf), fp))
955 {
956 config_line = config_line_buf; /* from now on, use a pointer */
957 DBG (DBG_DBG, "check_host: config file line: `%s'\n", config_line);
958 if (config_line[0] == '#')
959 continue; /* ignore comments */
960
961 if (strchr (config_line, '='))
962 continue; /* ignore lines with an = sign */
963
964 len = strlen (config_line);
965 if (!len)
966 continue; /* ignore empty lines */
967
968 /* look for a subnet specification */
969 netmask = strchr (config_line, '/');
970 if (netmask != NULL)
971 {
972 *netmask = '\0';
973 netmask++;
974 DBG (DBG_DBG, "check_host: subnet with base IP = %s, CIDR netmask = %s\n",
975 config_line, netmask);
976 }
977
978 #ifdef ENABLE_IPV6
979 /* IPv6 addresses are enclosed in [] */
980 if (*config_line == '[')
981 {
982 config_line++;
983 tmp = strchr (config_line, ']');
984 if (tmp == NULL)
985 {
986 DBG (DBG_ERR,
987 "check_host: malformed IPv6 address in config file, skipping: [%s\n",
988 config_line);
989 continue;
990 }
991 *tmp = '\0';
992 }
993 #endif /* ENABLE_IPV6 */
994
995 if (strcmp (config_line, "+") == 0)
996 {
997 access_ok = 1;
998 DBG (DBG_DBG,
999 "check_host: access granted from any host (`+')\n");
1000 }
1001 /* compare remote_ip (remote IP address) to the config_line */
1002 else if (strcasecmp (config_line, remote_ip) == 0)
1003 {
1004 access_ok = 1;
1005 DBG (DBG_DBG,
1006 "check_host: access granted from IP address %s\n", remote_ip);
1007 }
1008 #ifdef ENABLE_IPV6
1009 else if ((IPv4map == SANE_TRUE) && (strcmp (config_line, remote_ipv4) == 0))
1010 {
1011 access_ok = 1;
1012 DBG (DBG_DBG,
1013 "check_host: access granted from IP address %s (IPv4-mapped)\n", remote_ip);
1014 }
1015 /* handle IP ranges, take care of the IPv4map stuff */
1016 else if (netmask != NULL)
1017 {
1018 if (strchr (config_line, ':') != NULL) /* is a v6 address */
1019 {
1020 if (SS_FAMILY(remote_address.ss) == AF_INET6)
1021 {
1022 if (check_v6_in_range (sin6, config_line, netmask))
1023 {
1024 access_ok = 1;
1025 DBG (DBG_DBG, "check_host: access granted from IP address %s (in subnet [%s]/%s)\n",
1026 remote_ip, config_line, netmask);
1027 }
1028 }
1029 }
1030 else /* is a v4 address */
1031 {
1032 if (IPv4map == SANE_TRUE)
1033 {
1034 /* get a sockaddr_in representing the v4-mapped IP address */
1035 memset (&hints, 0, sizeof (struct addrinfo));
1036 hints.ai_flags = AI_NUMERICHOST;
1037 hints.ai_family = PF_INET;
1038
1039 err = getaddrinfo (remote_ipv4, NULL, &hints, &res);
1040 if (err)
1041 DBG (DBG_DBG, "check_host: getaddrinfo() failed: %s\n", gai_strerror (err));
1042 else
1043 sin = (struct sockaddr_in *)res->ai_addr;
1044 }
1045
1046 if ((SS_FAMILY(remote_address.ss) == AF_INET) ||
1047 (IPv4map == SANE_TRUE))
1048 {
1049
1050 if (check_v4_in_range (sin, config_line, netmask))
1051 {
1052 DBG (DBG_DBG, "check_host: access granted from IP address %s (in subnet %s/%s)\n",
1053 ((IPv4map == SANE_TRUE) ? remote_ipv4 : remote_ip), config_line, netmask);
1054 access_ok = 1;
1055 }
1056 else
1057 {
1058 /* restore the old sin pointer */
1059 sin = &remote_address.sin;
1060 }
1061
1062 if (res != NULL)
1063 {
1064 freeaddrinfo (res);
1065 res = NULL;
1066 }
1067 }
1068 }
1069 }
1070 #else /* !ENABLE_IPV6 */
1071 /* handle IP ranges */
1072 else if (netmask != NULL)
1073 {
1074 if (check_v4_in_range (sin, config_line, netmask))
1075 {
1076 access_ok = 1;
1077 DBG (DBG_DBG, "check_host: access granted from IP address %s (in subnet %s/%s)\n",
1078 remote_ip, config_line, netmask);
1079 }
1080 }
1081 #endif /* ENABLE_IPV6 */
1082 else
1083 {
1084 memset (&hints, 0, sizeof (hints));
1085 hints.ai_flags = AI_CANONNAME;
1086 #ifdef ENABLE_IPV6
1087 hints.ai_family = PF_UNSPEC;
1088 #else
1089 hints.ai_family = PF_INET;
1090 #endif /* ENABLE_IPV6 */
1091
1092 err = getaddrinfo (config_line, NULL, &hints, &res);
1093 if (err)
1094 {
1095 DBG (DBG_DBG,
1096 "check_host: getaddrinfo for `%s' failed: %s\n",
1097 config_line, gai_strerror (err));
1098 DBG (DBG_MSG, "check_host: entry isn't an IP address "
1099 "and can't be found in DNS\n");
1100 continue;
1101 }
1102 else
1103 {
1104 for (resp = res; resp != NULL; resp = resp->ai_next)
1105 {
1106 err = getnameinfo (resp->ai_addr, resp->ai_addrlen, text_addr,
1107 sizeof (text_addr), NULL, 0, NI_NUMERICHOST);
1108 if (err)
1109 strncpy (text_addr, "[error]", 8);
1110
1111 DBG (DBG_MSG,
1112 "check_host: DNS lookup returns IP address: %s\n",
1113 text_addr);
1114
1115 #ifdef ENABLE_IPV6
1116 if ((strcasecmp (text_addr, remote_ip) == 0) ||
1117 ((IPv4map == SANE_TRUE) && (strcmp (text_addr, remote_ipv4) == 0)))
1118 #else
1119 if (strcmp (text_addr, remote_ip) == 0)
1120 #endif /* ENABLE_IPV6 */
1121 access_ok = 1;
1122
1123 if (access_ok)
1124 break;
1125 }
1126 freeaddrinfo (res);
1127 res = NULL;
1128 }
1129 }
1130 }
1131 fclose (fp);
1132 }
1133
1134 if (access_ok)
1135 return SANE_STATUS_GOOD;
1136
1137 return SANE_STATUS_ACCESS_DENIED;
1138 }
1139
1140 #else /* !SANED_USES_AF_INDEP */
1141
1142 static SANE_Status
check_host(int fd)1143 check_host (int fd)
1144 {
1145 struct sockaddr_in sin;
1146 int j, access_ok = 0;
1147 struct hostent *he;
1148 char text_addr[64];
1149 char config_line_buf[1024];
1150 char *config_line;
1151 char *netmask;
1152 char hostname[MAXHOSTNAMELEN];
1153 char *r_hostname;
1154 static struct in_addr config_line_address;
1155
1156 int len;
1157 FILE *fp;
1158
1159 /* Get address of remote host */
1160 len = sizeof (sin);
1161 if (getpeername (fd, (struct sockaddr *) &sin, (socklen_t *) &len) < 0)
1162 {
1163 DBG (DBG_ERR, "check_host: getpeername failed: %s\n", strerror (errno));
1164 remote_ip = strdup ("[error]");
1165 return SANE_STATUS_INVAL;
1166 }
1167 r_hostname = inet_ntoa (sin.sin_addr);
1168 remote_ip = strdup (r_hostname);
1169 DBG (DBG_WARN, "check_host: access by remote host: %s\n",
1170 remote_ip);
1171 /* Save remote address for check of control and data connections */
1172 memcpy (&remote_address, &sin.sin_addr, sizeof (remote_address));
1173
1174 /* Always allow access from local host. Do it here to avoid DNS lookups
1175 and reading saned.conf. */
1176 if (IN_LOOPBACK (ntohl (sin.sin_addr.s_addr)))
1177 {
1178 DBG (DBG_MSG,
1179 "check_host: remote host is IN_LOOPBACK: access accepted\n");
1180 return SANE_STATUS_GOOD;
1181 }
1182 DBG (DBG_DBG, "check_host: remote host is not IN_LOOPBACK\n");
1183
1184 /* Get name of local host */
1185 if (gethostname (hostname, sizeof (hostname)) < 0)
1186 {
1187 DBG (DBG_ERR, "check_host: gethostname failed: %s\n", strerror (errno));
1188 return SANE_STATUS_INVAL;
1189 }
1190 DBG (DBG_DBG, "check_host: local hostname: %s\n", hostname);
1191
1192 /* Get local address */
1193 he = gethostbyname (hostname);
1194
1195 if (!he)
1196 {
1197 DBG (DBG_ERR, "check_host: gethostbyname for local hostname failed: %s\n",
1198 hstrerror (h_errno));
1199
1200 /* Proceed even if the local hostname doesn't resolve */
1201 if (h_errno != HOST_NOT_FOUND)
1202 return SANE_STATUS_INVAL;
1203 }
1204 else
1205 {
1206 DBG (DBG_DBG, "check_host: local hostname (from DNS): %s\n",
1207 he->h_name);
1208
1209 if ((he->h_length == 4) || (he->h_addrtype == AF_INET))
1210 {
1211 if (!inet_ntop (he->h_addrtype, he->h_addr_list[0], text_addr,
1212 sizeof (text_addr)))
1213 strcpy (text_addr, "[error]");
1214 DBG (DBG_DBG, "check_host: local host address (from DNS): %s\n",
1215 text_addr);
1216 if (memcmp (he->h_addr_list[0], &remote_address.s_addr, 4) == 0)
1217 {
1218 DBG (DBG_MSG,
1219 "check_host: remote host has same addr as local: "
1220 "access accepted\n");
1221 return SANE_STATUS_GOOD;
1222 }
1223 }
1224 else
1225 {
1226 DBG (DBG_ERR, "check_host: can't get local address "
1227 "(only IPv4 is supported)\n");
1228 }
1229
1230 DBG (DBG_DBG,
1231 "check_host: remote host doesn't have same addr as local\n");
1232 }
1233
1234 /* must be a remote host: check contents of PATH_NET_CONFIG or
1235 /etc/hosts.equiv if former doesn't exist: */
1236 for (j = 0; j < NELEMS (config_file_names); ++j)
1237 {
1238 DBG (DBG_DBG, "check_host: opening config file: %s\n",
1239 config_file_names[j]);
1240 if (config_file_names[j][0] == '/')
1241 fp = fopen (config_file_names[j], "r");
1242 else
1243 fp = sanei_config_open (config_file_names[j]);
1244 if (!fp)
1245 {
1246 DBG (DBG_MSG,
1247 "check_host: can't open config file: %s (%s)\n",
1248 config_file_names[j], strerror (errno));
1249 continue;
1250 }
1251
1252 while (!access_ok && sanei_config_read (config_line_buf,
1253 sizeof (config_line_buf), fp))
1254 {
1255 config_line = config_line_buf; /* from now on, use a pointer */
1256 DBG (DBG_DBG, "check_host: config file line: `%s'\n", config_line);
1257 if (config_line[0] == '#')
1258 continue; /* ignore comments */
1259
1260 if (strchr (config_line, '='))
1261 continue; /* ignore lines with an = sign */
1262
1263 len = strlen (config_line);
1264 if (!len)
1265 continue; /* ignore empty lines */
1266
1267 /* look for a subnet specification */
1268 netmask = strchr (config_line, '/');
1269 if (netmask != NULL)
1270 {
1271 *netmask = '\0';
1272 netmask++;
1273 DBG (DBG_DBG, "check_host: subnet with base IP = %s, CIDR netmask = %s\n",
1274 config_line, netmask);
1275 }
1276
1277 if (strcmp (config_line, "+") == 0)
1278 {
1279 access_ok = 1;
1280 DBG (DBG_DBG,
1281 "check_host: access accepted from any host (`+')\n");
1282 }
1283 else
1284 {
1285 if (inet_pton (AF_INET, config_line, &config_line_address) > 0)
1286 {
1287 if (memcmp (&remote_address.s_addr,
1288 &config_line_address.s_addr, 4) == 0)
1289 access_ok = 1;
1290 else if (netmask != NULL)
1291 {
1292 if (check_v4_in_range (&remote_address, &config_line_address, netmask))
1293 {
1294 access_ok = 1;
1295 DBG (DBG_DBG, "check_host: access granted from IP address %s (in subnet %s/%s)\n",
1296 remote_ip, config_line, netmask);
1297 }
1298 }
1299 }
1300 else
1301 {
1302 DBG (DBG_DBG,
1303 "check_host: inet_pton for `%s' failed\n",
1304 config_line);
1305 he = gethostbyname (config_line);
1306 if (!he)
1307 {
1308 DBG (DBG_DBG,
1309 "check_host: gethostbyname for `%s' failed: %s\n",
1310 config_line, hstrerror (h_errno));
1311 DBG (DBG_MSG, "check_host: entry isn't an IP address "
1312 "and can't be found in DNS\n");
1313 continue;
1314 }
1315 if (!inet_ntop (he->h_addrtype, he->h_addr_list[0],
1316 text_addr, sizeof (text_addr)))
1317 strcpy (text_addr, "[error]");
1318 DBG (DBG_MSG,
1319 "check_host: DNS lookup returns IP address: %s\n",
1320 text_addr);
1321 if (memcmp (&remote_address.s_addr,
1322 he->h_addr_list[0], 4) == 0)
1323 access_ok = 1;
1324 }
1325 }
1326 }
1327 fclose (fp);
1328 if (access_ok)
1329 return SANE_STATUS_GOOD;
1330 }
1331 return SANE_STATUS_ACCESS_DENIED;
1332 }
1333
1334 #endif /* SANED_USES_AF_INDEP */
1335
1336 static int
init(Wire * w)1337 init (Wire * w)
1338 {
1339 SANE_Word word, be_version_code;
1340 SANE_Init_Reply reply;
1341 SANE_Status status;
1342 SANE_Init_Req req;
1343
1344 reset_watchdog ();
1345
1346 status = check_host (w->io.fd);
1347 if (status != SANE_STATUS_GOOD)
1348 {
1349 DBG (DBG_WARN, "init: access by host %s denied\n", remote_ip);
1350 return -1;
1351 }
1352 else
1353 DBG (DBG_MSG, "init: access granted\n");
1354
1355 sanei_w_set_dir (w, WIRE_DECODE);
1356 if (w->status)
1357 {
1358 DBG (DBG_ERR, "init: bad status after sanei_w_set_dir: %d\n", w->status);
1359 return -1;
1360 }
1361
1362 sanei_w_word (w, &word); /* decode procedure number */
1363 if (w->status || word != SANE_NET_INIT)
1364 {
1365 DBG (DBG_ERR, "init: bad status=%d or procnum=%d\n",
1366 w->status, word);
1367 return -1;
1368 }
1369
1370 sanei_w_init_req (w, &req);
1371 if (w->status)
1372 {
1373 DBG (DBG_ERR, "init: bad status after sanei_w_init_req: %d\n", w->status);
1374 return -1;
1375 }
1376
1377 w->version = SANEI_NET_PROTOCOL_VERSION;
1378 if (req.username)
1379 default_username = strdup (req.username);
1380
1381 sanei_w_free (w, (WireCodecFunc) sanei_w_init_req, &req);
1382 if (w->status)
1383 {
1384 DBG (DBG_ERR, "init: bad status after sanei_w_free: %d\n", w->status);
1385 return -1;
1386 }
1387
1388 reply.version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR,
1389 SANEI_NET_PROTOCOL_VERSION);
1390
1391 DBG (DBG_WARN, "init: access granted to %s@%s\n",
1392 default_username, remote_ip);
1393
1394 if (status == SANE_STATUS_GOOD)
1395 {
1396 status = sane_init (&be_version_code, auth_callback);
1397 if (status != SANE_STATUS_GOOD)
1398 DBG (DBG_ERR, "init: failed to initialize backend (%s)\n",
1399 sane_strstatus (status));
1400
1401 if (SANE_VERSION_MAJOR (be_version_code) != V_MAJOR)
1402 {
1403 DBG (DBG_ERR,
1404 "init: unexpected backend major version %d (expected %d)\n",
1405 SANE_VERSION_MAJOR (be_version_code), V_MAJOR);
1406 status = SANE_STATUS_INVAL;
1407 }
1408 }
1409 reply.status = status;
1410 if (status != SANE_STATUS_GOOD)
1411 reply.version_code = 0;
1412 sanei_w_reply (w, (WireCodecFunc) sanei_w_init_reply, &reply);
1413
1414 if (w->status || status != SANE_STATUS_GOOD)
1415 return -1;
1416
1417 return 0;
1418 }
1419
1420 #ifdef SANED_USES_AF_INDEP
1421 static int
start_scan(Wire * w,int h,SANE_Start_Reply * reply)1422 start_scan (Wire * w, int h, SANE_Start_Reply * reply)
1423 {
1424 union {
1425 struct sockaddr_storage ss;
1426 struct sockaddr sa;
1427 struct sockaddr_in sin;
1428 #ifdef ENABLE_IPV6
1429 struct sockaddr_in6 sin6;
1430 #endif /* ENABLE_IPV6 */
1431 } data_addr;
1432 struct sockaddr_in *sin;
1433 #ifdef ENABLE_IPV6
1434 struct sockaddr_in6 *sin6;
1435 #endif /* ENABLE_IPV6 */
1436 SANE_Handle be_handle;
1437 int fd, len;
1438 in_port_t data_port;
1439 int ret = -1;
1440
1441 be_handle = handle[h].handle;
1442
1443 len = sizeof (data_addr.ss);
1444 if (getsockname (w->io.fd, &data_addr.sa, (socklen_t *) &len) < 0)
1445 {
1446 DBG (DBG_ERR, "start_scan: failed to obtain socket address (%s)\n",
1447 strerror (errno));
1448 reply->status = SANE_STATUS_IO_ERROR;
1449 return -1;
1450 }
1451
1452 fd = socket (SS_FAMILY(data_addr.ss), SOCK_STREAM, 0);
1453 if (fd < 0)
1454 {
1455 DBG (DBG_ERR, "start_scan: failed to obtain data socket (%s)\n",
1456 strerror (errno));
1457 reply->status = SANE_STATUS_IO_ERROR;
1458 return -1;
1459 }
1460
1461 switch (SS_FAMILY(data_addr.ss))
1462 {
1463 case AF_INET:
1464 sin = &data_addr.sin;
1465 break;
1466 #ifdef ENABLE_IPV6
1467 case AF_INET6:
1468 sin6 = &data_addr.sin6;
1469 break;
1470 #endif /* ENABLE_IPV6 */
1471 default:
1472 break;
1473 }
1474
1475 /* Try to bind a port between data_port_lo and data_port_hi for the data connection */
1476 for (data_port = data_port_lo; data_port <= data_port_hi; data_port++)
1477 {
1478 switch (SS_FAMILY(data_addr.ss))
1479 {
1480 case AF_INET:
1481 sin->sin_port = htons(data_port);
1482 break;
1483 #ifdef ENABLE_IPV6
1484 case AF_INET6:
1485 sin6->sin6_port = htons(data_port);
1486 break;
1487 #endif /* ENABLE_IPV6 */
1488 default:
1489 break;
1490 }
1491
1492 DBG (DBG_INFO, "start_scan: trying to bind data port %d\n", data_port);
1493
1494 ret = bind (fd, &data_addr.sa, len);
1495 if (ret == 0)
1496 break;
1497 }
1498
1499 if (ret < 0)
1500 {
1501 DBG (DBG_ERR, "start_scan: failed to bind address (%s)\n",
1502 strerror (errno));
1503 reply->status = SANE_STATUS_IO_ERROR;
1504 return -1;
1505 }
1506
1507 if (listen (fd, 1) < 0)
1508 {
1509 DBG (DBG_ERR, "start_scan: failed to make socket listen (%s)\n",
1510 strerror (errno));
1511 reply->status = SANE_STATUS_IO_ERROR;
1512 return -1;
1513 }
1514
1515 if (getsockname (fd, &data_addr.sa, (socklen_t *) &len) < 0)
1516 {
1517 DBG (DBG_ERR, "start_scan: failed to obtain socket address (%s)\n",
1518 strerror (errno));
1519 reply->status = SANE_STATUS_IO_ERROR;
1520 return -1;
1521 }
1522
1523 switch (SS_FAMILY(data_addr.ss))
1524 {
1525 case AF_INET:
1526 sin = &data_addr.sin;
1527 reply->port = ntohs (sin->sin_port);
1528 break;
1529 #ifdef ENABLE_IPV6
1530 case AF_INET6:
1531 sin6 = &data_addr.sin6;
1532 reply->port = ntohs (sin6->sin6_port);
1533 break;
1534 #endif /* ENABLE_IPV6 */
1535 default:
1536 break;
1537 }
1538
1539 DBG (DBG_MSG, "start_scan: using port %d for data\n", reply->port);
1540
1541 reply->status = sane_start (be_handle);
1542 if (reply->status == SANE_STATUS_GOOD)
1543 {
1544 handle[h].scanning = 1;
1545 handle[h].docancel = 0;
1546 }
1547
1548 return fd;
1549 }
1550
1551 #else /* !SANED_USES_AF_INDEP */
1552
1553 static int
start_scan(Wire * w,int h,SANE_Start_Reply * reply)1554 start_scan (Wire * w, int h, SANE_Start_Reply * reply)
1555 {
1556 struct sockaddr_in sin;
1557 SANE_Handle be_handle;
1558 int fd, len;
1559 in_port_t data_port;
1560 int ret;
1561
1562 be_handle = handle[h].handle;
1563
1564 len = sizeof (sin);
1565 if (getsockname (w->io.fd, (struct sockaddr *) &sin, (socklen_t *) &len) < 0)
1566 {
1567 DBG (DBG_ERR, "start_scan: failed to obtain socket address (%s)\n",
1568 strerror (errno));
1569 reply->status = SANE_STATUS_IO_ERROR;
1570 return -1;
1571 }
1572
1573 fd = socket (AF_INET, SOCK_STREAM, 0);
1574 if (fd < 0)
1575 {
1576 DBG (DBG_ERR, "start_scan: failed to obtain data socket (%s)\n",
1577 strerror (errno));
1578 reply->status = SANE_STATUS_IO_ERROR;
1579 return -1;
1580 }
1581
1582 /* Try to bind a port between data_port_lo and data_port_hi for the data connection */
1583 for (data_port = data_port_lo; data_port <= data_port_hi; data_port++)
1584 {
1585 sin.sin_port = htons(data_port);
1586
1587 DBG(DBG_INFO, "start_scan: trying to bind data port %d\n", data_port);
1588
1589 ret = bind (fd, (struct sockaddr *) &sin, len);
1590 if (ret == 0)
1591 break;
1592 }
1593
1594 if (ret < 0)
1595 {
1596 DBG (DBG_ERR, "start_scan: failed to bind address (%s)\n",
1597 strerror (errno));
1598 reply->status = SANE_STATUS_IO_ERROR;
1599 return -1;
1600 }
1601
1602 if (listen (fd, 1) < 0)
1603 {
1604 DBG (DBG_ERR, "start_scan: failed to make socket listen (%s)\n",
1605 strerror (errno));
1606 reply->status = SANE_STATUS_IO_ERROR;
1607 return -1;
1608 }
1609
1610 if (getsockname (fd, (struct sockaddr *) &sin, (socklen_t *) &len) < 0)
1611 {
1612 DBG (DBG_ERR, "start_scan: failed to obtain socket address (%s)\n",
1613 strerror (errno));
1614 reply->status = SANE_STATUS_IO_ERROR;
1615 return -1;
1616 }
1617
1618 reply->port = ntohs (sin.sin_port);
1619
1620 DBG (DBG_MSG, "start_scan: using port %d for data\n", reply->port);
1621
1622 reply->status = sane_start (be_handle);
1623 if (reply->status == SANE_STATUS_GOOD)
1624 {
1625 handle[h].scanning = 1;
1626 handle[h].docancel = 0;
1627 }
1628
1629 return fd;
1630 }
1631 #endif /* SANED_USES_AF_INDEP */
1632
1633 static int
store_reclen(SANE_Byte * buf,size_t buf_size,int i,size_t reclen)1634 store_reclen (SANE_Byte * buf, size_t buf_size, int i, size_t reclen)
1635 {
1636 buf[i++] = (reclen >> 24) & 0xff;
1637 if (i >= (int) buf_size)
1638 i = 0;
1639 buf[i++] = (reclen >> 16) & 0xff;
1640 if (i >= (int) buf_size)
1641 i = 0;
1642 buf[i++] = (reclen >> 8) & 0xff;
1643 if (i >= (int) buf_size)
1644 i = 0;
1645 buf[i++] = (reclen >> 0) & 0xff;
1646 if (i >= (int) buf_size)
1647 i = 0;
1648 return i;
1649 }
1650
1651 static void
do_scan(Wire * w,int h,int data_fd)1652 do_scan (Wire * w, int h, int data_fd)
1653 {
1654 int num_fds, be_fd = -1, reader, writer, bytes_in_buf, status_dirty = 0;
1655 SANE_Handle be_handle = handle[h].handle;
1656 struct timeval tv, *timeout = 0;
1657 fd_set rd_set, rd_mask, wr_set, wr_mask;
1658 SANE_Byte buf[8192];
1659 SANE_Status status;
1660 long int nwritten;
1661 SANE_Int length;
1662 size_t nbytes;
1663
1664 DBG (3, "do_scan: start\n");
1665
1666 FD_ZERO (&rd_mask);
1667 FD_SET (w->io.fd, &rd_mask);
1668 num_fds = w->io.fd + 1;
1669
1670 FD_ZERO (&wr_mask);
1671 FD_SET (data_fd, &wr_mask);
1672 if (data_fd >= num_fds)
1673 num_fds = data_fd + 1;
1674
1675 sane_set_io_mode (be_handle, SANE_TRUE);
1676 if (sane_get_select_fd (be_handle, &be_fd) == SANE_STATUS_GOOD)
1677 {
1678 FD_SET (be_fd, &rd_mask);
1679 if (be_fd >= num_fds)
1680 num_fds = be_fd + 1;
1681 }
1682 else
1683 {
1684 memset (&tv, 0, sizeof (tv));
1685 timeout = &tv;
1686 }
1687
1688 status = SANE_STATUS_GOOD;
1689 reader = writer = bytes_in_buf = 0;
1690 do
1691 {
1692 rd_set = rd_mask;
1693 wr_set = wr_mask;
1694 if (select (num_fds, &rd_set, &wr_set, 0, timeout) < 0)
1695 {
1696 if (be_fd >= 0 && errno == EBADF)
1697 {
1698 /* This normally happens when a backend closes a select
1699 filedescriptor when reaching the end of file. So
1700 pass back this status to the client: */
1701 FD_CLR (be_fd, &rd_mask);
1702 be_fd = -1;
1703 /* only set status_dirty if EOF hasn't been already detected */
1704 if (status == SANE_STATUS_GOOD)
1705 status_dirty = 1;
1706 status = SANE_STATUS_EOF;
1707 DBG (DBG_INFO, "do_scan: select_fd was closed --> EOF\n");
1708 continue;
1709 }
1710 else
1711 {
1712 status = SANE_STATUS_IO_ERROR;
1713 DBG (DBG_ERR, "do_scan: select failed (%s)\n", strerror (errno));
1714 break;
1715 }
1716 }
1717
1718 if (bytes_in_buf)
1719 {
1720 if (FD_ISSET (data_fd, &wr_set))
1721 {
1722 if (bytes_in_buf > 0)
1723 {
1724 /* write more input data */
1725 nbytes = bytes_in_buf;
1726 if (writer + nbytes > sizeof (buf))
1727 nbytes = sizeof (buf) - writer;
1728 DBG (DBG_INFO,
1729 "do_scan: trying to write %d bytes to client\n",
1730 nbytes);
1731 nwritten = write (data_fd, buf + writer, nbytes);
1732 DBG (DBG_INFO,
1733 "do_scan: wrote %ld bytes to client\n", nwritten);
1734 if (nwritten < 0)
1735 {
1736 DBG (DBG_ERR, "do_scan: write failed (%s)\n",
1737 strerror (errno));
1738 status = SANE_STATUS_CANCELLED;
1739 handle[h].docancel = 1;
1740 break;
1741 }
1742 bytes_in_buf -= nwritten;
1743 writer += nwritten;
1744 if (writer == sizeof (buf))
1745 writer = 0;
1746 }
1747 }
1748 }
1749 else if (status == SANE_STATUS_GOOD
1750 && (timeout || FD_ISSET (be_fd, &rd_set)))
1751 {
1752 int i;
1753
1754 /* get more input data */
1755
1756 /* reserve 4 bytes to store the length of the data record: */
1757 i = reader;
1758 reader += 4;
1759 if (reader >= (int) sizeof (buf))
1760 reader -= sizeof(buf);
1761
1762 assert (bytes_in_buf == 0);
1763 nbytes = sizeof (buf) - 4;
1764 if (reader + nbytes > sizeof (buf))
1765 nbytes = sizeof (buf) - reader;
1766
1767 DBG (DBG_INFO,
1768 "do_scan: trying to read %d bytes from scanner\n", nbytes);
1769 status = sane_read (be_handle, buf + reader, nbytes, &length);
1770 DBG (DBG_INFO,
1771 "do_scan: read %d bytes from scanner\n", length);
1772
1773 reset_watchdog ();
1774
1775 reader += length;
1776 if (reader >= (int) sizeof (buf))
1777 reader = 0;
1778 bytes_in_buf += length + 4;
1779
1780 if (status != SANE_STATUS_GOOD)
1781 {
1782 reader = i; /* restore reader index */
1783 status_dirty = 1;
1784 DBG (DBG_MSG,
1785 "do_scan: status = `%s'\n", sane_strstatus(status));
1786 }
1787 else
1788 store_reclen (buf, sizeof (buf), i, length);
1789 }
1790
1791 if (status_dirty && sizeof (buf) - bytes_in_buf >= 5)
1792 {
1793 status_dirty = 0;
1794 reader = store_reclen (buf, sizeof (buf), reader, 0xffffffff);
1795 buf[reader] = status;
1796 bytes_in_buf += 5;
1797 DBG (DBG_MSG, "do_scan: statuscode `%s' was added to buffer\n",
1798 sane_strstatus(status));
1799 }
1800
1801 if (FD_ISSET (w->io.fd, &rd_set))
1802 {
1803 DBG (DBG_MSG,
1804 "do_scan: processing RPC request on fd %d\n", w->io.fd);
1805 if(process_request (w) < 0)
1806 handle[h].docancel = 1;
1807
1808 if (handle[h].docancel)
1809 break;
1810 }
1811 }
1812 while (status == SANE_STATUS_GOOD || bytes_in_buf > 0 || status_dirty);
1813 DBG (DBG_MSG, "do_scan: done, status=%s\n", sane_strstatus (status));
1814
1815 if(handle[h].docancel)
1816 sane_cancel (handle[h].handle);
1817
1818 handle[h].docancel = 0;
1819 handle[h].scanning = 0;
1820 }
1821
1822 static int
process_request(Wire * w)1823 process_request (Wire * w)
1824 {
1825 SANE_Handle be_handle;
1826 SANE_Word h, word;
1827 int i;
1828
1829 DBG (DBG_DBG, "process_request: waiting for request\n");
1830 sanei_w_set_dir (w, WIRE_DECODE);
1831 sanei_w_word (w, &word); /* decode procedure number */
1832
1833 if (w->status)
1834 {
1835 DBG (DBG_ERR,
1836 "process_request: bad status %d\n", w->status);
1837 return -1;
1838 }
1839
1840 current_request = word;
1841
1842 DBG (DBG_MSG, "process_request: got request %d\n", current_request);
1843
1844 switch (current_request)
1845 {
1846 case SANE_NET_GET_DEVICES:
1847 {
1848 SANE_Get_Devices_Reply reply;
1849
1850 reply.status =
1851 sane_get_devices ((const SANE_Device ***) &reply.device_list,
1852 SANE_TRUE);
1853 sanei_w_reply (w, (WireCodecFunc) sanei_w_get_devices_reply, &reply);
1854 }
1855 break;
1856
1857 case SANE_NET_OPEN:
1858 {
1859 SANE_Open_Reply reply;
1860 SANE_Handle be_handle;
1861 SANE_String name, resource;
1862
1863 sanei_w_string (w, &name);
1864 if (w->status)
1865 {
1866 DBG (DBG_ERR,
1867 "process_request: (open) error while decoding args (%s)\n",
1868 strerror (w->status));
1869 return 1;
1870 }
1871
1872 if (!name)
1873 {
1874 DBG (DBG_ERR, "process_request: (open) device_name == NULL\n");
1875 reply.status = SANE_STATUS_INVAL;
1876 sanei_w_reply (w, (WireCodecFunc) sanei_w_open_reply, &reply);
1877 return 1;
1878 }
1879
1880 can_authorize = 1;
1881
1882 resource = strdup (name);
1883
1884 if (strlen(resource) == 0) {
1885
1886 const SANE_Device **device_list;
1887
1888 DBG(DBG_DBG, "process_request: (open) strlen(resource) == 0\n");
1889 free (resource);
1890
1891 if ((i = sane_get_devices (&device_list, SANE_TRUE)) !=
1892 SANE_STATUS_GOOD)
1893 {
1894 DBG(DBG_ERR, "process_request: (open) sane_get_devices failed\n");
1895 memset (&reply, 0, sizeof (reply));
1896 reply.status = i;
1897 sanei_w_reply (w, (WireCodecFunc) sanei_w_open_reply, &reply);
1898 break;
1899 }
1900
1901 if ((device_list == NULL) || (device_list[0] == NULL))
1902 {
1903 DBG(DBG_ERR, "process_request: (open) device_list[0] == 0\n");
1904 memset (&reply, 0, sizeof (reply));
1905 reply.status = SANE_STATUS_INVAL;
1906 sanei_w_reply (w, (WireCodecFunc) sanei_w_open_reply, &reply);
1907 break;
1908 }
1909
1910 resource = strdup (device_list[0]->name);
1911 }
1912
1913 if (strchr (resource, ':'))
1914 *(strchr (resource, ':')) = 0;
1915
1916 if (sanei_authorize (resource, "saned", auth_callback) !=
1917 SANE_STATUS_GOOD)
1918 {
1919 DBG (DBG_ERR, "process_request: access to resource `%s' denied\n",
1920 resource);
1921 free (resource);
1922 memset (&reply, 0, sizeof (reply)); /* avoid leaking bits */
1923 reply.status = SANE_STATUS_ACCESS_DENIED;
1924 }
1925 else
1926 {
1927 DBG (DBG_MSG, "process_request: access to resource `%s' granted\n",
1928 resource);
1929 free (resource);
1930 memset (&reply, 0, sizeof (reply)); /* avoid leaking bits */
1931 reply.status = sane_open (name, &be_handle);
1932 DBG (DBG_MSG, "process_request: sane_open returned: %s\n",
1933 sane_strstatus (reply.status));
1934 }
1935
1936 if (reply.status == SANE_STATUS_GOOD)
1937 {
1938 h = get_free_handle ();
1939 if (h < 0)
1940 reply.status = SANE_STATUS_NO_MEM;
1941 else
1942 {
1943 handle[h].handle = be_handle;
1944 reply.handle = h;
1945 }
1946 }
1947
1948 can_authorize = 0;
1949
1950 sanei_w_reply (w, (WireCodecFunc) sanei_w_open_reply, &reply);
1951 sanei_w_free (w, (WireCodecFunc) sanei_w_string, &name);
1952 }
1953 break;
1954
1955 case SANE_NET_CLOSE:
1956 {
1957 SANE_Word ack = 0;
1958
1959 h = decode_handle (w, "close");
1960 close_handle (h);
1961 sanei_w_reply (w, (WireCodecFunc) sanei_w_word, &ack);
1962 }
1963 break;
1964
1965 case SANE_NET_GET_OPTION_DESCRIPTORS:
1966 {
1967 SANE_Option_Descriptor_Array opt;
1968
1969 h = decode_handle (w, "get_option_descriptors");
1970 if (h < 0)
1971 return 1;
1972 be_handle = handle[h].handle;
1973 sane_control_option (be_handle, 0, SANE_ACTION_GET_VALUE,
1974 &opt.num_options, 0);
1975
1976 opt.desc = malloc (opt.num_options * sizeof (opt.desc[0]));
1977 for (i = 0; i < opt.num_options; ++i)
1978 opt.desc[i] = (SANE_Option_Descriptor *)
1979 sane_get_option_descriptor (be_handle, i);
1980
1981 sanei_w_reply (w,(WireCodecFunc) sanei_w_option_descriptor_array,
1982 &opt);
1983
1984 free (opt.desc);
1985 }
1986 break;
1987
1988 case SANE_NET_CONTROL_OPTION:
1989 {
1990 SANE_Control_Option_Req req;
1991 SANE_Control_Option_Reply reply;
1992
1993 sanei_w_control_option_req (w, &req);
1994 if (w->status || (unsigned) req.handle >= (unsigned) num_handles
1995 || !handle[req.handle].inuse)
1996 {
1997 DBG (DBG_ERR,
1998 "process_request: (control_option) "
1999 "error while decoding args h=%d (%s)\n"
2000 , req.handle, strerror (w->status));
2001 return 1;
2002 }
2003
2004 /* Addresses CVE-2017-6318 (#315576, Debian BTS #853804) */
2005 /* This is done here (rather than in sanei/sanei_wire.c where
2006 * it should be done) to minimize scope of impact and amount
2007 * of code change.
2008 */
2009 if (w->direction == WIRE_DECODE
2010 && req.value_type == SANE_TYPE_STRING
2011 && req.action == SANE_ACTION_GET_VALUE)
2012 {
2013 if (req.value)
2014 {
2015 /* FIXME: If req.value contains embedded NUL
2016 * characters, this is wrong but we do not have
2017 * access to the amount of memory allocated in
2018 * sanei/sanei_wire.c at this point.
2019 */
2020 w->allocated_memory -= (1 + strlen (req.value));
2021 free (req.value);
2022 }
2023 req.value = malloc (req.value_size);
2024 if (!req.value)
2025 {
2026 w->status = ENOMEM;
2027 DBG (DBG_ERR,
2028 "process_request: (control_option) "
2029 "h=%d (%s)\n", req.handle, strerror (w->status));
2030 return 1;
2031 }
2032 memset (req.value, 0, req.value_size);
2033 w->allocated_memory += req.value_size;
2034 }
2035
2036 can_authorize = 1;
2037
2038 memset (&reply, 0, sizeof (reply)); /* avoid leaking bits */
2039 be_handle = handle[req.handle].handle;
2040 reply.status = sane_control_option (be_handle, req.option,
2041 req.action, req.value,
2042 &reply.info);
2043 reply.value_type = req.value_type;
2044 reply.value_size = req.value_size;
2045 reply.value = req.value;
2046
2047 can_authorize = 0;
2048
2049 sanei_w_reply (w, (WireCodecFunc) sanei_w_control_option_reply,
2050 &reply);
2051 sanei_w_free (w, (WireCodecFunc) sanei_w_control_option_req, &req);
2052 }
2053 break;
2054
2055 case SANE_NET_GET_PARAMETERS:
2056 {
2057 SANE_Get_Parameters_Reply reply;
2058
2059 h = decode_handle (w, "get_parameters");
2060 if (h < 0)
2061 return 1;
2062 be_handle = handle[h].handle;
2063
2064 reply.status = sane_get_parameters (be_handle, &reply.params);
2065
2066 sanei_w_reply (w, (WireCodecFunc) sanei_w_get_parameters_reply,
2067 &reply);
2068 }
2069 break;
2070
2071 case SANE_NET_START:
2072 {
2073 SANE_Start_Reply reply;
2074 int fd = -1, data_fd = -1;
2075
2076 h = decode_handle (w, "start");
2077 if (h < 0)
2078 return 1;
2079
2080 memset (&reply, 0, sizeof (reply)); /* avoid leaking bits */
2081 reply.byte_order = SANE_NET_LITTLE_ENDIAN;
2082 if (byte_order.w != 1)
2083 reply.byte_order = SANE_NET_BIG_ENDIAN;
2084
2085 if (handle[h].scanning)
2086 reply.status = SANE_STATUS_DEVICE_BUSY;
2087 else
2088 fd = start_scan (w, h, &reply);
2089
2090 sanei_w_reply (w, (WireCodecFunc) sanei_w_start_reply, &reply);
2091
2092 #ifdef SANED_USES_AF_INDEP
2093 if (reply.status == SANE_STATUS_GOOD)
2094 {
2095 struct sockaddr_storage ss;
2096 char text_addr[64];
2097 int len;
2098 int error;
2099 struct pollfd fds[1];
2100 int ret;
2101
2102 fds->fd = fd;
2103 fds->events = POLLIN;
2104
2105 DBG (DBG_MSG, "process_request: waiting 4s for data connection\n");
2106 if(data_connect_timeout)
2107 {
2108 while (1)
2109 {
2110 ret = poll (fds, 1, data_connect_timeout);
2111 if (ret < 0)
2112 {
2113 if (errno == EINTR)
2114 continue;
2115 else
2116 {
2117 DBG (DBG_ERR, "run_standalone: poll failed: %s\n",
2118 strerror (errno));
2119 }
2120 break;
2121 }
2122 break;
2123 }
2124 }
2125 else
2126 ret = 0;
2127 if(ret >= 0)
2128 data_fd = accept (fd, 0, 0);
2129 close (fd);
2130
2131 /* Get address of remote host */
2132 len = sizeof (ss);
2133 if (getpeername (data_fd, (struct sockaddr *) &ss, (socklen_t *) &len) < 0)
2134 {
2135 DBG (DBG_ERR, "process_request: getpeername failed: %s\n",
2136 strerror (errno));
2137 return 1;
2138 }
2139
2140 error = getnameinfo ((struct sockaddr *) &ss, len, text_addr,
2141 sizeof (text_addr), NULL, 0, NI_NUMERICHOST);
2142 if (error)
2143 {
2144 DBG (DBG_ERR, "process_request: getnameinfo failed: %s\n",
2145 gai_strerror (error));
2146 return 1;
2147 }
2148
2149 DBG (DBG_MSG, "process_request: access to data port from %s\n",
2150 text_addr);
2151
2152 if (strcmp (text_addr, remote_ip) != 0)
2153 {
2154 DBG (DBG_ERR, "process_request: however, only %s is authorized\n",
2155 text_addr);
2156 DBG (DBG_ERR, "process_request: configuration problem or attack?\n");
2157 close (data_fd);
2158 data_fd = -1;
2159 return -1;
2160 }
2161
2162 #else /* !SANED_USES_AF_INDEP */
2163
2164 if (reply.status == SANE_STATUS_GOOD)
2165 {
2166 struct sockaddr_in sin;
2167 int len;
2168 int ret;
2169 struct pollfd fds[1];
2170
2171 fds->fd = fd;
2172 fds->events = POLLIN;
2173
2174 DBG (DBG_MSG, "process_request: waiting for data connection\n");
2175 if(data_connect_timeout)
2176 {
2177 while (1)
2178 {
2179 ret = poll (fds, 1, data_connect_timeout);
2180 if (ret < 0)
2181 {
2182 if (errno == EINTR)
2183 continue;
2184 else
2185 {
2186 DBG (DBG_ERR, "run_standalone: poll failed: %s\n", strerror (errno));
2187 }
2188 break;
2189 }
2190 break;
2191 }
2192 }
2193 else
2194 ret = 0;
2195 if(ret >= 0)
2196 data_fd = accept (fd, 0, 0);
2197
2198 close (fd);
2199
2200 /* Get address of remote host */
2201 len = sizeof (sin);
2202 if (getpeername (data_fd, (struct sockaddr *) &sin,
2203 (socklen_t *) &len) < 0)
2204 {
2205 DBG (DBG_ERR, "process_request: getpeername failed: %s\n",
2206 strerror (errno));
2207 return 1;
2208 }
2209
2210 if (memcmp (&remote_address, &sin.sin_addr,
2211 sizeof (remote_address)) != 0)
2212 {
2213 DBG (DBG_ERR,
2214 "process_request: access to data port from %s\n",
2215 inet_ntoa (sin.sin_addr));
2216 DBG (DBG_ERR,
2217 "process_request: however, only %s is authorized\n",
2218 inet_ntoa (remote_address));
2219 DBG (DBG_ERR,
2220 "process_request: configuration problem or attack?\n");
2221 close (data_fd);
2222 data_fd = -1;
2223 return -1;
2224 }
2225 else
2226 DBG (DBG_MSG, "process_request: access to data port from %s\n",
2227 inet_ntoa (sin.sin_addr));
2228 #endif /* SANED_USES_AF_INDEP */
2229
2230 if (data_fd < 0)
2231 {
2232 sane_cancel (handle[h].handle);
2233 handle[h].scanning = 0;
2234 handle[h].docancel = 0;
2235 DBG (DBG_ERR, "process_request: accept failed! (%s)\n",
2236 strerror (errno));
2237 return 1;
2238 }
2239 fcntl (data_fd, F_SETFL, 1); /* set non-blocking */
2240 shutdown (data_fd, 0);
2241 do_scan (w, h, data_fd);
2242 close (data_fd);
2243 }
2244 }
2245 break;
2246
2247 case SANE_NET_CANCEL:
2248 {
2249 SANE_Word ack = 0;
2250
2251 h = decode_handle (w, "cancel");
2252 if (h >= 0)
2253 {
2254 sane_cancel (handle[h].handle);
2255 handle[h].docancel = 1;
2256 }
2257 sanei_w_reply (w, (WireCodecFunc) sanei_w_word, &ack);
2258 }
2259 break;
2260
2261 case SANE_NET_EXIT:
2262 return -1;
2263 break;
2264
2265 case SANE_NET_INIT:
2266 case SANE_NET_AUTHORIZE:
2267 default:
2268 DBG (DBG_ERR,
2269 "process_request: received unexpected procedure number %d\n",
2270 current_request);
2271 return -1;
2272 }
2273
2274 return 0;
2275 }
2276
2277
2278 static int
2279 wait_child (pid_t pid, int *status, int options)
2280 {
2281 struct saned_child *c;
2282 struct saned_child *p = NULL;
2283 int ret;
2284
2285 ret = waitpid(pid, status, options);
2286
2287 if (ret <= 0)
2288 return ret;
2289
2290 #if WITH_AVAHI
2291 if ((avahi_pid > 0) && (ret == avahi_pid))
2292 {
2293 avahi_pid = -1;
2294 numchildren--;
2295 return ret;
2296 }
2297 #endif /* WITH_AVAHI */
2298
2299 for (c = children; (c != NULL) && (c->next != NULL); p = c, c = c->next)
2300 {
2301 if (c->pid == ret)
2302 {
2303 if (c == children)
2304 children = c->next;
2305 else if (p != NULL)
2306 p->next = c->next;
2307
2308 free(c);
2309
2310 numchildren--;
2311
2312 break;
2313 }
2314 }
2315
2316 return ret;
2317 }
2318
2319 static int
2320 add_child (pid_t pid)
2321 {
2322 struct saned_child *c;
2323
2324 c = (struct saned_child *) malloc (sizeof(struct saned_child));
2325
2326 if (c == NULL)
2327 {
2328 DBG (DBG_ERR, "add_child: out of memory\n");
2329 return -1;
2330 }
2331
2332 c->pid = pid;
2333 c->next = children;
2334
2335 children = c;
2336
2337 return 0;
2338 }
2339
2340
2341 static void
2342 handle_connection (int fd)
2343 {
2344 #ifdef TCP_NODELAY
2345 int on = 1;
2346 int level = -1;
2347 #endif
2348
2349 DBG (DBG_DBG, "handle_connection: processing client connection\n");
2350
2351 wire.io.fd = fd;
2352
2353 signal (SIGALRM, quit);
2354 signal (SIGPIPE, quit);
2355
2356 #ifdef TCP_NODELAY
2357 # ifdef SOL_TCP
2358 level = SOL_TCP;
2359 # else /* !SOL_TCP */
2360 /* Look up the protocol level in the protocols database. */
2361 {
2362 struct protoent *p;
2363 p = getprotobyname ("tcp");
2364 if (p == 0)
2365 {
2366 DBG (DBG_WARN, "handle_connection: cannot look up `tcp' protocol number");
2367 }
2368 else
2369 level = p->p_proto;
2370 }
2371 # endif /* SOL_TCP */
2372 if (level == -1
2373 || setsockopt (wire.io.fd, level, TCP_NODELAY, &on, sizeof (on)))
2374 DBG (DBG_WARN, "handle_connection: failed to put socket in TCP_NODELAY mode (%s)",
2375 strerror (errno));
2376 #endif /* !TCP_NODELAY */
2377
2378 if (init (&wire) < 0)
2379 return;
2380
2381 while (1)
2382 {
2383 reset_watchdog ();
2384 if (process_request (&wire) < 0)
2385 break;
2386 }
2387 }
2388
2389 static void
2390 handle_client (int fd)
2391 {
2392 pid_t pid;
2393 int i;
2394
2395 DBG (DBG_DBG, "handle_client: spawning child process\n");
2396
2397 pid = fork ();
2398 if (pid == 0)
2399 {
2400 /* child */
2401 if (log_to_syslog)
2402 closelog();
2403
2404 for (i = 3; i < fd; i++)
2405 close(i);
2406
2407 if (log_to_syslog)
2408 openlog ("saned", LOG_PID | LOG_CONS, LOG_DAEMON);
2409
2410 handle_connection (fd);
2411 quit (0);
2412 }
2413 else if (pid > 0)
2414 {
2415 /* parent */
2416 add_child (pid);
2417 close(fd);
2418 }
2419 else
2420 {
2421 /* FAILED */
2422 DBG (DBG_ERR, "handle_client: fork() failed: %s\n", strerror (errno));
2423 close(fd);
2424 }
2425 }
2426
2427 static void
2428 bail_out (int error)
2429 {
2430 DBG (DBG_ERR, "%sbailing out, waiting for children...\n", (error) ? "FATAL ERROR; " : "");
2431
2432 #if WITH_AVAHI
2433 if (avahi_pid > 0)
2434 kill (avahi_pid, SIGTERM);
2435 #endif /* WITH_AVAHI */
2436
2437 while (numchildren > 0)
2438 wait_child (-1, NULL, 0);
2439
2440 DBG (DBG_ERR, "bail_out: all children exited\n");
2441
2442 exit ((error) ? 1 : 0);
2443 }
2444
2445 void
2446 sig_int_term_handler (int signum);
2447
2448 void
2449 sig_int_term_handler (int signum)
2450 {
2451 /* unused */
2452 (void) signum;
2453
2454 signal (SIGINT, NULL);
2455 signal (SIGTERM, NULL);
2456
2457 bail_out (0);
2458 }
2459
2460
2461 #if WITH_AVAHI
2462 static void
2463 saned_avahi (struct pollfd *fds, int nfds);
2464
2465 static void
2466 saned_create_avahi_services (AvahiClient *c);
2467
2468 static void
2469 saned_avahi_callback (AvahiClient *c, AvahiClientState state, void *userdata);
2470
2471 static void
2472 saned_avahi_group_callback (AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata);
2473
2474
2475 static void
2476 saned_avahi (struct pollfd *fds, int nfds)
2477 {
2478 struct pollfd *fdp = NULL;
2479 int error;
2480
2481 avahi_pid = fork ();
2482
2483 if (avahi_pid > 0)
2484 {
2485 numchildren++;
2486 return;
2487 }
2488 else if (avahi_pid < 0)
2489 {
2490 DBG (DBG_ERR, "saned_avahi: could not spawn Avahi process: %s\n", strerror (errno));
2491 return;
2492 }
2493
2494 signal (SIGINT, NULL);
2495 signal (SIGTERM, NULL);
2496
2497 /* Close network fds */
2498 for (fdp = fds; nfds > 0; nfds--, fdp++)
2499 close (fdp->fd);
2500
2501 free(fds);
2502
2503 avahi_svc_name = avahi_strdup(SANED_NAME);
2504
2505 avahi_poll = avahi_simple_poll_new ();
2506 if (avahi_poll == NULL)
2507 {
2508 DBG (DBG_ERR, "saned_avahi: failed to create simple poll object\n");
2509 goto fail;
2510 }
2511
2512 avahi_client = avahi_client_new (avahi_simple_poll_get (avahi_poll), AVAHI_CLIENT_NO_FAIL, saned_avahi_callback, NULL, &error);
2513 if (avahi_client == NULL)
2514 {
2515 DBG (DBG_ERR, "saned_avahi: failed to create client: %s\n", avahi_strerror (error));
2516 goto fail;
2517 }
2518
2519 avahi_simple_poll_loop (avahi_poll);
2520
2521 DBG (DBG_INFO, "saned_avahi: poll loop exited\n");
2522
2523 exit(EXIT_SUCCESS);
2524
2525 /* NOT REACHED */
2526 return;
2527
2528 fail:
2529 if (avahi_client)
2530 avahi_client_free (avahi_client);
2531
2532 if (avahi_poll)
2533 avahi_simple_poll_free (avahi_poll);
2534
2535 avahi_free (avahi_svc_name);
2536
2537 exit(EXIT_FAILURE);
2538 }
2539
2540 static void
2541 saned_avahi_group_callback (AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata)
2542 {
2543 char *n;
2544
2545 /* unused */
2546 (void) userdata;
2547
2548 if ((!g) || (g != avahi_group))
2549 return;
2550
2551 switch (state)
2552 {
2553 case AVAHI_ENTRY_GROUP_ESTABLISHED:
2554 /* The entry group has been established successfully */
2555 DBG (DBG_INFO, "saned_avahi_group_callback: service '%s' successfully established\n", avahi_svc_name);
2556 break;
2557
2558 case AVAHI_ENTRY_GROUP_COLLISION:
2559 /* A service name collision with a remote service
2560 * happened. Let's pick a new name */
2561 n = avahi_alternative_service_name (avahi_svc_name);
2562 avahi_free (avahi_svc_name);
2563 avahi_svc_name = n;
2564
2565 DBG (DBG_WARN, "saned_avahi_group_callback: service name collision, renaming service to '%s'\n", avahi_svc_name);
2566
2567 /* And recreate the services */
2568 saned_create_avahi_services (avahi_entry_group_get_client (g));
2569 break;
2570
2571 case AVAHI_ENTRY_GROUP_FAILURE :
2572 DBG (DBG_ERR, "saned_avahi_group_callback: entry group failure: %s\n", avahi_strerror (avahi_client_errno (avahi_entry_group_get_client (g))));
2573
2574 /* Some kind of failure happened while we were registering our services */
2575 avahi_simple_poll_quit (avahi_poll);
2576 break;
2577
2578 case AVAHI_ENTRY_GROUP_UNCOMMITED:
2579 case AVAHI_ENTRY_GROUP_REGISTERING:
2580 break;
2581 }
2582 }
2583
2584 static void
2585 saned_create_avahi_services (AvahiClient *c)
2586 {
2587 char *n;
2588 char txt[32];
2589 AvahiProtocol proto;
2590 int ret;
2591
2592 if (!c)
2593 return;
2594
2595 if (!avahi_group)
2596 {
2597 avahi_group = avahi_entry_group_new (c, saned_avahi_group_callback, NULL);
2598 if (avahi_group == NULL)
2599 {
2600 DBG (DBG_ERR, "saned_create_avahi_services: avahi_entry_group_new() failed: %s\n", avahi_strerror (avahi_client_errno (c)));
2601 goto fail;
2602 }
2603 }
2604
2605 if (avahi_entry_group_is_empty (avahi_group))
2606 {
2607 DBG (DBG_INFO, "saned_create_avahi_services: adding service '%s'\n", avahi_svc_name);
2608
2609 snprintf(txt, sizeof (txt), "protovers=%x", SANE_VERSION_CODE (V_MAJOR, V_MINOR, SANEI_NET_PROTOCOL_VERSION));
2610
2611 #ifdef ENABLE_IPV6
2612 proto = AVAHI_PROTO_UNSPEC;
2613 #else
2614 proto = AVAHI_PROTO_INET;
2615 #endif /* ENABLE_IPV6 */
2616
2617 ret = avahi_entry_group_add_service (avahi_group, AVAHI_IF_UNSPEC, proto, 0, avahi_svc_name, SANED_SERVICE_DNS, NULL, NULL, SANED_SERVICE_PORT, txt, NULL);
2618 if (ret < 0)
2619 {
2620 if (ret == AVAHI_ERR_COLLISION)
2621 {
2622 n = avahi_alternative_service_name (avahi_svc_name);
2623 avahi_free (avahi_svc_name);
2624 avahi_svc_name = n;
2625
2626 DBG (DBG_WARN, "saned_create_avahi_services: service name collision, renaming service to '%s'\n", avahi_svc_name);
2627
2628 avahi_entry_group_reset (avahi_group);
2629
2630 saned_create_avahi_services (c);
2631
2632 return;
2633 }
2634
2635 DBG (DBG_ERR, "saned_create_avahi_services: failed to add %s service: %s\n", SANED_SERVICE_DNS, avahi_strerror (ret));
2636 goto fail;
2637 }
2638
2639 /* Tell the server to register the service */
2640 ret = avahi_entry_group_commit (avahi_group);
2641 if (ret < 0)
2642 {
2643 DBG (DBG_ERR, "saned_create_avahi_services: failed to commit entry group: %s\n", avahi_strerror (ret));
2644 goto fail;
2645 }
2646 }
2647
2648 return;
2649
2650 fail:
2651 avahi_simple_poll_quit (avahi_poll);
2652 }
2653
2654 static void
2655 saned_avahi_callback (AvahiClient *c, AvahiClientState state, void *userdata)
2656 {
2657 int error;
2658
2659 /* unused */
2660 (void) userdata;
2661
2662 if (!c)
2663 return;
2664
2665 switch (state)
2666 {
2667 case AVAHI_CLIENT_CONNECTING:
2668 DBG (DBG_INFO, "saned_avahi_callback: AVAHI_CLIENT_CONNECTING\n");
2669 break;
2670
2671 case AVAHI_CLIENT_S_RUNNING:
2672 DBG (DBG_INFO, "saned_avahi_callback: AVAHI_CLIENT_S_RUNNING\n");
2673 saned_create_avahi_services (c);
2674 break;
2675
2676 case AVAHI_CLIENT_S_COLLISION:
2677 DBG (DBG_INFO, "saned_avahi_callback: AVAHI_CLIENT_S_COLLISION\n");
2678 if (avahi_group)
2679 avahi_entry_group_reset (avahi_group);
2680 break;
2681
2682 case AVAHI_CLIENT_S_REGISTERING:
2683 DBG (DBG_INFO, "saned_avahi_callback: AVAHI_CLIENT_S_REGISTERING\n");
2684 if (avahi_group)
2685 avahi_entry_group_reset (avahi_group);
2686 break;
2687
2688 case AVAHI_CLIENT_FAILURE:
2689 DBG (DBG_INFO, "saned_avahi_callback: AVAHI_CLIENT_FAILURE\n");
2690
2691 error = avahi_client_errno (c);
2692 if (error == AVAHI_ERR_DISCONNECTED)
2693 {
2694 DBG (DBG_INFO, "saned_avahi_callback: AVAHI_ERR_DISCONNECTED\n");
2695
2696 /* Server disappeared - try to reconnect */
2697 avahi_client_free (avahi_client);
2698 avahi_client = NULL;
2699 avahi_group = NULL;
2700
2701 avahi_client = avahi_client_new (avahi_simple_poll_get (avahi_poll), AVAHI_CLIENT_NO_FAIL, saned_avahi_callback, NULL, &error);
2702 if (avahi_client == NULL)
2703 {
2704 DBG (DBG_ERR, "saned_avahi_callback: failed to create client: %s\n", avahi_strerror (error));
2705 avahi_simple_poll_quit (avahi_poll);
2706 }
2707 }
2708 else
2709 {
2710 /* Another error happened - game over */
2711 DBG (DBG_ERR, "saned_avahi_callback: client failure: %s\n", avahi_strerror (error));
2712 avahi_simple_poll_quit (avahi_poll);
2713 }
2714 break;
2715 }
2716 }
2717 #endif /* WITH_AVAHI */
2718
2719
2720 static void
2721 read_config (void)
2722 {
2723 char config_line[PATH_MAX];
2724 const char *optval;
2725 char *endval;
2726 long val;
2727 FILE *fp;
2728 int len;
2729
2730 DBG (DBG_INFO, "read_config: searching for config file\n");
2731 fp = sanei_config_open (SANED_CONFIG_FILE);
2732 if (fp)
2733 {
2734 while (sanei_config_read (config_line, sizeof (config_line), fp))
2735 {
2736 if (config_line[0] == '#')
2737 continue; /* ignore line comments */
2738
2739 optval = strchr (config_line, '=');
2740 if (optval == NULL)
2741 continue; /* only interested in options, skip hosts */
2742
2743 len = strlen (config_line);
2744 if (!len)
2745 continue; /* ignore empty lines */
2746
2747 /*
2748 * Check for saned options.
2749 * Anything that isn't an option is a client.
2750 */
2751 if (strstr(config_line, "data_portrange") != NULL)
2752 {
2753 optval = sanei_config_skip_whitespace (++optval);
2754 if ((optval != NULL) && (*optval != '\0'))
2755 {
2756 val = strtol (optval, &endval, 10);
2757 if (optval == endval)
2758 {
2759 DBG (DBG_ERR, "read_config: invalid value for data_portrange\n");
2760 continue;
2761 }
2762 else if ((val < 0) || (val > 65535))
2763 {
2764 DBG (DBG_ERR, "read_config: data_portrange start port is invalid\n");
2765 continue;
2766 }
2767
2768 optval = strchr (endval, '-');
2769 if (optval == NULL)
2770 {
2771 DBG (DBG_ERR, "read_config: no end port value for data_portrange\n");
2772 continue;
2773 }
2774
2775 optval = sanei_config_skip_whitespace (++optval);
2776
2777 data_port_lo = val;
2778
2779 val = strtol (optval, &endval, 10);
2780 if (optval == endval)
2781 {
2782 DBG (DBG_ERR, "read_config: invalid value for data_portrange\n");
2783 data_port_lo = 0;
2784 continue;
2785 }
2786 else if ((val < 0) || (val > 65535))
2787 {
2788 DBG (DBG_ERR, "read_config: data_portrange end port is invalid\n");
2789 data_port_lo = 0;
2790 continue;
2791 }
2792 else if (val < data_port_lo)
2793 {
2794 DBG (DBG_ERR, "read_config: data_portrange end port is less than start port\n");
2795 data_port_lo = 0;
2796 continue;
2797 }
2798
2799 data_port_hi = val;
2800
2801 DBG (DBG_INFO, "read_config: data port range: %d - %d\n", data_port_lo, data_port_hi);
2802 }
2803 }
2804 else if(strstr(config_line, "data_connect_timeout") != NULL)
2805 {
2806 optval = sanei_config_skip_whitespace (++optval);
2807 if ((optval != NULL) && (*optval != '\0'))
2808 {
2809 val = strtol (optval, &endval, 10);
2810 if (optval == endval)
2811 {
2812 DBG (DBG_ERR, "read_config: invalid value for data_connect_timeout\n");
2813 continue;
2814 }
2815 else if ((val < 0) || (val > 65535))
2816 {
2817 DBG (DBG_ERR, "read_config: data_connect_timeout is invalid\n");
2818 continue;
2819 }
2820 data_connect_timeout = val;
2821 DBG (DBG_INFO, "read_config: data connect timeout: %d\n", data_connect_timeout);
2822 }
2823 }
2824 }
2825 fclose (fp);
2826 DBG (DBG_INFO, "read_config: done reading config\n");
2827 }
2828 else
2829 DBG (DBG_ERR, "read_config: could not open config file (%s): %s\n",
2830 SANED_CONFIG_FILE, strerror (errno));
2831 }
2832
2833
2834 #ifdef SANED_USES_AF_INDEP
2835 static void
2836 do_bindings_family (int family, int *nfds, struct pollfd **fds, struct addrinfo *res)
2837 {
2838 struct addrinfo *resp;
2839 struct pollfd *fdp;
2840 short sane_port;
2841 int fd = -1;
2842 int on = 1;
2843 int i;
2844
2845 sane_port = bind_port;
2846 fdp = *fds;
2847
2848 for (resp = res, i = 0; resp != NULL; resp = resp->ai_next, i++)
2849 {
2850 /* We're not interested */
2851 if (resp->ai_family != family)
2852 continue;
2853
2854 if (resp->ai_family == AF_INET)
2855 {
2856 if (sane_port != -1)
2857 ((struct sockaddr_in *) resp->ai_addr)->sin_port = htons(sane_port);
2858 else
2859 sane_port = ntohs(((struct sockaddr_in *) resp->ai_addr)->sin_port);
2860 }
2861 #ifdef ENABLE_IPV6
2862 else if (resp->ai_family == AF_INET6)
2863 {
2864 if (sane_port != -1)
2865 ((struct sockaddr_in6 *) resp->ai_addr)->sin6_port = htons(sane_port);
2866 else
2867 sane_port = ntohs (((struct sockaddr_in6 *) resp->ai_addr)->sin6_port);
2868 }
2869 #endif /* ENABLE_IPV6 */
2870 else
2871 continue;
2872
2873 DBG (DBG_DBG, "do_bindings: [%d] socket () using IPv%d\n", i, (family == AF_INET) ? 4 : 6);
2874 if ((fd = socket (resp->ai_family, SOCK_STREAM, 0)) < 0)
2875 {
2876 DBG (DBG_ERR, "do_bindings: [%d] socket failed: %s\n", i, strerror (errno));
2877
2878 continue;
2879 }
2880
2881 DBG (DBG_DBG, "do_bindings: [%d] setsockopt ()\n", i);
2882 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)))
2883 DBG (DBG_ERR, "do_bindings: [%d] failed to put socket in SO_REUSEADDR mode (%s)\n", i, strerror (errno));
2884
2885
2886 DBG (DBG_DBG, "do_bindings: [%d] bind () to port %d\n", i, sane_port);
2887 if (bind (fd, resp->ai_addr, resp->ai_addrlen) < 0)
2888 {
2889 /*
2890 * Binding a socket may fail with EADDRINUSE if we already bound
2891 * to an IPv6 addr returned by getaddrinfo (usually the first ones)
2892 * and we're trying to bind to an IPv4 addr now.
2893 * It can also fail because we're trying to bind an IPv6 socket and IPv6
2894 * is not functional on this machine.
2895 * In any case, a bind() call returning an error is not necessarily fatal.
2896 */
2897 DBG (DBG_WARN, "do_bindings: [%d] bind failed: %s\n", i, strerror (errno));
2898
2899 close (fd);
2900
2901 continue;
2902 }
2903
2904 DBG (DBG_DBG, "do_bindings: [%d] listen ()\n", i);
2905 if (listen (fd, 1) < 0)
2906 {
2907 DBG (DBG_ERR, "do_bindings: [%d] listen failed: %s\n", i, strerror (errno));
2908
2909 close (fd);
2910
2911 continue;
2912 }
2913
2914 if (sane_port == 0)
2915 {
2916 /* sane was asked to bind to an ephemeral port, log it */
2917 socklen_t len = sizeof (*resp->ai_addr);
2918 if (getsockname(fd, resp->ai_addr, &len) != -1)
2919 {
2920 if (resp->ai_family == AF_INET)
2921 {
2922 DBG (DBG_INFO, "do_bindings: [%d] selected ephemeral port: %d\n", i, ntohs(((struct sockaddr_in *) resp->ai_addr)->sin_port));
2923 }
2924
2925 #ifdef ENABLE_IPV6
2926 if (resp->ai_family == AF_INET6)
2927 {
2928 DBG (DBG_INFO, "do_bindings: [%d] selected ephemeral port: %d\n", i, ntohs(((struct sockaddr_in6 *) resp->ai_addr)->sin6_port));
2929 }
2930
2931 #endif /* ENABLE_IPV6 */
2932
2933 }
2934 }
2935
2936 fdp->fd = fd;
2937 fdp->events = POLLIN;
2938
2939 (*nfds)++;
2940 fdp++;
2941 }
2942
2943 *fds = fdp;
2944 }
2945
2946 static void
2947 do_bindings (int *nfds, struct pollfd **fds)
2948 {
2949 struct addrinfo *res;
2950 struct addrinfo *resp;
2951 struct addrinfo hints;
2952 struct pollfd *fdp;
2953 int err;
2954
2955 DBG (DBG_DBG, "do_bindings: trying to get port for service \"%s\" (getaddrinfo)\n", SANED_SERVICE_NAME);
2956
2957 memset (&hints, 0, sizeof (struct addrinfo));
2958
2959 hints.ai_family = PF_UNSPEC;
2960 hints.ai_flags = AI_PASSIVE;
2961 hints.ai_socktype = SOCK_STREAM;
2962
2963 err = getaddrinfo (bind_addr, SANED_SERVICE_NAME, &hints, &res);
2964 if (err)
2965 {
2966 DBG (DBG_WARN, "do_bindings: \" %s \" service unknown on your host; you should add\n", SANED_SERVICE_NAME);
2967 DBG (DBG_WARN, "do_bindings: %s %d/tcp saned # SANE network scanner daemon\n", SANED_SERVICE_NAME, SANED_SERVICE_PORT);
2968 DBG (DBG_WARN, "do_bindings: to your /etc/services file (or equivalent). Proceeding anyway.\n");
2969 err = getaddrinfo (bind_addr, SANED_SERVICE_PORT_S, &hints, &res);
2970 if (err)
2971 {
2972 DBG (DBG_ERR, "do_bindings: getaddrinfo() failed even with numeric port: %s\n", gai_strerror (err));
2973 bail_out (1);
2974 }
2975 }
2976
2977 for (resp = res, *nfds = 0; resp != NULL; resp = resp->ai_next, (*nfds)++)
2978 ;
2979
2980 *fds = malloc (*nfds * sizeof (struct pollfd));
2981
2982 if (fds == NULL)
2983 {
2984 DBG (DBG_ERR, "do_bindings: not enough memory for fds\n");
2985 freeaddrinfo (res);
2986 bail_out (1);
2987 }
2988
2989 fdp = *fds;
2990 *nfds = 0;
2991
2992 /* bind IPv6 first, IPv4 second */
2993 #ifdef ENABLE_IPV6
2994 do_bindings_family (AF_INET6, nfds, &fdp, res);
2995 #endif
2996 do_bindings_family (AF_INET, nfds, &fdp, res);
2997
2998 resp = NULL;
2999 freeaddrinfo (res);
3000
3001 if (*nfds <= 0)
3002 {
3003 DBG (DBG_ERR, "do_bindings: couldn't bind an address. Exiting.\n");
3004 bail_out (1);
3005 }
3006 }
3007
3008 #else /* !SANED_USES_AF_INDEP */
3009
3010 static void
3011 do_bindings (int *nfds, struct pollfd **fds)
3012 {
3013 struct sockaddr_in sin;
3014 struct servent *serv;
3015 short port;
3016 int fd = -1;
3017 int on = 1;
3018
3019 DBG (DBG_DBG, "do_bindings: trying to get port for service \"%s\" (getservbyname)\n", SANED_SERVICE_NAME);
3020 serv = getservbyname (SANED_SERVICE_NAME, "tcp");
3021
3022 if (serv)
3023 {
3024 port = serv->s_port;
3025 DBG (DBG_MSG, "do_bindings: port is %d\n", ntohs (port));
3026 }
3027 else
3028 {
3029 port = htons (SANED_SERVICE_PORT);
3030 DBG (DBG_WARN, "do_bindings: \"%s\" service unknown on your host; you should add\n", SANED_SERVICE_NAME);
3031 DBG (DBG_WARN, "do_bindings: %s %d/tcp saned # SANE network scanner daemon\n", SANED_SERVICE_NAME, SANED_SERVICE_PORT);
3032 DBG (DBG_WARN, "do_bindings: to your /etc/services file (or equivalent). Proceeding anyway.\n");
3033 }
3034
3035 *nfds = 1;
3036 *fds = malloc (*nfds * sizeof (struct pollfd));
3037
3038 if (fds == NULL)
3039 {
3040 DBG (DBG_ERR, "do_bindings: not enough memory for fds\n");
3041 bail_out (1);
3042 }
3043
3044 memset (&sin, 0, sizeof (sin));
3045
3046 sin.sin_family = AF_INET;
3047 if(bind_addr)
3048 sin.sin_addr.s_addr = inet_addr(bind_addr);
3049 else
3050 sin.sin_addr.s_addr = INADDR_ANY;
3051 sin.sin_port = port;
3052
3053 DBG (DBG_DBG, "do_bindings: socket ()\n");
3054 fd = socket (AF_INET, SOCK_STREAM, 0);
3055
3056 DBG (DBG_DBG, "do_bindings: setsockopt ()\n");
3057 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)))
3058 DBG (DBG_ERR, "do_bindings: failed to put socket in SO_REUSEADDR mode (%s)", strerror (errno));
3059
3060 DBG (DBG_DBG, "do_bindings: bind ()\n");
3061 if (bind (fd, (struct sockaddr *) &sin, sizeof (sin)) < 0)
3062 {
3063 DBG (DBG_ERR, "do_bindings: bind failed: %s", strerror (errno));
3064 bail_out (1);
3065 }
3066
3067 DBG (DBG_DBG, "do_bindings: listen ()\n");
3068 if (listen (fd, 1) < 0)
3069 {
3070 DBG (DBG_ERR, "do_bindings: listen failed: %s", strerror (errno));
3071 bail_out (1);
3072 }
3073
3074 (*fds)->fd = fd;
3075 (*fds)->events = POLLIN;
3076 }
3077
3078 #endif /* SANED_USES_AF_INDEP */
3079
3080
3081 static void
3082 runas_user (char *user)
3083 {
3084 uid_t runas_uid = 0;
3085 gid_t runas_gid = 0;
3086 struct passwd *pwent;
3087 gid_t *grplist = NULL;
3088 struct group *grp;
3089 int ngroups = 0;
3090 int ret;
3091
3092 pwent = getpwnam(user);
3093
3094 if (pwent == NULL)
3095 {
3096 DBG (DBG_ERR, "FATAL ERROR: user %s not found on system\n", user);
3097 bail_out (1);
3098 }
3099
3100 runas_uid = pwent->pw_uid;
3101 runas_gid = pwent->pw_gid;
3102
3103 /* Get group list for runas_uid */
3104 grplist = (gid_t *)malloc(sizeof(gid_t));
3105
3106 if (grplist == NULL)
3107 {
3108 DBG (DBG_ERR, "FATAL ERROR: cannot allocate memory for group list\n");
3109
3110 exit (1);
3111 }
3112
3113 ngroups = 1;
3114 grplist[0] = runas_gid;
3115
3116 setgrent();
3117 while ((grp = getgrent()) != NULL)
3118 {
3119 int i = 0;
3120
3121 /* Already added current group */
3122 if (grp->gr_gid == runas_gid)
3123 continue;
3124
3125 while (grp->gr_mem[i])
3126 {
3127 if (strcmp(grp->gr_mem[i], user) == 0)
3128 {
3129 int need_to_add = 1, j;
3130
3131 /* Make sure its not already in list */
3132 for (j = 0; j < ngroups; j++)
3133 {
3134 if (grp->gr_gid == grplist[i])
3135 need_to_add = 0;
3136 }
3137 if (need_to_add)
3138 {
3139 grplist = (gid_t *)realloc(grplist,
3140 sizeof(gid_t)*ngroups+1);
3141 if (grplist == NULL)
3142 {
3143 DBG (DBG_ERR, "FATAL ERROR: cannot reallocate memory for group list\n");
3144
3145 exit (1);
3146 }
3147 grplist[ngroups++] = grp->gr_gid;
3148 }
3149 }
3150 i++;
3151 }
3152 }
3153 endgrent();
3154
3155 /* Drop privileges if requested */
3156 if (runas_uid > 0)
3157 {
3158 ret = setgroups(ngroups, grplist);
3159 if (ret < 0)
3160 {
3161 DBG (DBG_ERR, "FATAL ERROR: could not set group list: %s\n", strerror(errno));
3162
3163 exit (1);
3164 }
3165
3166 free(grplist);
3167
3168 ret = setegid (runas_gid);
3169 if (ret < 0)
3170 {
3171 DBG (DBG_ERR, "FATAL ERROR: setegid to gid %d failed: %s\n", runas_gid, strerror (errno));
3172
3173 exit (1);
3174 }
3175
3176 ret = seteuid (runas_uid);
3177 if (ret < 0)
3178 {
3179 DBG (DBG_ERR, "FATAL ERROR: seteuid to uid %d failed: %s\n", runas_uid, strerror (errno));
3180
3181 exit (1);
3182 }
3183
3184 DBG (DBG_WARN, "Dropped privileges to uid %d gid %d\n", runas_uid, runas_gid);
3185 }
3186 }
3187
3188
3189 static void
3190 run_standalone (char *user)
3191 {
3192 struct pollfd *fds = NULL;
3193 struct pollfd *fdp = NULL;
3194 int nfds;
3195 int fd = -1;
3196 int i;
3197 int ret;
3198
3199 FILE *pidfile;
3200
3201 do_bindings (&nfds, &fds);
3202
3203 if (run_foreground == SANE_FALSE)
3204 {
3205 DBG (DBG_MSG, "run_standalone: daemonizing now\n");
3206
3207 fd = open ("/dev/null", O_RDWR);
3208 if (fd < 0)
3209 {
3210 DBG (DBG_ERR, "FATAL ERROR: cannot open /dev/null: %s\n", strerror (errno));
3211 exit (1);
3212 }
3213
3214 ret = fork ();
3215 if (ret > 0)
3216 {
3217 _exit (0);
3218 }
3219 else if (ret < 0)
3220 {
3221 DBG (DBG_ERR, "FATAL ERROR: fork failed: %s\n", strerror (errno));
3222 exit (1);
3223 }
3224
3225 DBG (DBG_WARN, "Now daemonized\n");
3226
3227 /* Write out PID file */
3228 pidfile = fopen (SANED_PID_FILE, "w");
3229 if (pidfile)
3230 {
3231 fprintf (pidfile, "%d", getpid());
3232 fclose (pidfile);
3233 }
3234 else
3235 DBG (DBG_ERR, "Could not write PID file: %s\n", strerror (errno));
3236
3237 chdir ("/");
3238
3239 dup2 (fd, STDIN_FILENO);
3240 dup2 (fd, STDOUT_FILENO);
3241 dup2 (fd, STDERR_FILENO);
3242
3243 close (fd);
3244
3245 setsid ();
3246
3247 signal(SIGINT, sig_int_term_handler);
3248 signal(SIGTERM, sig_int_term_handler);
3249 }
3250
3251 if (user)
3252 runas_user(user);
3253
3254 #if WITH_AVAHI
3255 DBG (DBG_INFO, "run_standalone: spawning Avahi process\n");
3256 saned_avahi (fds, nfds);
3257
3258 /* NOT REACHED (Avahi process) */
3259 #endif /* WITH_AVAHI */
3260
3261 DBG (DBG_MSG, "run_standalone: waiting for control connection\n");
3262
3263 while (1)
3264 {
3265 ret = poll (fds, nfds, 500);
3266 if (ret < 0)
3267 {
3268 if (errno == EINTR)
3269 continue;
3270 else
3271 {
3272 DBG (DBG_ERR, "run_standalone: poll failed: %s\n", strerror (errno));
3273 free (fds);
3274 bail_out (1);
3275 }
3276 }
3277
3278 /* Wait for children */
3279 while (wait_child (-1, NULL, WNOHANG) > 0)
3280 ;
3281
3282 if (ret == 0)
3283 continue;
3284
3285 for (i = 0, fdp = fds; i < nfds; i++, fdp++)
3286 {
3287 /* Error on an fd */
3288 if (fdp->revents & (POLLERR | POLLHUP | POLLNVAL))
3289 {
3290 for (i = 0, fdp = fds; i < nfds; i++, fdp++)
3291 close (fdp->fd);
3292
3293 free (fds);
3294
3295 DBG (DBG_WARN, "run_standalone: invalid fd in set, attempting to re-bind\n");
3296
3297 /* Reopen sockets */
3298 do_bindings (&nfds, &fds);
3299
3300 break;
3301 }
3302 else if (! (fdp->revents & POLLIN))
3303 continue;
3304
3305 fd = accept (fdp->fd, 0, 0);
3306 if (fd < 0)
3307 {
3308 DBG (DBG_ERR, "run_standalone: accept failed: %s", strerror (errno));
3309 continue;
3310 }
3311
3312 handle_client (fd);
3313
3314 if (run_once == SANE_TRUE)
3315 break; /* We have handled the only connection we're going to handle */
3316 }
3317
3318 if (run_once == SANE_TRUE)
3319 break;
3320 }
3321
3322 for (i = 0, fdp = fds; i < nfds; i++, fdp++)
3323 close (fdp->fd);
3324
3325 free (fds);
3326 }
3327
3328
3329 static void
3330 run_inetd (char __sane_unused__ *sock)
3331 {
3332
3333 int fd = -1;
3334
3335 #ifdef HAVE_SYSTEMD
3336 int n;
3337
3338 n = sd_listen_fds(0);
3339
3340 if (n > 1)
3341 {
3342 DBG (DBG_ERR, "run_inetd: Too many file descriptors (sockets) received from systemd!\n");
3343 return;
3344 }
3345
3346 if (n == 1)
3347 {
3348 fd = SD_LISTEN_FDS_START + 0;
3349 DBG (DBG_INFO, "run_inetd: Using systemd socket %d!\n", fd);
3350 }
3351 #endif
3352
3353 if (fd == -1)
3354 {
3355 int dave_null;
3356
3357 /* Some backends really can't keep their dirty fingers off
3358 * stdin/stdout/stderr; we work around them here so they don't
3359 * mess up the network dialog and crash the remote net backend
3360 * by messing with the inetd socket.
3361 * For systemd this not an issue as systemd uses fd >= 3 for the
3362 * socket and can even redirect stdout and stderr to syslog.
3363 * We can even use this to get the debug logging
3364 */
3365 do
3366 {
3367 /* get new fd for the inetd socket */
3368 fd = dup (1);
3369
3370 if (fd == -1)
3371 {
3372 DBG (DBG_ERR, "run_inetd: duplicating fd failed: %s", strerror (errno));
3373 return;
3374 }
3375 }
3376 while (fd < 3);
3377
3378 /* Our good'ole friend Dave Null to the rescue */
3379 dave_null = open ("/dev/null", O_RDWR);
3380 if (dave_null < 0)
3381 {
3382 DBG (DBG_ERR, "run_inetd: could not open /dev/null: %s", strerror (errno));
3383 return;
3384 }
3385
3386 close (STDIN_FILENO);
3387 close (STDOUT_FILENO);
3388 close (STDERR_FILENO);
3389
3390 dup2 (dave_null, STDIN_FILENO);
3391 dup2 (dave_null, STDOUT_FILENO);
3392 dup2 (dave_null, STDERR_FILENO);
3393
3394 close (dave_null);
3395 }
3396 #ifdef HAVE_OS2_H
3397 /* under OS/2, the socket handle is passed as argument on the command
3398 line; the socket handle is relative to IBM TCP/IP, so a call
3399 to impsockethandle() is required to add it to the EMX runtime */
3400 if (sock)
3401 {
3402 fd = _impsockhandle (atoi (sock), 0);
3403 if (fd == -1)
3404 perror ("impsockhandle");
3405 }
3406 #endif /* HAVE_OS2_H */
3407
3408 handle_connection(fd);
3409 }
3410
3411 static void usage(char *me, int err)
3412 {
3413 fprintf (stderr,
3414 "Usage: %s [OPTIONS]\n\n"
3415 " Options:\n\n"
3416 " -a, --alone[=user] equal to `-l -D -u user'\n"
3417 " -l, --listen run in standalone mode (listen for connection)\n"
3418 " -u, --user=user run as `user'\n"
3419 " -D, --daemonize run in background\n"
3420 " -o, --once exit after first client disconnects\n"
3421 " -d, --debug=level set debug level `level' (default is 2)\n"
3422 " -e, --stderr output to stderr\n"
3423 " -b, --bind=addr bind address `addr' (default all interfaces)\n"
3424 " -p, --port=port bind port `port` (default sane-port or 6566)\n"
3425 " -h, --help show this help message and exit\n", me);
3426
3427 exit(err);
3428 }
3429
3430 static int debug;
3431
3432 static struct option long_options[] =
3433 {
3434 /* These options set a flag. */
3435 {"help", no_argument, 0, 'h'},
3436 {"alone", optional_argument, 0, 'a'},
3437 {"listen", no_argument, 0, 'l'},
3438 {"user", required_argument, 0, 'u'},
3439 {"daemonize", no_argument, 0, 'D'},
3440 {"once", no_argument, 0, 'o'},
3441 {"debug", required_argument, 0, 'd'},
3442 {"stderr", no_argument, 0, 'e'},
3443 {"bind", required_argument, 0, 'b'},
3444 {"port", required_argument, 0, 'p'},
3445 {0, 0, 0, 0 }
3446 };
3447
3448 int
3449 main (int argc, char *argv[])
3450 {
3451 char options[64] = "";
3452 char *user = NULL;
3453 char *sock = NULL;
3454 int c;
3455 int long_index = 0;
3456
3457 debug = DBG_WARN;
3458
3459 prog_name = strrchr (argv[0], '/');
3460 if (prog_name)
3461 ++prog_name;
3462 else
3463 prog_name = argv[0];
3464
3465 numchildren = 0;
3466 run_mode = SANED_RUN_INETD;
3467 run_foreground = SANE_TRUE;
3468 run_once = SANE_FALSE;
3469
3470 while((c = getopt_long(argc, argv,"ha::lu:Dod:eb:p:", long_options, &long_index )) != -1)
3471 {
3472 switch(c) {
3473 case 'a':
3474 run_mode = SANED_RUN_ALONE;
3475 run_foreground = SANE_FALSE;
3476 if (optarg)
3477 user = optarg;
3478 break;
3479 case 'l':
3480 run_mode = SANED_RUN_ALONE;
3481 break;
3482 case 'u':
3483 user = optarg;
3484 break;
3485 case 'D':
3486 run_foreground = SANE_FALSE;
3487 break;
3488 case 'o':
3489 run_once = SANE_TRUE;
3490 break;
3491 case 'd':
3492 debug = atoi(optarg);
3493 break;
3494 case 'e':
3495 log_to_syslog = SANE_FALSE;
3496 break;
3497 case 'b':
3498 bind_addr = optarg;
3499 break;
3500 case 'p':
3501 bind_port = atoi(optarg);
3502 break;
3503 case 'h':
3504 usage(argv[0], EXIT_SUCCESS);
3505 break;
3506 default:
3507 usage(argv[0], EXIT_FAILURE);
3508 break;
3509 }
3510 }
3511
3512 if (log_to_syslog)
3513 openlog ("saned", LOG_PID | LOG_CONS, LOG_DAEMON);
3514
3515 read_config ();
3516
3517 byte_order.w = 0;
3518 byte_order.ch = 1;
3519
3520 sanei_w_init (&wire, sanei_codec_bin_init);
3521 wire.io.read = read;
3522 wire.io.write = write;
3523
3524 #ifdef SANED_USES_AF_INDEP
3525 strcat(options, "AF-indep");
3526 # ifdef ENABLE_IPV6
3527 strcat(options, "+IPv6");
3528 #endif
3529 #else
3530 strcat(options, "IPv4 only");
3531 #endif
3532 #ifdef HAVE_SYSTEMD
3533 if (sd_listen_fds(0) > 0)
3534 {
3535 strcat(options, "+systemd");
3536 }
3537 #endif
3538
3539 if (strlen(options) > 0)
3540 {
3541 DBG (DBG_WARN, "saned (%s) from %s starting up\n", options, PACKAGE_STRING);
3542 }
3543 else
3544 {
3545 DBG (DBG_WARN, "saned from %s ready\n", PACKAGE_STRING);
3546 }
3547
3548 if (run_mode == SANED_RUN_ALONE)
3549 {
3550 run_standalone(user);
3551 }
3552 else
3553 {
3554 #ifdef HAVE_OS2_H
3555 if (argc == 2)
3556 sock = argv[1];
3557 #endif
3558 run_inetd(sock);
3559 }
3560
3561 DBG (DBG_WARN, "saned exiting\n");
3562
3563 return 0;
3564 }
3565