1 /*-
2  * Copyright (c) 1998-2008 DHIS, Dynamic Host Information System
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27 
28 
29 #include "dhisd.h"
30 #include "network.h"
31 #include "ddb.h"
32 #include "online.h"
33 #include "qrc.h"
34 #include "misc.h"
35 
36 int udp_sock=-1;
37 int udp_port=DHISD_PORT;
38 char dhisd_bind_address[32]="0.0.0.0";
39 
40 extern online_t *onbase;
41 
42 
43 /*
44  * msg_size_by_opcode() - Returns the size of a structure of opcode type
45  *
46  */
msg_size_by_opcode(int opcode)47 int msg_size_by_opcode(int opcode) {
48 
49 	switch(opcode) {
50 	case(ECHO_REQ): return(sizeof(echo_req_t));
51 	case(ECHO_ACK): return(sizeof(echo_ack_t));
52 	case(AUTH_REQ): return(sizeof(auth_req_t));
53 	case(AUTH_ACK): return(sizeof(auth_ack_t));
54 	case(R51_AUTH_ACK): return(sizeof(auth_ack_51_t));
55 	case(AUTH_DENY): return(sizeof(auth_deny_t));
56 	case(AUTH_SX): return(sizeof(auth_sendx_t));
57 	case(AUTH_SY): return(sizeof(auth_sendy_t));
58 	case(CHECK_REQ): return(sizeof(check_req_t));
59 	case(CHECK_ACK): return(sizeof(check_ack_t));
60 	case(OFFLINE_REQ): return(sizeof(offline_req_t));
61 
62 	case(R4_ECHO_REQ): return(sizeof(r4_echo_req_t));
63 	case(R4_ECHO_ACK): return(sizeof(r4_echo_ack_t));
64 	case(R4_AUTH_REQ): return(sizeof(r4_auth_req_t));
65 	case(R4_AUTH_ACK): return(sizeof(r4_auth_ack_t));
66 	case(R4_AUTH_DENY): return(sizeof(r4_auth_deny_t));
67 	case(R4_AUTH_SX): return(sizeof(r4_auth_sendx_t));
68 	case(R4_AUTH_SY): return(sizeof(r4_auth_sendy_t));
69 	case(R4_CHECK_REQ): return(sizeof(r4_check_req_t));
70 	case(R4_CHECK_ACK): return(sizeof(r4_check_ack_t));
71 	case(R4_OFFLINE_REQ): return(sizeof(r4_offline_req_t));
72 
73 	case(R3_ONLINE_REQ): return(sizeof(r3_online_req_t));
74 	case(R3_OFFLINE_REQ): return(sizeof(r3_offline_req_t));
75 	default:	return(0);
76 	}
77 }
78 
79 /*
80  * swap_int() - Swaps the byte order of an integer
81  *
82  */
swap_int(int * n)83 void swap_int(int *n) {
84 
85         unsigned char *p,a,b,c,d;
86         p=(unsigned char *)n;
87         a=*p++;b=*p++;c=*p++;d=*p;
88         p=(unsigned char *)n;
89         *p++ = d;*p++ = c;*p++ = b;*p = a;
90 }
91 
92 /*
93  * swap_msg() - Calls swap_int to n members of the message
94  *
95  */
swap_msg(int * m,int n)96 void swap_msg(int *m,int n) {
97 
98         int i;
99         for(i=0;i<n;i++) {
100                 swap_int(m);
101                 m++;
102         }
103 }
104 
105 /*
106  * little_entian() - Checks if the system is little endian.
107  *                   Returns 1 if so or 0 if not
108  *
109  */
little_endian(void)110 int little_endian(void) {
111 
112         int a=1;
113         unsigned char *p;
114         p=(unsigned char *)&a;
115         if((int)p[0]==1) return(1);
116         return(0);
117 }
118 
119 /*
120  * convert_message() - Converts a message to big/little endian as required
121  *
122  */
convert_message(msg_t * p,int mode)123 void convert_message(msg_t *p,int mode) {
124 
125 	int opcode=0;
126 
127 	if(mode==1)  	opcode=p->hdr.opcode;
128 	swap_msg((int *)&(p->hdr),4);
129 	if(mode==2) opcode=p->hdr.opcode;
130 
131         if(opcode >= ECHO_REQ )
132 		swap_int((int *)&(p->hdr.hostid));
133 
134 
135 	switch(opcode) {
136 
137 
138 	case(ECHO_REQ): break;
139 	case(ECHO_ACK): { echo_ack_t *p2; p2=(echo_ack_t *)p;
140 			  swap_int((int *)&(p2->oserial));
141 			  break;
142 			}
143 
144 	case(AUTH_REQ):  { auth_req_t *p2; p2=(auth_req_t *)p;
145 			  swap_int((int *)&(p2->refresh));
146 			  break;
147 			}
148 	case(AUTH_ACK):  { auth_ack_t *p2; p2=(auth_ack_t *)p;
149 			  swap_int((int *)&(p2->sid));
150 			  break;
151 			}
152 	case(R51_AUTH_ACK):  { auth_ack_51_t *p2; p2=(auth_ack_51_t *)p;
153 			  swap_int((int *)&(p2->sid));
154 			  break;
155 			}
156 	case(AUTH_DENY): break;
157 	case(AUTH_SX): { auth_sendx_t *p2; p2=(auth_sendx_t *)p;
158 			  break;
159 			}
160 
161 	case(AUTH_SY): break;
162 
163 	case(CHECK_REQ):  { check_req_t *p2; p2=(check_req_t *)p;
164 			  swap_int((int *)&(p2->next_check));
165 			  break;
166 			}
167 
168 	case(CHECK_ACK):  { check_ack_t *p2; p2=(check_ack_t *)p;
169 			  swap_int((int *)&(p2->sid));
170 			  break;
171 			}
172 
173 	case(OFFLINE_REQ):  { offline_req_t *p2; p2=(offline_req_t *)p;
174 			  swap_int((int *)&(p2->sid));
175 			  break;
176 			}
177 
178 	/* R4 messages */
179 	case(R4_ECHO_REQ): break;
180 	case(R4_ECHO_ACK): { r4_echo_ack_t *p2; p2=(r4_echo_ack_t *)p;
181 			  swap_int((int *)&(p2->oserial));
182 			  break;
183 			}
184 
185 	case(R4_AUTH_REQ):  { r4_auth_req_t *p2; p2=(r4_auth_req_t *)p;
186 			  swap_int((int *)&(p2->id));
187 			  break;
188 			}
189 	case(R4_AUTH_ACK):  { r4_auth_ack_t *p2; p2=(r4_auth_ack_t *)p;
190 			  swap_int((int *)&(p2->sid));
191 			  break;
192 			}
193 	case(R4_AUTH_DENY): break;
194 	case(R4_AUTH_SX): { r4_auth_sendx_t *p2; p2=(r4_auth_sendx_t *)p;
195 			  swap_int((int *)&(p2->id));
196 			  break;
197 			}
198 
199 	case(R4_AUTH_SY): break;
200 
201 	case(R4_CHECK_REQ):  { r4_check_req_t *p2; p2=(r4_check_req_t *)p;
202 			  swap_int((int *)&(p2->next_check));
203 			  break;
204 			}
205 
206 	case(R4_CHECK_ACK):  { r4_check_ack_t *p2; p2=(r4_check_ack_t *)p;
207 			  swap_int((int *)&(p2->sid));
208 			  break;
209 			}
210 
211 	case(R4_OFFLINE_REQ):  { r4_offline_req_t *p2; p2=(r4_offline_req_t *)p;
212 			  swap_int((int *)&(p2->sid));
213 			  break;
214 			}
215 
216 
217 	/* R3 messages */
218 	case(R3_OFFLINE_REQ):  { r3_offline_req_t *p2; p2=(r3_offline_req_t *)p;
219 			  swap_int((int *)&(p2->id));
220 			  swap_int((int *)&(p2->pass));
221 			  break;
222 			}
223 	case(R3_ONLINE_REQ):  { r3_online_req_t *p2; p2=(r3_online_req_t *)p;
224 			  swap_int((int *)&(p2->id));
225 			  swap_int((int *)&(p2->pass));
226 			  break;
227 			}
228 
229 	}
230 	return;
231 }
232 
get_serial(void)233 int get_serial(void) { static int s=0; return(++s); }
234 
235 /*
236  * net_init() - Initialises the socket descriptor for receiving
237  *              UDP connections
238  *
239  * Updates:   udp_sock only
240  *
241  * Returns:   0 on success, 1 on error
242  *
243  */
244 
net_init(void)245 int net_init(void) {
246 
247         struct sockaddr_in sa;
248 
249 
250         /* Create UDP socket */
251         udp_sock=socket(AF_INET,SOCK_DGRAM,0);
252         if(udp_sock<0) return(1);
253 
254         /* Bind the UDP socket */
255         sa.sin_family=AF_INET;
256         sa.sin_port=htons(udp_port);
257         sa.sin_addr.s_addr=inet_addr(dhisd_bind_address);
258         if(bind(udp_sock,(struct sockaddr *)&sa,sizeof(struct sockaddr_in)))
259         {
260                 close(udp_sock);
261                 return(1);
262         }
263 
264         /* UDP socket is ready to receive messages */
265         return(0);
266 }
267 
268 /*
269  * net_close() - Closes sockets associated with UDP incoming ports
270  *
271  * Updates:   udp_sock only
272  *
273  * Returns:   0
274  *
275  */
net_close(void)276 int net_close(void) {
277 
278         close(udp_sock);
279         return(0);
280 }
281 
282 /*
283  * net_check_message() - Returns 1 if there is a message to be read or 0
284  *                           otherwise.
285  *
286  */
net_check_message(void)287 int net_check_message(void) {
288 
289    	fd_set readfds;
290         struct timeval tv;
291 
292         /* Prepare for select */
293         FD_ZERO(&readfds);
294         FD_SET(udp_sock,&readfds);
295         tv.tv_sec=0;
296         tv.tv_usec=0;
297 
298         /* Check for new messages */
299         if(select(udp_sock+1,&readfds,NULL,NULL,&tv)==-1) return(0);
300         if(!FD_ISSET(udp_sock,&readfds)) return(0);
301 	return(1);
302 }
303 
304 /*
305  * net_read_message() - Reads a message into *p and returns length read
306  *			or 0 on error.
307  *
308  */
net_read_message(msg_t * p,int * from)309 int net_read_message(msg_t *p,int *from) {
310 
311 	int n;
312 	socklen_t sl;
313 	struct sockaddr_in sa;
314 
315         /* Read message */
316         sl=sizeof(struct sockaddr_in);
317         n=recvfrom(udp_sock,p,MAX_MSG,0,(struct sockaddr *)&sa,&sl);
318 	if(n<=0 || n >MAX_MSG) return(0);
319 
320 	DSYSLOG(1,(LOG_DEBUG,"net_read_message(): Message arrived from %s\n",
321 		inet_ntoa(sa.sin_addr)));
322 
323 	/* Convert to big endian if necessary */
324 	if(little_endian()) convert_message(p,2);
325 	memcpy(from,&sa.sin_addr,sizeof(struct in_addr));
326 
327 	if(p->hdr.version>=54)
328 		p->hdr.rport=ntohs(sa.sin_port);
329 
330 
331 	return(n);
332 }
333 
334 /*
335  * net_write_message() - Writes a message from *p and returns the number of
336  *                       bytes sent or 0 on error.
337  *
338  */
net_write_message(msg_t * p,int toaddr,int toport)339 int net_write_message(msg_t *p,int toaddr,int toport) {
340 
341  	struct sockaddr_in sa;
342 	int len;
343 	int r;
344 	struct in_addr sai;
345 
346 	sai.s_addr=toaddr;
347 	DSYSLOG(1,(LOG_DEBUG,"net_write_message(): Sending Message to %s\n",
348 		inet_ntoa(sai)));
349 
350 	p->hdr.version=DHIS_VERSION;
351 	p->hdr.serial=get_serial();
352 	p->hdr.rport=udp_port;
353 
354         /* set destination */
355         sa.sin_family=AF_INET;
356         sa.sin_port=htons(toport);
357         sa.sin_addr.s_addr=toaddr;
358 
359 	/* Get message size */
360 	len=msg_size_by_opcode(p->hdr.opcode);
361 
362 	/* Convert to big endian if necessary */
363 	if(little_endian()) convert_message(p,1);
364 
365         /* Send message request */
366         r=sendto(udp_sock,(unsigned char *)p,len,0,(struct sockaddr *)&sa,
367 		sizeof(struct sockaddr_in));
368 
369 	/* Convert back just in case */
370 	if(little_endian()) convert_message(p,2);
371 
372 	return(r);
373 
374 }
375 
376 
net_do_dgram(msg_t msg,int from)377 int net_do_dgram(msg_t msg,int from) {
378 
379 	DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Processing packet [OPCODE=%x] started\n",
380 			   msg.hdr.opcode));
381 
382 	/* First lets take care of DHIS R3 compatible messages */
383 
384 	if(msg.hdr.version<DHIS_MIN_VERSION) return(0);
385 
386 	if(msg.hdr.version<DHIS_R4) { /* DHIS R3 here */
387 
388 		char *p;
389 		r3_online_req_t *m;	/* Same as offline_req anyway */
390 
391 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Message is in R3 format\n"));
392 
393 		m=(r3_online_req_t *)&msg;
394 		if(msg.hdr.opcode!=R3_ONLINE_REQ && msg.hdr.opcode!=R3_OFFLINE_REQ) {
395 
396 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Message opcode is unsupported. Discarded.\n"));
397 
398 			return(0);
399 		}
400 
401 		p=db_password(m->id);
402 		if(p==NULL) {
403 
404 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): HostID does not match database.\n"));
405 
406 			return(0);
407 		}
408 
409 		if(r3_pass_encrypt((unsigned char *)p,msg.hdr.rport)!=m->pass) {
410 
411 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Security: Invalid password. Discarded.\n"));
412 
413 			return(0);
414 		}
415 		if(msg.hdr.opcode==R3_ONLINE_REQ) {
416 
417 			if(db_is_locked(m->id)) {
418 				DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Online Broadcast: But record is locked!.\n"));
419 			}
420 			else {
421 				DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Online Broadcast: callind on_update().\n"));
422 
423 				on_update(m->id,from,0,msg.hdr.version,0);
424 			}
425 		}
426 		if(msg.hdr.opcode==R3_OFFLINE_REQ) {
427 
428 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Offline Broadcast: callind on_delete().\n"));
429 
430 			on_delete(m->id);
431 		}
432 
433 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): End of R3 message processing.\n"));
434 
435 		return(1);
436 	} /* end R3 */
437 
438 	/* Now lets process R4 messages */
439 
440 
441 	if(msg.hdr.version>=40 && msg.hdr.version < 50)
442 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Message is in R4 format\n"));
443 
444 	if(msg.hdr.opcode==R4_OFFLINE_REQ) {
445 		r4_offline_req_t *mp;
446 		online_t *op;
447 		mp=(r4_offline_req_t *)&msg;
448 
449 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): R4_OFFLINE_REQ received\n"));
450 
451 		op=onbase;
452 		while(op!=NULL) {
453 			if(op->sid==mp->sid && op->addr==from) break;
454 			op=op->next;
455 		}
456 		if(op!=NULL) {
457 
458 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Calling on_delete() for %d\n",op->id));
459 
460 			on_delete(op->id);
461 		}
462 		else {
463 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Security: Invalid addr or sid. Discarded.\n"));
464 		}
465 		return(1);
466 	}
467 	if(msg.hdr.opcode==R4_ECHO_REQ) {
468 		r4_echo_ack_t m;
469 
470 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): R4_ECHO_REQ received. Sending ECHO_ACK.\n"));
471 
472 		m.hdr.opcode=R4_ECHO_ACK;
473 		m.oserial=msg.hdr.serial;
474 		net_write_message((msg_t *)&m,from,msg.hdr.rport);
475 		return(1);
476 	}
477 
478 	if(msg.hdr.opcode==R4_CHECK_ACK) {
479 		online_t *p;
480 		r4_check_ack_t *mp;
481 
482 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Received R4_CHECK_ACK.\n"));
483 
484 		mp=(r4_check_ack_t *)&msg;
485 		p=onbase;
486 		while(p!=NULL) {
487 			if(p->addr==from) break;
488 			p=p->next;
489 		}
490 		if(p==NULL) return(0);
491 		if(mp->sid!=p->sid) return(0);
492 		on_update(p->id,from,msg.hdr.rport,msg.hdr.version,0);
493 		p->ka=time(NULL) + NEXT_CHECK;
494 		p->check_fails=0;
495 		return(1);
496 	}
497 
498 	if(msg.hdr.opcode==R4_AUTH_SX) {
499 		struct dhis_rec *dbp;
500 		r4_auth_sendx_t *mp;
501 		mpz_t x;
502 		char buff[1024];
503 
504 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Received R4_AUTH_SX.\n"));
505 
506 		mp=(r4_auth_sendx_t *)&msg;
507 		dbp=get_rec(mp->id);
508 
509 		if(dbp==NULL) {
510 			r4_auth_deny_t m;
511 
512 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_DENY. Invalid ID.\n"));
513 
514 			m.hdr.opcode=R4_AUTH_DENY;
515 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
516 			return(0);
517 		}
518 		if(!dbp->status) {
519 			r4_auth_deny_t m;
520 
521 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_DENY. Locked.\n"));
522 
523 			m.hdr.opcode=R4_AUTH_DENY;
524 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
525 			return(0);
526 		}
527 
528 		if(dbp->atype!=AQRC || dbp->xstage==0) {
529 			r4_auth_deny_t m;
530 
531 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_DENY. Not in X waiting mode.\n"));
532 
533 			m.hdr.opcode=R4_AUTH_DENY;
534 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
535 			return(0);
536 		}
537 		mpz_init(x);
538 		memcpy(buff,mp->x,200);
539 		buff[200]='\0';
540 		mpz_set_str(x,buff,10);
541 		if(mpz_cmp(x,dbp->x)) {
542 			r4_auth_deny_t m;
543 
544 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_DENY. X and X do not match.\n"));
545 
546 			m.hdr.opcode=R4_AUTH_DENY;
547 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
548 			if(dbp->xstage) mpz_clear(dbp->x);
549 			dbp->xstage=0;
550 			mpz_clear(x);
551 			return(0);
552 		} else {
553 			r4_auth_ack_t m;
554 
555 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_ACK. X and X match.\n"));
556 
557 			mpz_clear(x);
558 			mpz_clear(dbp->x);
559 			dbp->xstage=0;
560 			m.hdr.opcode=R4_AUTH_ACK;
561 			if((m.sid=on_update(dbp->hostid,from,msg.hdr.rport,msg.hdr.version,0))!=0) {
562 				net_write_message((msg_t *)&m,from,msg.hdr.rport);
563 				return(1);
564 			} else return(0);
565 		}
566 	}
567 
568 	if(msg.hdr.opcode==R4_AUTH_REQ) {
569 		struct dhis_rec *dbp;
570 		r4_auth_req_t *mp;
571 		mp=(r4_auth_req_t *)&msg;
572 
573 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Received R4_AUTH_REQ for %d\n",mp->id));
574 
575 		dbp=get_rec(mp->id);
576 		if(dbp==NULL) {
577 			r4_auth_deny_t m;
578 
579 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_DENY. Invalid ID.\n"));
580 
581 			m.hdr.opcode=R4_AUTH_DENY;
582 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
583 			return(0);
584 		}
585 		if(!dbp->status) {
586 			r4_auth_deny_t m;
587 
588 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_DENY. Locked.\n"));
589 
590 			m.hdr.opcode=R4_AUTH_DENY;
591 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
592 			return(0);
593 		}
594 		mp->pass[MAX_PASS-1]='\0';
595 		if(dbp->atype==APASS) {
596 
597 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Password Authentication.\n"));
598 
599 			if(strcmp(mp->pass,dbp->hostpass)) {
600 				r4_auth_deny_t m;
601 
602 				DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_DENY. Invalid Password.\n"));
603 
604 				m.hdr.opcode=R4_AUTH_DENY;
605 				net_write_message((msg_t *)&m,from,msg.hdr.rport);
606 				return(0);
607 			} else {
608 				r4_auth_ack_t m;
609 
610 				DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_ACK.\n"));
611 
612 				m.hdr.opcode=R4_AUTH_ACK;
613 				if((m.sid=on_update(dbp->hostid,from,msg.hdr.rport,msg.hdr.version,0))!=0) {
614 					net_write_message((msg_t *)&m,from,msg.hdr.rport);
615 					return(1);
616 				} else return(0);
617 			}
618 		}
619 		if(dbp->atype==AQRC) {
620 			r4_auth_sendy_t m;
621 			mpz_t y;
622 
623 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): QRC Authentication.\n"));
624 
625 			if(dbp->xstage==1) { dbp->xstage=0; mpz_clear(dbp->x);}
626 			m.hdr.opcode=R4_AUTH_SY;
627 			dbp->xstage=1;
628 			mpz_init(dbp->x);
629 			qrc_genx(dbp->x,dbp->mauthn);
630 			mpz_init(y);
631 			qrc_geny(y,dbp->x,dbp->mauthn);
632 			qrc_fill_str(y,m.y,200);
633 			mpz_clear(y);
634 
635 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending R4_AUTH_SY.\n"));
636 
637 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
638 			return(1);
639 		}
640 		return(0);
641 
642 	}
643 
644 	/* Finally process R5 messages */
645 
646 
647 	if(msg.hdr.version>=50)
648 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Message is in R5 format\n"));
649 
650 	if(msg.hdr.opcode==OFFLINE_REQ) {
651 		offline_req_t *mp;
652 		online_t *op;
653 		mp=(offline_req_t *)&msg;
654 
655 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): OFFLINE_REQ received\n"));
656 
657 		op=onbase;
658 		while(op!=NULL) {
659 			if(op->sid==mp->sid && op->addr==from) break;
660 			op=op->next;
661 		}
662 		if(op!=NULL) {
663 
664 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Calling on_delete() for %d\n",op->id));
665 
666 			on_delete(op->id);
667 		}
668 		else {
669 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Security: Invalid addr or sid. Discarded.\n"));
670 		}
671 		return(1);
672 	}
673 
674 	if(msg.hdr.opcode==ECHO_REQ) {
675 		echo_ack_t m;
676 		online_t *p;
677 		echo_req_t *mp;
678 
679 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): ECHO_REQ received. Sending ECHO_ACK.\n"));
680 
681 		m.hdr.opcode=ECHO_ACK;
682 		m.oserial=msg.hdr.serial;
683 		m.hdr.hostid=msg.hdr.hostid;
684 
685 		mp=(echo_req_t *)&msg;
686 		p=onbase;
687 		while(p!=NULL) {
688 			if(p->id==mp->hdr.hostid) break;
689 			p=p->next;
690 		}
691 
692 		if(p==NULL) {
693 			if(msg.hdr.version>=54)
694 				m.oserial=0;
695 		} else {
696 			if(p->client_refresh && from!=p->addr)
697 				m.oserial=0;
698 		}
699 
700 		net_write_message((msg_t *)&m,from,msg.hdr.rport);
701 
702 		if(p==NULL) return(0);
703 
704 		if(p->client_refresh && from==p->addr) {
705 			on_update(p->id,from,msg.hdr.rport,msg.hdr.version,0);
706 			p->ka=time(NULL) + p->refresh;
707 			p->check_fails=0;
708 		}
709 		return(1);
710 	}
711 
712 	if(msg.hdr.opcode==CHECK_ACK) {
713 		online_t *p;
714 		check_ack_t *mp;
715 
716 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Received CHECK_ACK.\n"));
717 
718 		mp=(check_ack_t *)&msg;
719 		p=onbase;
720 		while(p!=NULL) {
721 			if(p->addr==from && p->id==mp->hdr.hostid) break;
722 			p=p->next;
723 		}
724 		if(p==NULL) return(0);
725 		if(mp->sid!=p->sid) return(0);
726 		on_update(p->id,from,msg.hdr.rport,msg.hdr.version,0);
727 		p->ka=time(NULL) + p->refresh;
728 		p->check_fails=0;
729 		return(1);
730 	}
731 
732 	if(msg.hdr.opcode==AUTH_SX) {
733 		struct dhis_rec *dbp;
734 		auth_sendx_t *mp;
735 		mpz_t x;
736 		char buff[1024];
737 
738 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Received AUTH_SX.\n"));
739 
740 		mp=(auth_sendx_t *)&msg;
741 		dbp=get_rec(mp->hdr.hostid);
742 		if(dbp==NULL) {
743 			auth_deny_t m;
744 
745 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_DENY. Invalid ID.\n"));
746 
747 			m.hdr.opcode=AUTH_DENY;
748 			m.hdr.hostid=msg.hdr.hostid;
749 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
750 			return(0);
751 		}
752 		if(!dbp->status) {
753 			auth_deny_t m;
754 
755 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_DENY. Locked.\n"));
756 
757 			m.hdr.opcode=AUTH_DENY;
758 			m.hdr.hostid=msg.hdr.hostid;
759 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
760 			return(0);
761 		}
762 
763 		if(dbp->atype!=AQRC || dbp->xstage==0) {
764 			auth_deny_t m;
765 
766 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_DENY. Not in X waiting mode.\n"));
767 
768 			m.hdr.opcode=AUTH_DENY;
769 			m.hdr.hostid=msg.hdr.hostid;
770 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
771 			return(0);
772 		}
773 		mpz_init(x);
774 		memcpy(buff,mp->x,200);
775 		buff[200]='\0';
776 		mpz_set_str(x,buff,10);
777 		if(mpz_cmp(x,dbp->x)) {
778 			auth_deny_t m;
779 
780 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_DENY. X and X do not match.\n"));
781 
782 			m.hdr.opcode=AUTH_DENY;
783 			m.hdr.hostid=msg.hdr.hostid;
784 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
785 			if(dbp->xstage) mpz_clear(dbp->x);
786 			dbp->xstage=0;
787 			mpz_clear(x);
788 			return(0);
789 		} else {
790 			auth_ack_t m;
791 			auth_ack_51_t m51;
792 
793 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_ACK. X and X match.\n"));
794 
795 			mpz_clear(x);
796 			mpz_clear(dbp->x);
797 			dbp->xstage=0;
798 			if(msg.hdr.version>=51) {
799 				m51.hdr.opcode=R51_AUTH_ACK;
800 				m51.hdr.hostid=msg.hdr.hostid;
801 				m51.raddr=from;
802 				if((m51.sid=on_update(dbp->hostid,from,msg.hdr.rport,msg.hdr.version,dbp->refresh))!=0) {
803 					net_write_message((msg_t *)&m51,from,msg.hdr.rport);
804 					return(1);
805 				} else return(0);
806 
807 			} else {
808 				m.hdr.opcode=AUTH_ACK;
809 				m.hdr.hostid=msg.hdr.hostid;
810 				if((m.sid=on_update(dbp->hostid,from,msg.hdr.rport,
811 									msg.hdr.version,dbp->refresh))!=0) {
812 					net_write_message((msg_t *)&m,from,msg.hdr.rport);
813 				return(1); } else return(0);
814 			}
815 		}
816 	}
817 
818 	if(msg.hdr.opcode==AUTH_REQ) {
819 		struct dhis_rec *dbp;
820 		auth_req_t *mp;
821 		mp=(auth_req_t *)&msg;
822 
823 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Received AUTH_REQ for %d\n",mp->hdr.hostid));
824 		DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Refresh rate is set to %d\n",mp->refresh));
825 
826 		dbp=get_rec(mp->hdr.hostid);
827 		if(dbp==NULL) {
828 			auth_deny_t m;
829 
830 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_DENY. Invalid ID.\n"));
831 
832 			m.hdr.opcode=AUTH_DENY;
833 			m.hdr.hostid=msg.hdr.hostid;
834 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
835 			return(0);
836 		}
837 		if(!dbp->status) {
838 			auth_deny_t m;
839 
840 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_DENY. Locked.\n"));
841 
842 			m.hdr.opcode=AUTH_DENY;
843 			m.hdr.hostid=msg.hdr.hostid;
844 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
845 			return(0);
846 		}
847 		mp->pass[MAX_PASS-1]='\0';
848 		if(dbp->atype==APASS) {
849 
850 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Password Authentication.\n"));
851 
852 			if(strcmp(mp->pass,dbp->hostpass)) {
853 				auth_deny_t m;
854 
855 				DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_DENY. Invalid Password.\n"));
856 				m.hdr.opcode=AUTH_DENY;
857 				m.hdr.hostid=msg.hdr.hostid;
858 				net_write_message((msg_t *)&m,from,msg.hdr.rport);
859 				return(0);
860 			} else {
861 				auth_ack_t m;
862 				auth_ack_51_t m51;
863 
864 				DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_ACK.\n"));
865 
866 				dbp->refresh=mp->refresh;
867 				if(msg.hdr.version>=51) {
868 					m51.hdr.opcode=R51_AUTH_ACK;
869 					m51.hdr.hostid=msg.hdr.hostid;
870 					m51.raddr=from;
871 					if((m51.sid=on_update(dbp->hostid,from,msg.hdr.rport,
872 										  msg.hdr.version,dbp->refresh))!=0) {
873                         net_write_message((msg_t *)&m51,from,msg.hdr.rport);
874 					return(1); } else return(0);
875 				} else {
876 					m.hdr.opcode=AUTH_ACK;
877 					m.hdr.hostid=msg.hdr.hostid;
878 					if((m.sid=on_update(dbp->hostid,from,msg.hdr.rport,
879 										msg.hdr.version,dbp->refresh))!=0) {
880                         net_write_message((msg_t *)&m,from,msg.hdr.rport);
881 					return(1); } else return(0);
882 				}
883 			}
884 		}
885 		if(dbp->atype==AQRC) {
886 			auth_sendy_t m;
887 			mpz_t y;
888 
889 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): QRC Authentication.\n"));
890 
891 			dbp->refresh=mp->refresh;
892 			if(dbp->xstage==1) { dbp->xstage=0; mpz_clear(dbp->x);}
893 			m.hdr.opcode=AUTH_SY;
894 			dbp->xstage=1;
895 			mpz_init(dbp->x);
896 			qrc_genx(dbp->x,dbp->mauthn);
897 			mpz_init(y);
898 			qrc_geny(y,dbp->x,dbp->mauthn);
899 			qrc_fill_str(y,m.y,200);
900 			mpz_clear(y);
901 
902 			DSYSLOG(1,(LOG_DEBUG,"do_dgram(): Sending AUTH_SY.\n"));
903 
904 			m.hdr.hostid=msg.hdr.hostid;
905 			net_write_message((msg_t *)&m,from,msg.hdr.rport);
906 			return(1);
907 		}
908 		return(0);
909 
910 	}
911 
912 
913 
914 	return(1);
915 }
916 
917 
918 
919