forked from mdornseif/didentd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
didentd.c
187 lines (152 loc) · 4.94 KB
/
didentd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* $Id: didentd.c,v 1.9 2001/10/15 00:27:22 drt Exp $
* --drt@un.bewaff.net - http://c0re.jp/c0de/didentd/
*
* core for an ident server
*/
#include <unistd.h> /* for close */
#include <pwd.h> /* for getpwuid */
#include <stdlib.h> /* for random() */
#include <time.h> /* time */
#include "buffer.h"
#include "env.h"
#include "fmt.h"
#include "getln.h"
#include "ip4.h"
#include "ip6.h"
#include "scan.h"
#include "str.h"
#include "stralloc.h"
#include "strerr.h"
#include "timeoutread.h"
#include "uint16.h"
#include "uint32.h"
static char rcsid[] = "$Id: didentd.c,v 1.9 2001/10/15 00:27:22 drt Exp $";
/* returns a pointer to a string describing a problem or "ok" if
sucessfull, adds to stralloc *answer the part after the ports of an
RfC 1413 reply */
extern char *generate_answer(stralloc *answer, unsigned long uid,
char *lip, uint16 lport, char *rip, uint16 rport);
/* returns the uid asociated with the IPv4 connection defined by
lip, rip, lport, rport or 0xffffffff if unsucessfull */
uint32 get_connection_info4(char *lip, uint16 lport, char *rip, uint16 rport);
/* returns the uid asociated with the IPv6 connection defined by
lip, rip, lport, rport or 0xffffffff if unsucessfull */
uint32 get_connection_info6(char *lip, uint16 lport, char *rip, uint16 rport);
/* server specific initialisation */
extern void didentd_init();
#define stderr 2
#define stdout 1
#define stdin 0
#define FATAL "didentd: fatal: "
int main()
{
unsigned char *remotehost, *remoteip, *remoteport, *localip, *localport;
unsigned char query[256] = {0};
uint32 uid = 0xffffffff; // that's our default for "not found"
int query_len = 0;
int pos = 0;
char *problem = "ok";
stralloc answer = {0};
char strnum[FMT_ULONG];
int proto = 0;
char *x;
char lip[16] = {0};
char rip[16] = {0};
uint16 lport = 0;
uint16 rport = 0;
didentd_init();
x = env_get("PROTO");
if(x)
{
if(str_equal(x, "TCP")) proto = 4;
if(str_equal(x, "TCP6")) proto = 6;
}
if(proto == 0)
{
buffer_puts(buffer_2, "warning: can't determine $PROTO\n");
buffer_flush(buffer_2);
}
srandom(((long long) getpid () *
(long long) time(0) *
(long long) getppid() *
(long long) random() *
(long long) clock()) % 0xffffffff);
/* since we run under tcpserver, we can get all info
about the remote side from the enviroment */
remotehost = env_get("TCPREMOTEHOST");
if (!remotehost) remotehost = "unknown";
remoteport = env_get("TCPREMOTEPORT");
if (remoteport) scan_ushort(remoteport, &rport); else remoteport = "0";
localport = env_get("TCPLOCALPORT");
if (localport) scan_ushort(localport, &lport); else localport = "0";
remoteip = env_get("TCPREMOTEIP");
if (!remoteip) remoteip = "0.0.0.0";
localip = env_get("TCPLOCALIP");
if (!localip) localip = "0.0.0.0";
if(proto == 4)
{
if(remoteip)
ip4_scan(remoteip, rip);
if(localip)
ip4_scan(localip, lip);
/* seed some entropy into the by IPv4 unsused bytes */
rip[5] = (char) random() & 0xff;
rip[6] = (char) random() & 0xff;
}
if(proto == 6)
{
if (remoteip)
ip6_scan(remoteip, rip);
if (localip)
ip6_scan(localip, lip);
}
/* Read the request from the client and \0-terminate it */
/* timeout after 60 seconds */
query_len = timeoutread(60, stdin, query, sizeof(query) - 1);
query[query_len] = '\0';
/* If there was any data we can go on */
problem = "empty query";
if (query_len > 0)
{
problem = "illegal query";
pos = scan_ushort(query, &lport);
if(query[pos++] == ' ')
if(query[pos++] == ',')
if(query[pos++] == ' ')
{
pos = scan_ushort(&query[pos], &rport);
problem = "ok";
if(proto == 4)
uid = get_connection_info4(lip, lport, rip, rport);
if(proto == 6)
uid = get_connection_info6(lip, lport, rip, rport);
stralloc_copyb(&answer, strnum, fmt_ulong(strnum, lport));
stralloc_cats(&answer, " , ");
stralloc_catb(&answer, strnum, fmt_ulong(strnum, rport));
if(uid != 0xffffffff)
problem = generate_answer(&answer, uid, lip, lport, rip, rport);
else
generate_answer(&answer, uid, lip, lport, rip, rport);
buffer_puts(buffer_1, answer.s);
buffer_flush(buffer_1);
}
}
/* Do logging */
buffer_puts(buffer_2, localip);
buffer_puts(buffer_2, ":");
buffer_put(buffer_2, strnum, fmt_ulong(strnum, lport));
buffer_puts(buffer_2, " -> ");
buffer_puts(buffer_2, remoteip);
buffer_puts(buffer_2, ":");
buffer_put(buffer_2, strnum, fmt_ulong(strnum, rport));
buffer_puts(buffer_2, " [");
buffer_puts(buffer_2, problem);
buffer_puts(buffer_2, "] ");
if(uid < 0xffffffff)
buffer_put(buffer_2, strnum, fmt_ulong(strnum,uid));
else
buffer_puts(buffer_2, "unknown");
buffer_puts(buffer_2, "\n");
buffer_flush(buffer_2);
return 0;
}