2 * Emergency Access Daemon
3 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <sys/types.h>
17 #include <sys/select.h>
31 #include <t_defines.h>
37 #include "ead-crypt.h"
42 #include "libbridge_init.c"
46 #include <linux/if_packet.h>
49 #define PASSWD_FILE "/etc/passwd"
51 #ifndef DEFAULT_IFNAME
52 #define DEFAULT_IFNAME "eth0"
55 #ifndef DEFAULT_DEVNAME
56 #define DEFAULT_DEVNAME "Unknown"
60 #define PCAP_TIMEOUT 200
62 #if EAD_DEBUGLEVEL >= 1
63 #define DEBUG(n, format, ...) do { \
64 if (EAD_DEBUGLEVEL >= n) \
65 fprintf(stderr, format, ##__VA_ARGS__); \
69 #define DEBUG(n, format, ...) do {} while(0)
73 struct list_head list
;
83 static char ethmac
[6] = "\x00\x13\x37\x00\x00\x00"; /* last 3 bytes will be randomized */
84 static pcap_t
*pcap_fp
= NULL
;
85 static pcap_t
*pcap_fp_rx
= NULL
;
86 static char pktbuf_b
[PCAP_MRU
];
87 static struct ead_packet
*pktbuf
= (struct ead_packet
*)pktbuf_b
;
88 static u16_t nid
= 0xffff; /* node id */
89 static char username
[32] = "";
90 static int state
= EAD_TYPE_SET_USERNAME
;
91 static const char *passwd_file
= PASSWD_FILE
;
92 static const char password
[MAXPARAMLEN
];
93 static bool child_pending
= false;
95 static unsigned char abuf
[MAXPARAMLEN
+ 1];
96 static unsigned char pwbuf
[MAXPARAMLEN
];
97 static unsigned char saltbuf
[MAXSALTLEN
];
98 static unsigned char pw_saltbuf
[MAXSALTLEN
];
99 static struct list_head instances
;
100 static const char *dev_name
= DEFAULT_DEVNAME
;
101 static bool nonfork
= false;
102 static struct ead_instance
*instance
= NULL
;
104 static struct t_pwent tpe
= {
107 .password
.data
= pwbuf
,
109 .salt
.data
= saltbuf
,
112 struct t_confent
*tce
= NULL
;
113 static struct t_server
*ts
= NULL
;
114 static struct t_num A
, *B
= NULL
;
118 set_recv_type(pcap_t
*p
, bool rx
)
120 #ifdef PACKET_RECV_TYPE
121 struct sockaddr_ll sll
;
126 fd
= pcap_get_selectable_fd(p
);
131 mask
= 1 << PACKET_BROADCAST
;
135 ret
= setsockopt(fd
, SOL_PACKET
, PACKET_RECV_TYPE
, &mask
, sizeof(mask
));
141 ead_open_pcap(const char *ifname
, char *errbuf
, bool rx
)
145 p
= pcap_create(ifname
, errbuf
);
149 pcap_set_snaplen(p
, PCAP_MRU
);
150 pcap_set_promisc(p
, rx
);
151 pcap_set_timeout(p
, PCAP_TIMEOUT
);
152 #ifdef HAS_PROTO_EXTENSION
153 pcap_set_protocol(p
, (rx
? htons(ETH_P_IP
) : 0));
155 pcap_set_buffer_size(p
, (rx
? 10 : 1) * PCAP_MRU
);
157 set_recv_type(p
, rx
);
163 get_random_bytes(void *ptr
, int len
)
167 fd
= open("/dev/urandom", O_RDONLY
);
177 prepare_password(void)
179 static char lbuf
[1024];
180 unsigned char dig
[SHA_DIGESTSIZE
];
181 BigInteger x
, v
, n
, g
;
183 int ulen
= strlen(username
);
186 lbuf
[sizeof(lbuf
) - 1] = 0;
188 f
= fopen(passwd_file
, "r");
192 while (fgets(lbuf
, sizeof(lbuf
) - 1, f
) != NULL
) {
195 if (strncmp(lbuf
, username
, ulen
) != 0)
198 if (lbuf
[ulen
] != ':')
201 str
= &lbuf
[ulen
+ 1];
203 if (strncmp(str
, "$1$", 3) != 0)
206 s2
= strchr(str
+ 3, '$');
210 if (s2
- str
>= MAXSALTLEN
)
213 strncpy((char *) pw_saltbuf
, str
, s2
- str
);
214 pw_saltbuf
[s2
- str
] = 0;
216 s2
= strchr(s2
, ':');
221 if (s2
- str
>= MAXPARAMLEN
)
224 strncpy((char *)password
, str
, MAXPARAMLEN
);
234 tce
= gettcid(tpe
.index
);
236 t_random(tpe
.password
.data
, SALTLEN
);
237 } while (memcmp(saltbuf
, (char *)dig
, sizeof(saltbuf
)) == 0);
241 n
= BigIntegerFromBytes(tce
->modulus
.data
, tce
->modulus
.len
);
242 g
= BigIntegerFromBytes(tce
->generator
.data
, tce
->generator
.len
);
243 v
= BigIntegerFromInt(0);
246 SHA1Update(&ctxt
, (unsigned char *) username
, strlen(username
));
247 SHA1Update(&ctxt
, (unsigned char *) ":", 1);
248 SHA1Update(&ctxt
, (unsigned char *) password
, strlen(password
));
249 SHA1Final(dig
, &ctxt
);
252 SHA1Update(&ctxt
, saltbuf
, tpe
.salt
.len
);
253 SHA1Update(&ctxt
, dig
, sizeof(dig
));
254 SHA1Final(dig
, &ctxt
);
256 /* x = H(s, H(u, ':', p)) */
257 x
= BigIntegerFromBytes(dig
, sizeof(dig
));
259 BigIntegerModExp(v
, g
, x
, n
);
260 tpe
.password
.len
= BigIntegerToBytes(v
, (unsigned char *)pwbuf
);
270 chksum(u16_t sum
, const u8_t
*data
, u16_t len
)
274 const u8_t
*last_byte
;
277 last_byte
= data
+ len
- 1;
279 while(dataptr
< last_byte
) { /* At least two more bytes */
280 t
= (dataptr
[0] << 8) + dataptr
[1];
288 if(dataptr
== last_byte
) {
289 t
= (dataptr
[0] << 8) + 0;
296 /* Return sum in host byte order. */
301 ead_send_packet_clone(struct ead_packet
*pkt
)
305 memcpy(pktbuf
, pkt
, offsetof(struct ead_packet
, msg
));
306 memcpy(pktbuf
->eh
.ether_shost
, ethmac
, 6);
307 memcpy(pktbuf
->eh
.ether_dhost
, pkt
->eh
.ether_shost
, 6);
310 len
= sizeof(struct ead_packet
) - sizeof(struct ether_header
) + ntohl(pktbuf
->msg
.len
);
311 pktbuf
->len
[0] = len
>> 8;
312 pktbuf
->len
[1] = len
& 0xff;
313 memcpy(pktbuf
->srcipaddr
, &pkt
->msg
.ip
, 4);
314 memcpy(pktbuf
->destipaddr
, pkt
->srcipaddr
, 4);
317 pktbuf
->ipchksum
= 0;
318 sum
= chksum(0, (void *) &pktbuf
->vhl
, UIP_IPH_LEN
);
321 pktbuf
->ipchksum
= htons(~sum
);
324 pktbuf
->srcport
= pkt
->destport
;
325 pktbuf
->destport
= pkt
->srcport
;
329 pktbuf
->udplen
= htons(len
);
330 pktbuf
->udpchksum
= 0;
331 sum
= len
+ UIP_PROTO_UDP
;
332 sum
= chksum(sum
, (void *) &pktbuf
->srcipaddr
[0], 8); /* src, dest ip */
333 sum
= chksum(sum
, (void *) &pktbuf
->srcport
, len
);
336 pktbuf
->udpchksum
= htons(~sum
);
337 pcap_sendpacket(pcap_fp
, (void *) pktbuf
, sizeof(struct ead_packet
) + ntohl(pktbuf
->msg
.len
));
341 set_state(int nstate
)
346 if (nstate
< state
) {
347 if ((nstate
< EAD_TYPE_GET_PRIME
) &&
348 (state
>= EAD_TYPE_GET_PRIME
)) {
356 case EAD_TYPE_SET_USERNAME
:
357 if (!prepare_password())
359 ts
= t_serveropenraw(&tpe
, tce
);
363 case EAD_TYPE_GET_PRIME
:
364 B
= t_servergenexp(ts
);
366 case EAD_TYPE_SEND_A
:
367 skey
= t_servergetkey(ts
, &A
);
381 handle_ping(struct ead_packet
*pkt
, int len
, int *nstate
)
383 struct ead_msg
*msg
= &pktbuf
->msg
;
384 struct ead_msg_pong
*pong
= EAD_DATA(msg
, pong
);
387 slen
= strlen(dev_name
);
391 msg
->len
= htonl(sizeof(struct ead_msg_pong
) + slen
);
392 strncpy(pong
->name
, dev_name
, slen
);
393 pong
->name
[slen
] = 0;
394 pong
->auth_type
= htons(EAD_AUTH_MD5
);
400 handle_set_username(struct ead_packet
*pkt
, int len
, int *nstate
)
402 struct ead_msg
*msg
= &pkt
->msg
;
403 struct ead_msg_user
*user
= EAD_DATA(msg
, user
);
405 set_state(EAD_TYPE_SET_USERNAME
); /* clear old state */
406 strncpy(username
, user
->username
, sizeof(username
));
407 username
[sizeof(username
) - 1] = 0;
412 *nstate
= EAD_TYPE_GET_PRIME
;
417 handle_get_prime(struct ead_packet
*pkt
, int len
, int *nstate
)
419 struct ead_msg
*msg
= &pktbuf
->msg
;
420 struct ead_msg_salt
*salt
= EAD_DATA(msg
, salt
);
422 msg
->len
= htonl(sizeof(struct ead_msg_salt
));
423 salt
->prime
= tce
->index
- 1;
424 salt
->len
= ts
->s
.len
;
425 memcpy(salt
->salt
, ts
->s
.data
, ts
->s
.len
);
426 memcpy(salt
->ext_salt
, pw_saltbuf
, MAXSALTLEN
);
428 *nstate
= EAD_TYPE_SEND_A
;
433 handle_send_a(struct ead_packet
*pkt
, int len
, int *nstate
)
435 struct ead_msg
*msg
= &pkt
->msg
;
436 struct ead_msg_number
*number
= EAD_DATA(msg
, number
);
437 len
= ntohl(msg
->len
) - sizeof(struct ead_msg_number
);
439 if (len
> MAXPARAMLEN
+ 1)
444 memcpy(A
.data
, number
->data
, len
);
447 number
= EAD_DATA(msg
, number
);
448 msg
->len
= htonl(sizeof(struct ead_msg_number
) + B
->len
);
449 memcpy(number
->data
, B
->data
, B
->len
);
451 *nstate
= EAD_TYPE_SEND_AUTH
;
456 handle_send_auth(struct ead_packet
*pkt
, int len
, int *nstate
)
458 struct ead_msg
*msg
= &pkt
->msg
;
459 struct ead_msg_auth
*auth
= EAD_DATA(msg
, auth
);
461 if (t_serververify(ts
, auth
->data
) != 0) {
462 DEBUG(2, "Client authentication failed\n");
463 *nstate
= EAD_TYPE_SET_USERNAME
;
468 auth
= EAD_DATA(msg
, auth
);
469 msg
->len
= htonl(sizeof(struct ead_msg_auth
));
471 DEBUG(2, "Client authentication successful\n");
472 memcpy(auth
->data
, t_serverresponse(ts
), sizeof(auth
->data
));
474 *nstate
= EAD_TYPE_SEND_CMD
;
479 handle_send_cmd(struct ead_packet
*pkt
, int len
, int *nstate
)
481 struct ead_msg
*msg
= &pkt
->msg
;
482 struct ead_msg_cmd
*cmd
= EAD_ENC_DATA(msg
, cmd
);
483 struct ead_msg_cmd_data
*cmddata
;
484 struct timeval tv
, to
, tn
;
493 datalen
= ead_decrypt_message(msg
) - sizeof(struct ead_msg_cmd
);
497 type
= ntohs(cmd
->type
);
498 timeout
= ntohs(cmd
->timeout
);
501 cmd
->data
[datalen
] = 0;
507 fcntl(pfd
[0], F_SETFL
, O_NONBLOCK
| fcntl(pfd
[0], F_GETFL
));
508 child_pending
= true;
512 fd
= open("/dev/null", O_RDWR
);
518 system((char *)cmd
->data
);
520 } else if (pid
> 0) {
523 timeout
= EAD_CMD_TIMEOUT
;
529 case EAD_CMD_BACKGROUND
:
532 /* close stdin, stdout, stderr, replace with fd to /dev/null */
533 fd
= open("/dev/null", O_RDWR
);
539 system((char *)cmd
->data
);
541 } else if (pid
> 0) {
550 cmddata
= EAD_ENC_DATA(msg
, cmd_data
);
555 /* send keepalive packets every 200 ms so that the client doesn't timeout */
556 gettimeofday(&to
, NULL
);
557 memcpy(&tn
, &to
, sizeof(tn
));
558 tv
.tv_usec
= PCAP_TIMEOUT
* 1000;
562 FD_SET(pfd
[0], &fds
);
563 nfds
= select(pfd
[0] + 1, &fds
, NULL
, NULL
, &tv
);
566 bytes
= read(pfd
[0], cmddata
->data
, 1024);
570 if (!bytes
&& !child_pending
)
572 DEBUG(3, "Sending %d bytes of console data, type=%d, timeout=%d\n", bytes
, ntohl(msg
->type
), timeout
);
573 ead_encrypt_message(msg
, sizeof(struct ead_msg_cmd_data
) + bytes
);
574 ead_send_packet_clone(pkt
);
575 gettimeofday(&tn
, NULL
);
576 } while (tn
.tv_sec
< to
.tv_sec
+ timeout
);
583 ead_encrypt_message(msg
, sizeof(struct ead_msg_cmd_data
));
591 parse_message(struct ead_packet
*pkt
, int len
)
593 bool (*handler
)(struct ead_packet
*pkt
, int len
, int *nstate
);
594 int min_len
= sizeof(struct ead_packet
);
596 int type
= ntohl(pkt
->msg
.type
);
598 if ((type
>= EAD_TYPE_GET_PRIME
) &&
602 if ((type
!= EAD_TYPE_PING
) &&
603 ((ntohs(pkt
->msg
.sid
) & EAD_INSTANCE_MASK
) >>
604 EAD_INSTANCE_SHIFT
) != instance
->id
)
609 handler
= handle_ping
;
611 case EAD_TYPE_SET_USERNAME
:
612 handler
= handle_set_username
;
613 min_len
+= sizeof(struct ead_msg_user
);
615 case EAD_TYPE_GET_PRIME
:
616 handler
= handle_get_prime
;
618 case EAD_TYPE_SEND_A
:
619 handler
= handle_send_a
;
620 min_len
+= sizeof(struct ead_msg_number
);
622 case EAD_TYPE_SEND_AUTH
:
623 handler
= handle_send_auth
;
624 min_len
+= sizeof(struct ead_msg_auth
);
626 case EAD_TYPE_SEND_CMD
:
627 handler
= handle_send_cmd
;
628 min_len
+= sizeof(struct ead_msg_cmd
) + sizeof(struct ead_msg_encrypted
);
635 DEBUG(2, "discarding packet: message too small\n");
639 pktbuf
->msg
.magic
= htonl(EAD_MAGIC
);
640 pktbuf
->msg
.type
= htonl(type
+ 1);
641 pktbuf
->msg
.nid
= htons(nid
);
642 pktbuf
->msg
.sid
= pkt
->msg
.sid
;
645 if (handler(pkt
, len
, &nstate
)) {
646 DEBUG(2, "sending response to packet type %d: %d\n", type
+ 1, ntohl(pktbuf
->msg
.len
));
647 /* format response packet */
648 ead_send_packet_clone(pkt
);
654 handle_packet(u_char
*user
, const struct pcap_pkthdr
*h
, const u_char
*bytes
)
656 struct ead_packet
*pkt
= (struct ead_packet
*) bytes
;
658 if (h
->len
< sizeof(struct ead_packet
))
661 if (pkt
->eh
.ether_type
!= htons(ETHERTYPE_IP
))
664 if (memcmp(pkt
->eh
.ether_dhost
, "\xff\xff\xff\xff\xff\xff", 6) != 0)
667 if (pkt
->proto
!= UIP_PROTO_UDP
)
670 if (pkt
->destport
!= htons(EAD_PORT
))
673 if (pkt
->msg
.magic
!= htonl(EAD_MAGIC
))
676 if (h
->len
< sizeof(struct ead_packet
) + ntohl(pkt
->msg
.len
))
679 if ((pkt
->msg
.nid
!= 0xffff) &&
680 (pkt
->msg
.nid
!= htons(nid
)))
683 parse_message(pkt
, h
->len
);
687 ead_pcap_reopen(bool first
)
689 static char errbuf
[PCAP_ERRBUF_SIZE
] = "";
691 if (pcap_fp_rx
&& (pcap_fp_rx
!= pcap_fp
))
692 pcap_close(pcap_fp_rx
);
700 if (instance
->bridge
[0]) {
701 pcap_fp_rx
= ead_open_pcap(instance
->bridge
, errbuf
, 1);
702 pcap_fp
= ead_open_pcap(instance
->ifname
, errbuf
, 0);
706 pcap_fp
= ead_open_pcap(instance
->ifname
, errbuf
, 1);
710 pcap_fp_rx
= pcap_fp
;
711 if (first
&& !pcap_fp
) {
712 DEBUG(1, "WARNING: unable to open interface '%s'\n", instance
->ifname
);
718 pcap_setfilter(pcap_fp_rx
, &pktfilter
);
726 if (pcap_dispatch(pcap_fp_rx
, 1, handle_packet
, NULL
) < 0) {
727 ead_pcap_reopen(false);
735 usage(const char *prog
)
737 fprintf(stderr
, "Usage: %s [<options>]\n"
739 "\t-B Run in background mode\n"
740 "\t-d <device> Set the device to listen on\n"
741 "\t-D <name> Set the name of the device visible to clients\n"
742 "\t-p <file> Set the password file for authenticating\n"
743 "\t-P <file> Write a pidfile\n"
749 server_handle_sigchld(int sig
)
751 struct ead_instance
*in
;
756 list_for_each(p
, &instances
) {
757 in
= list_entry(p
, struct ead_instance
, list
);
767 instance_handle_sigchld(int sig
)
771 child_pending
= false;
775 start_server(struct ead_instance
*i
)
787 signal(SIGCHLD
, instance_handle_sigchld
);
788 ead_pcap_reopen(true);
791 if (pcap_fp_rx
!= pcap_fp
)
792 pcap_close(pcap_fp_rx
);
799 start_servers(bool restart
)
801 struct ead_instance
*in
;
804 list_for_each(p
, &instances
) {
805 in
= list_entry(p
, struct ead_instance
, list
);
815 stop_server(struct ead_instance
*in
, bool do_free
)
818 kill(in
->pid
, SIGKILL
);
827 server_handle_sigint(int sig
)
829 struct ead_instance
*in
;
830 struct list_head
*p
, *tmp
;
832 list_for_each_safe(p
, tmp
, &instances
) {
833 in
= list_entry(p
, struct ead_instance
, list
);
834 stop_server(in
, true);
841 check_bridge_port(const char *br
, const char *port
, void *arg
)
843 struct ead_instance
*in
;
844 struct list_head
*p
, *tmp
;
846 list_for_each(p
, &instances
) {
847 in
= list_entry(p
, struct ead_instance
, list
);
849 if (strcmp(in
->ifname
, port
) != 0)
853 if (strcmp(in
->bridge
, br
) == 0)
856 strncpy(in
->bridge
, br
, sizeof(in
->bridge
));
857 DEBUG(2, "assigning port %s to bridge %s\n", in
->ifname
, in
->bridge
);
858 stop_server(in
, false);
864 check_bridge(const char *name
, void *arg
)
866 br_foreach_port(name
, check_bridge_port
, arg
);
872 check_all_interfaces(void)
875 struct ead_instance
*in
;
876 struct list_head
*p
, *tmp
;
878 br_foreach_bridge(check_bridge
, NULL
);
880 /* look for interfaces that are no longer part of a bridge */
881 list_for_each(p
, &instances
) {
882 in
= list_entry(p
, struct ead_instance
, list
);
885 in
->br_check
= false;
886 } else if (in
->bridge
[0]) {
887 DEBUG(2, "removing port %s from bridge %s\n", in
->ifname
, in
->bridge
);
889 stop_server(in
, false);
896 int main(int argc
, char **argv
)
898 struct ead_instance
*in
;
900 const char *pidfile
= NULL
;
901 bool background
= false;
906 return usage(argv
[0]);
908 INIT_LIST_HEAD(&instances
);
909 while ((ch
= getopt(argc
, argv
, "Bd:D:fhp:P:")) != -1) {
918 return usage(argv
[0]);
920 in
= malloc(sizeof(struct ead_instance
));
921 memset(in
, 0, sizeof(struct ead_instance
));
922 INIT_LIST_HEAD(&in
->list
);
923 strncpy(in
->ifname
, optarg
, sizeof(in
->ifname
) - 1);
924 list_add(&in
->list
, &instances
);
931 passwd_file
= optarg
;
938 signal(SIGCHLD
, server_handle_sigchld
);
939 signal(SIGINT
, server_handle_sigint
);
940 signal(SIGTERM
, server_handle_sigint
);
941 signal(SIGKILL
, server_handle_sigint
);
944 fprintf(stderr
, "Error: ead needs at least one interface\n");
952 fd
= open("/dev/null", O_RDWR
);
963 fd
= open(pidfile
, O_CREAT
|O_WRONLY
|O_EXCL
, 0644);
965 len
= sprintf(pid
, "%d\n", getpid());
971 /* randomize the mac address */
972 get_random_bytes(ethmac
+ 3, 3);
973 nid
= *(((u16_t
*) ethmac
) + 2);
975 start_servers(false);
982 check_all_interfaces();
This page took 0.091544 seconds and 5 git commands to generate.