* citserver.c: improved is_public_client(), also if a public_client only
[citadel.git] / citadel / locate_host.c
1 /*
2  * locate the originating host
3  * $Id$
4  */
5
6 #include "sysdep.h"
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <signal.h>
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <limits.h>
15 #include <netdb.h>
16 #include <string.h>
17 #ifdef HAVE_PTHREAD_H
18 #include <pthread.h>
19 #endif
20 #include "citadel.h"
21 #include "server.h"
22 #include "locate_host.h"
23 #include "config.h"
24
25 void locate_host(char *tbuf)
26 {
27         struct sockaddr_in cs;
28         struct hostent *ch, *ch2;
29         int len;
30         char *i;
31         int a1, a2, a3, a4;
32
33         len = sizeof(cs);
34         if (getpeername(CC->client_socket, (struct sockaddr *) &cs, &len) < 0) {
35                 strcpy(tbuf, config.c_fqdn);
36                 return;
37         }
38 #ifdef HAVE_NONREENTRANT_NETDB
39         begin_critical_section(S_NETDB);
40 #endif
41
42         if ((ch = gethostbyaddr((char *) &cs.sin_addr, sizeof(cs.sin_addr),
43                                 AF_INET)) == NULL) {
44               bad_dns:
45                 i = (char *) &cs.sin_addr;
46                 a1 = ((*i++) & 0xff);
47                 a2 = ((*i++) & 0xff);
48                 a3 = ((*i++) & 0xff);
49                 a4 = ((*i++) & 0xff);
50                 sprintf(tbuf, "%d.%d.%d.%d", a1, a2, a3, a4);
51                 goto end;       /* because we might need to end the critical
52                                    section */
53         }
54         /* check if the forward DNS agrees; if not, they're spoofing */
55         if ((ch2 = gethostbyname(ch->h_name)) == NULL)
56                 goto bad_dns;
57
58         /* check address for consistency */
59         for (; *ch2->h_addr_list; ch2->h_addr_list++)
60                 if (!memcmp(*ch2->h_addr_list, &cs.sin_addr,
61                             sizeof cs.sin_addr)) {
62                         strncpy(tbuf, ch->h_name, 24);
63                         goto end;
64                 }
65         goto bad_dns;           /* they were spoofing. report a numeric IP
66                                    address. */
67
68       end:
69
70 #ifdef HAVE_NONREENTRANT_NETDB
71         end_critical_section(S_NETDB);
72 #endif
73
74         tbuf[24] = 0;
75 }