1 /* $Id: ident.c 6135 2003-01-19 01:15:40Z rra $
3 ** Ident authenticator.
13 #include "inn/messages.h"
18 #define IDENT_PORT 113
20 static void out(int sig UNUSED) {
24 int main(int argc, char *argv[])
29 struct sockaddr_in *lsin, *csin;
31 struct sockaddr_storage *lss;
32 struct sockaddr_in6 *lsin6, *csin6;
36 int truncate_domain = 0;
40 int lport, cport, identport;
43 message_program_name = "ident";
45 xsignal_norestart(SIGALRM,out);
48 s = getservbyname("ident", "tcp");
50 identport = IDENT_PORT;
52 identport = ntohs(s->s_port);
54 while ((opt = getopt(argc, argv, "p:t")) != -1) {
57 for (iter = optarg; *iter; iter++)
58 if (*iter < '0' || *iter > '9')
61 /* not entirely numeric */
62 s = getservbyname(optarg, "tcp");
64 die("cannot getsrvbyname(%s, tcp)", optarg);
65 identport = s->s_port;
67 identport = atoi(optarg);
75 /* read the connection info from stdin */
76 res = get_res_info(stdin);
78 die("did not get client information from nnrpd");
81 lss = (struct sockaddr_storage *)(res->local);
82 lsin6 = (struct sockaddr_in6 *)(res->local);
83 csin6 = (struct sockaddr_in6 *)(res->client);
84 if( lss->ss_family == AF_INET6 )
86 lport = ntohs( lsin6->sin6_port );
88 cport = ntohs( csin6->sin6_port );
89 csin6->sin6_port = htons( identport );
90 sock = socket(PF_INET6, SOCK_STREAM, 0);
94 lsin = (struct sockaddr_in *)(res->local);
95 lport = htons( lsin->sin_port );
97 csin = (struct sockaddr_in *)(res->client);
98 cport = htons( csin->sin_port );
99 csin->sin_port = htons( identport );
100 sock = socket(PF_INET, SOCK_STREAM, 0);
103 sysdie("cannot create socket");
104 if (bind(sock, res->local, SA_LEN(res->local)) < 0)
105 sysdie("cannot bind socket");
106 if (connect(sock, res->client, SA_LEN(res->local)) < 0) {
107 if (errno != ECONNREFUSED)
108 sysdie("cannot connect to ident server");
110 sysdie("client host does not accept ident connections");
114 /* send the request out */
115 snprintf(buf, sizeof(buf), "%d , %d\r\n", cport, lport);
116 opt = xwrite(sock, buf, strlen(buf));
118 sysdie("cannot write to ident server");
120 /* get the answer back */
123 opt = read(sock, buf+got, sizeof(buf)-got);
125 sysdie("cannot read from ident server");
127 die("end of file from ident server before response");
129 if (buf[got] != '\n')
131 } while (buf[got] != '\n');
133 if (buf[got-1] == '\r')
136 /* buf now contains the entire ident response. */
137 if (!(iter = strchr(buf, ':')))
138 /* malformed response */
139 die("malformed response \"%s\" from ident server", buf);
142 while (*iter && ISWHITE(*iter))
145 while (*endstr && *endstr != ':' && !ISWHITE(*endstr))
148 /* malformed response */
149 die("malformed response \"%s\" from ident server", buf);
150 if (*endstr != ':') {
152 while (*endstr != ':')
158 if (strcmp(iter, "ERROR") == 0)
159 die("ident server reported an error");
160 else if (strcmp(iter, "USERID") != 0)
161 die("ident server returned \"%s\", not USERID", iter);
163 /* skip the operating system */
164 if (!(iter = strchr(endstr+1, ':')))
167 /* everything else is username */
169 while (*iter && ISWHITE(*iter))
171 if (!*iter || *iter == '[')
172 /* null, or encrypted response */
173 die("ident response is null or encrypted");
174 if ((truncate_domain == 1) && ((p = strchr(iter, '@')) != NULL))
176 printf("User:%s\n", iter);