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