1 /*
2 ** ident-tester.c A small daemon that can be used to test Ident
3 ** servers
4 **
5 ** Author: Peter Eriksson <pen@lysator.liu.se>, 10 Aug 1992
6 */
7
8 #if HAVE_CONFIG_H
9 # include "config.h"
10 #endif
11
12 #include <stdio.h>
13 #include <errno.h>
14 #if HAVE_SYS_TYPES_H
15 # include <sys/types.h>
16 #endif
17 #if HAVE_UNISTD_H
18 # include <unistd.h>
19 #endif
20 #if HAVE_NETDB_H
21 # include <netdb.h>
22 #endif
23 #if HAVE_SYS_SOCKET_H
24 # include <sys/socket.h>
25 #endif
26 #if HAVE_SYSLOG_H
27 # include <syslog.h>
28 #endif
29
30 #define IN_LIBIDENT_SRC
31 #include "ident.h"
32
33 /*
34 ** Lookups the name of the connecting host, or the IP number as a string.
35 ** buf should be at least NI_MAXHOST bytes-long.
36 */
gethost(const struct sockaddr * addr,socklen_t addrlen,char * buf)37 int gethost (const struct sockaddr *addr, socklen_t addrlen, char *buf)
38 {
39 return getnameinfo(addr, addrlen, buf, NI_MAXHOST, NULL, 0, 0);
40 }
41
getport(const struct sockaddr * addr)42 int getport (const struct sockaddr *addr)
43 {
44 switch (addr->sa_family)
45 {
46 case AF_INET:
47 return ntohs(((struct sockaddr_in *)addr)->sin_port);
48 #ifdef AF_INET6
49 case AF_INET6:
50 return ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
51 #endif
52 }
53 return -1;
54 }
55
56 int
main(int argc,char * argv[])57 main (int argc, char *argv[])
58 {
59 struct sockaddr_storage laddr, faddr;
60 int len, res, lport, fport;
61 ident_t *id;
62 char *identifier, *opsys, *charset, hs[NI_MAXHOST];
63
64
65 printf("Welcome to the IDENT server tester, version 2.0\r\n");
66 printf("(Linked with libident %s)\r\n\r\n", id_version);
67
68 fflush(stdout);
69
70 len = sizeof(faddr);
71 if (getpeername(0, (struct sockaddr *) &faddr, &len))
72 {
73 perror("getpeername()");
74 return 1;
75 }
76
77 len = sizeof(laddr);
78 if (getsockname(0, (struct sockaddr *) &laddr, &len))
79 {
80 perror("getsockname()");
81 return 1;
82 }
83
84 res = gethost((struct sockaddr *)&faddr, sizeof(faddr), hs);
85 if (res == EAI_SYSTEM)
86 {
87 perror("getnameinfo()");
88 return 1;
89 }
90 else if (res != 0)
91 {
92 fprintf(stderr, "getnameinfo(): %s\r\n", gai_strerror (res));
93 return 1;
94 }
95
96 printf("Connecting to Ident server at %s...\r\n", hs);
97 fflush(stdout);
98
99 #ifdef LOG_LOCAL3
100 openlog("tidentd", 0, LOG_LOCAL3);
101 #else
102 openlog("tidentd", 0);
103 #endif
104
105 id = id_open_addr((struct sockaddr *)&laddr, (struct sockaddr *)&faddr,
106 NULL);
107 if (!id)
108 {
109 if (errno)
110 {
111 int saved_errno = errno;
112
113 perror("Connection denied");
114 fflush(stderr);
115
116 errno = saved_errno;
117 syslog(LOG_DEBUG, "Error: id_open_addr(): host=%s, error=%m", hs);
118 }
119 else
120 printf("Connection denied.\r\n");
121 return 0;
122 }
123
124 fport = getport((struct sockaddr *)&faddr);
125 lport = getport((struct sockaddr *)&laddr);
126 printf("Querying for lport %d, fport %d....\r\n", lport, fport);
127 fflush(stdout);
128
129 errno = 0;
130 if (id_query(id, fport, lport, 0) < 0)
131 {
132 if (errno)
133 {
134 int saved_errno = errno;
135
136 perror("id_query()");
137 fflush(stderr);
138
139 errno = saved_errno;
140 syslog(LOG_DEBUG, "Error: id_query(): host=%s, error=%m", hs);
141
142 }
143 else
144 printf("Query failed.\r\n");
145
146 return 0;
147 }
148
149 printf("Reading response data...\r\n");
150 fflush(stdout);
151
152 res = id_parse(id, NULL, &lport, &fport, &identifier, &opsys, &charset);
153
154 switch (res)
155 {
156 default:
157 if (errno)
158 {
159 int saved_errno = errno;
160
161 perror("id_parse()");
162 errno = saved_errno;
163 syslog(LOG_DEBUG, "Error: id_parse(): host=%s, error=%m", hs);
164 }
165 else
166 printf("Error: Invalid response (empty response?).\r\n");
167 break;
168
169 case -2:
170 syslog(LOG_DEBUG, "Error: id_parse(): host=%s, Parse Error: %s", hs,
171 identifier ? identifier : "<no information available>");
172 if (identifier)
173 printf("Parse error on reply:\r\n \"%s\"\r\n", identifier);
174 else
175 printf("Unidentifiable parse error on reply.\r\n");
176 break;
177
178 case -3:
179 syslog(LOG_DEBUG, "Error: id_parse(): host=%s, Illegal reply type: %s",
180 hs, identifier);
181 printf("Parse error in reply: Illegal reply type: %s\r\n", identifier);
182 break;
183
184 case 0:
185 syslog(LOG_DEBUG, "Error: id_parse(): host=%s, NotReady", hs);
186 printf("Not ready. This should not happen...\r\n");
187 break;
188
189 case 2:
190 syslog(LOG_DEBUG, "Reply: Error: host=%s, error=%s", hs, identifier);
191
192 printf("Error response is:\r\n");
193 printf(" Lport........ %d\r\n", lport);
194 printf(" Fport........ %d\r\n", fport);
195 printf(" Error........ %s\r\n", identifier);
196 break;
197
198 case 1:
199 if (charset)
200 syslog(LOG_INFO,
201 "Reply: Userid: host=%s, opsys=%s, charset=%s, userid=%s",
202 hs, opsys, charset, identifier);
203 else
204 syslog(LOG_INFO, "Reply: Userid: host=%s, opsys=%s, userid=%s",
205 hs, opsys, identifier);
206
207 printf("Userid response is:\r\n");
208 printf(" Lport........ %d\r\n", lport);
209 printf(" Fport........ %d\r\n", fport);
210 printf(" Opsys........ %s\r\n", opsys);
211 printf(" Charset...... %s\r\n", charset ? charset : "<not specified>");
212 printf(" Identifier... %s\r\n", identifier);
213
214 if (id_query(id, getport((struct sockaddr *)&faddr),
215 getport((struct sockaddr *)&laddr), 0) >= 0)
216 {
217 if (id_parse(id, NULL,
218 &lport, &fport,
219 &identifier,
220 &opsys,
221 &charset) == 1)
222 printf(" Multiquery... Enabled\r\n");
223 }
224 }
225
226 fflush(stdout);
227 return 0;
228 }
229