View | Details | Raw Unified | Return to bug 240175
Collapse All | Expand All

(-)security/fakeident/Makefile (-4 / +4 lines)
Lines 2-9 Link Here
2
# $FreeBSD$
2
# $FreeBSD$
3
3
4
PORTNAME=	fakeident
4
PORTNAME=	fakeident
5
PORTVERSION=	1.7
5
PORTVERSION=	2.7
6
PORTREVISION=	3
7
CATEGORIES=	security
6
CATEGORIES=	security
8
MASTER_SITES=	# empty
7
MASTER_SITES=	# empty
9
DISTFILES=	# empty
8
DISTFILES=	# empty
Lines 15-25 Link Here
15
LICENSE=	GPLv2+
14
LICENSE=	GPLv2+
16
15
17
PLIST_FILES=	sbin/identd
16
PLIST_FILES=	sbin/identd
17
18
USE_RC_SUBR=	fakeidentd
18
USE_RC_SUBR=	fakeidentd
19
19
20
do-build:
20
do-build:
21
	@${MKDIR} ${WRKSRC}
21
	@${MKDIR} ${WRKSRC} && ${CP} ${FILESDIR}/identd.c ${WRKSRC}
22
	${CC} ${CFLAGS} -o ${WRKSRC}/identd ${FILESDIR}/identd.c
22
	cd ${WRKSRC} && ${SH} identd.c CC=${CC} ${CFLAGS}
23
23
24
do-install:
24
do-install:
25
	${INSTALL_PROGRAM} ${WRKSRC}/identd ${STAGEDIR}${PREFIX}/sbin
25
	${INSTALL_PROGRAM} ${WRKSRC}/identd ${STAGEDIR}${PREFIX}/sbin
(-)security/fakeident/files/fakeidentd.in (-1 / +2 lines)
Lines 17-22 Link Here
17
# The username does not need to exist anywhere in your system.
17
# The username does not need to exist anywhere in your system.
18
18
19
name=fakeidentd
19
name=fakeidentd
20
desc="Standalone 'fake' ident daemon"
20
rcvar=fakeidentd_enable
21
rcvar=fakeidentd_enable
21
22
22
load_rc_config $name
23
load_rc_config $name
Lines 23-29 Link Here
23
24
24
: ${fakeidentd_enable:="NO"}
25
: ${fakeidentd_enable:="NO"}
25
26
26
command=%%PREFIX%%/sbin/identd
27
command="%%PREFIX%%/sbin/identd"
27
pidfile=/var/run/identd.pid
28
pidfile=/var/run/identd.pid
28
29
29
command_args="nobody && echo -n ' fakeidentd'"
30
command_args="nobody && echo -n ' fakeidentd'"
(-)security/fakeident/files/identd.c (-424 / +522 lines)
Lines 1-26 Link Here
1
#if 0 /*
1
#if 0 /* -*-  mode: c; c-file-style: "gnu"; tab-width: 8; -*-
2
#	This program is easy to compile. For example the following ways:
3
#		$ sh identd.c
4
#		$ sh identd.c -g -DDEBUG
5
#		$ sh identd.c -s -DXXXMULTI
6
#		$ CC=cc sh identd.c
7
#		$ CC=egcs sh identd.c -s -fomit-frame-pointer
8
2
9
NAME=`basename $0 .c`
3
#   This program is easy to compile. For example the following ways:
10
[ x`uname` = xSunOS ] && L="-lsocket -lnsl" || L=
4
#       $ sh identd.c
11
[ x$1 = x ] && set -- -s -O2
5
#       $ sh identd.c -g -DDEBUG
12
CMDLINE="${CC:-gcc} -Wall $@ -o $NAME $NAME.c $L"
6
#       $ sh identd.c -s -DXXXMULTI
13
echo $CMDLINE; exec $CMDLINE; exit -1
7
#       $ sh identd.c TRG=fake_identd -s -DBIND_ADDRESS=127.0.0.1
8
#       $ sh identd.c CC=cc
9
#       $ sh identd.c CC=egcs -s -fomit-frame-pointer
14
10
11
set -eu
12
13
CC= TRG=`basename "$0" .c` OIFS=$IFS
14
for arg in "$@" ''
15
do case $arg in	TRG=*) TRG=`echo "$arg" | sed 's/TRG=//'`; shift ;;
16
		CC=*) CC=`echo "$arg" | sed 's/CC=//'`; shift ;;
17
		clean) set -x; exec rm -f "$TRG" ;;
18
		readme) set -x; exec sed -n '1,/[e]nd/d;/\*\//q;s/..//p' "$0";;
19
		'') set 0 -s -O2; shift; break ;;
20
		*) break ;;
21
esac; done
22
case `uname` in SunOS) L='-lsocket -lnsl' ;; *) L= ;; esac
23
24
WARN="-Wall -Wstrict-prototypes -pedantic -Wno-long-long"
25
WARN="$WARN -Wcast-align -Wpointer-arith " # -Wfloat-equal #-Werror
26
WARN="$WARN -W -Wwrite-strings -Wcast-qual -Wshadow" # -Wconversion
27
28
VERSION=`sed -n '/^ [*] Version / {
29
	s/.*Version \([^ ]*\)  *\([^ ]*\).*./\1 (\2)/p; q; }' "$0"`
30
case $VERSION in '') echo Could not read version information. >&2; exit 1; esac
31
TRGNAME=`basename "$TRG"`
32
set -x; exec ${CC:-gcc} $WARN "$@" -DTRG="\"$TRGNAME\"" \
33
	-DVERSION="\"$VERSION\"" -o "$TRG" "$0" $L
34
exit 1
15
# */
35
# */
16
#endif
36
#endif
17
/*
37
/*
18
 * $Id: identd.c,v 1.7 2002/09/29 07:50:20 too Stab $
38
 * identd.c 2.6  2012-05-31 20:37:27 UTC
19
 *
39
 *
20
 * Author: Tomi Ollila <too@iki.fi>
40
 * Author: Tomi Ollila -- too ät iki fi
21
 *
41
 *
22
 * Created: Sat Nov 25 15:34:07 1995 too
42
 * Created: Sat Nov 25 15:34:07 EET 1995 too
23
 * Last modified: Sun Sep 29 10:48:42 2002 too
43
 * Last modified: Thu 31 May 2012 23:37:27 EEST too
24
 *
44
 *
25
 * This program is standalone 'fake' ident daemon. This program does
45
 * This program is standalone 'fake' ident daemon. This program does
26
 * not fork() but is configured to handle up to 20 concurrent connections.
46
 * not fork() but is configured to handle up to 20 concurrent connections.
Lines 28-34 Link Here
28
 * in use, the next connection will close the oldest connection data
48
 * in use, the next connection will close the oldest connection data
29
 * has been read. This way this program is not very vulnerable to so
49
 * has been read. This way this program is not very vulnerable to so
30
 * called `denial of service' attack, thus making this ideal "identd"
50
 * called `denial of service' attack, thus making this ideal "identd"
31
 * to be used in a firewall.
51
 * to be used in a firewall, IP masquerading hosts etc.
32
 *
52
 *
33
 * Program takes one (or many) arguments, which if exist, determines the
53
 * Program takes one (or many) arguments, which if exist, determines the
34
 * `user' name(s) that is returned for successful ident query.
54
 * `user' name(s) that is returned for successful ident query.
Lines 44-60 Link Here
44
 * GNU General Public License for more details.
64
 * GNU General Public License for more details.
45
 *
65
 *
46
 * HISTORY
66
 * HISTORY
47
 * $Log: identd.c,v $
48
 *
67
 *
68
 * Version 2.6  2012-05-31 20:37:27 UTC
69
 *   Applied patches from the wl500g project, including IPv6 support, with
70
 *   minor tweaks (patches provided by Daniel Gimpelevich. Thanks).
71
 *
72
 * Version 2.5  $Id: identd.c 862 2006-05-18 14:16:34Z too $
73
 *   Minor build and readme updates.
74
 *
75
 * Version 2.4  identd.c 568 2005-09-07 20:18:39Z too
76
 *   More compilation warnings options set -- iov.base being non-const
77
 *   gives warnings that are hard to avoid...
78
 *
79
 * Version 2.3  identd.c 564 2005-09-06 19:15:20Z too
80
 *   Randident code from  Matthias Jung  tuned in.
81
 *
82
 * Version 2.2  identd.c 12 2004-09-08 21:46:54Z too
83
 *   Fixed getservbyname() to look port for "auth" instead of "identd"
84
 *   port. This "bug" also revealed port number byte order handling bug,
85
 *   which was fixed.
86
 *   Now this file is stored in subversion repository -- I entered
87
 *   $ svn propset svn:keywords Id identd.c -- let's see how it works...
88
 *   ... ``svn propset svn:keywords 'Id Rev' identd.c'' !!!
89
 *
90
 * Revision 2.1  2004/01/15 18:14:42  too
91
 *   Made BIND_ADDRESS definable (in compiler command line).
92
 *   Added some typecasts (using checked_cast() macro).
93
 *   Thanks to Jeffrey D. Wheelhouse for his content.
94
 *
95
 * Revision 2.0  2003/05/05 15:21:01  too
96
 *   Major update. Removed fdprintf(); replaced with use of
97
 *   writev() and newly added outputstrings().
98
 *   Removed many now obsolete defines and converted one to
99
 *   constant character string.
100
 *   Added one assert() (and left room for more). Did some
101
 *   relativily small other adjustments.
102
 *
49
 * Revision 1.7  2002/09/29 07:50:20  too
103
 * Revision 1.7  2002/09/29 07:50:20  too
50
 *   No longer chops up to IDSTR_MAX chars, but uses "%.*s" to limit length;
104
 *   No longer chops up to IDSTR_MAX chars, but uses "%.*s" to limit length;
51
 *	now works also when XXXMULTI defined.
105
 *   now works also when XXXMULTI defined.
52
 *   Back-hacked self-compilable trick, with more tricks to avoid compiler
106
 *   Back-hacked self-compilable trick, with more tricks to avoid compiler
53
 *	warnings.
107
 *   warnings.
54
 *   Removed own define of FD_SETSIZE altogether;
108
 *   Removed own define of FD_SETSIZE altogether;
55
 *	systems has it small to begin with.
109
 *   systems has it small to begin with.
56
 *   Line '415' (or whatever that is now) fixed. () -> (void) in func def.
110
 *   Line '415' (or whatever that is now) fixed. () -> (void) in func def.
57
 *   Some fine tuning.
111
 *   Some fine-tuning.
58
 *   Thanks to Cristian for his patches.
112
 *   Thanks to Cristian for his patches.
59
 *
113
 *
60
 * Revision 1.6.1  2002-09-28 12:30:29 +0200  cii
114
 * Revision 1.6.1  2002-09-28 12:30:29 +0200  cii
Lines 83-122 Link Here
83
 *   + added IDENT_SUBSTR
137
 *   + added IDENT_SUBSTR
84
 *
138
 *
85
 * Revision 1.6  2002/07/31 16:25:20  too
139
 * Revision 1.6  2002/07/31 16:25:20  too
86
 * Now works when started as root (in Linux). Stupid me, tested
140
 *   Now works when started as root (in Linux). Stupid me, tested
87
 * only starting as an ordinary loser.
141
 *   only starting as an ordinary loser.
88
 *
142
 *
89
 * Revision 1.5  2002/07/29 14:02:42  too
143
 * Revision 1.5  2002/07/29 14:02:42  too
90
 * Added possibility to have multible reply users, one (pseudo)randomly
144
 *   Added possibility to have multible reply users, one (pseudo)randomly
91
 * chosen at each time.
145
 *   chosen at each time.
92
 *
146
 *
93
 * Revision 1.4  2001/02/09 08:45:42  too
147
 * Revision 1.4  2001/02/09 08:45:42  too
94
 * Now GID is also changed to nobody/nogroup.
148
 *   Now GID is also changed to nobody/nogroup.
95
 *
149
 *
96
 * Revision 1.3  2000/06/07 05:55:44  too
150
 * Revision 1.3  2000/06/07 05:55:44  too
97
 * Fixed some Solaris compilation "bugs".
151
 *   Fixed some Solaris compilation "bugs".
98
 * Changed LOG_PERROR to LOG_CONS
152
 *   Changed LOG_PERROR to LOG_CONS
99
 *
153
 *
100
 * Revision 1.2  1999/07/30 04:08:42  too
154
 * Revision 1.2  1999/07/30 04:08:42  too
101
 * Added printing version string (and exit) with `-V' command line option.
155
 *   Added printing version string (and exit) with `-V' command line option.
102
 *
156
 *
103
 * Revision 1.1  1999/04/21 17:23:20  too
157
 * Revision 1.1  1999/04/21 17:23:20  too
104
 * - Writes process id to /var/run/identd.pid.
158
 * - Writes process id to /var/run/identd.pid.
105
 * - Changes (effective) user id to `nobody' after initialization
159
 * - Changes (effective) user id to `nobody' after initialization
106
 *	(binding socket etc.).
160
 *      (binding socket etc.).
107
 * - Ignores some signals (HUP and PIPE).
161
 * - Ignores some signals (HUP and PIPE).
108
 * - Handles some signals that aborts by default. The handler function
162
 * - Handles some signals that aborts by default. The handler function
109
 *	tries to get rid of the pidfile.
163
 *      tries to get rid of the pidfile.
110
 *
164
 *
111
 * Revision 0.9b 1999/04/15 20:45:12  too
165
 * Revision 0.9b 1999/04/15 20:45:12  too
112
 * Not so much spaghetti anymore. Added documentation and more replies.
166
 *   Not so much spaghetti anymore. Added documentation and more replies.
113
 *
167
 *
114
 * Revision 0.9  1999/04/12 18:30:00  too
168
 * Revision 0.9  1999/04/12 18:30:00  too
115
 * Version for unix systems. Standalone, supports 20 concurrent connections.
169
 *   Version for unix systems. Standalone, supports 20 concurrent connections.
116
 * The code is quite a spaghetti. But that does not matter.
170
 *   The code is quite a spaghetti. But that does not matter.
117
 *
118
 */
171
 */
119
172
173
#ifdef DEBUG
174
#undef ndebug
175
#else
176
#define ndebug 1
177
#endif
178
179
#include <assert.h>
120
#include <unistd.h>
180
#include <unistd.h>
121
#include <stdio.h>
181
#include <stdio.h>
122
#include <stdlib.h>
182
#include <stdlib.h>
Lines 136-162 Link Here
136
#include <sys/socket.h>
196
#include <sys/socket.h>
137
#include <netinet/in.h>
197
#include <netinet/in.h>
138
#include <errno.h>
198
#include <errno.h>
199
#include <arpa/inet.h>
200
#include <sys/uio.h>
139
201
202
#include <sys/endian.h>
140
203
204
#if __BYTE_ORDER == __BIG_ENDIAN
205
206
#define IPADDR(a,b,c,d) ((in_addr_t)((a << 24) + (b << 16) + (c << 8) + d))
207
#define IPPORT(v) ((in_port_t)v)
208
#define A_x_256(a)((a<<8))
209
210
#elif __BYTE_ORDER == __LITTLE_ENDIAN
211
212
#define IPADDR(a,b,c,d) (a + (b << 8) + (c << 16) + (d << 24))
213
#define IPPORT(v) ((in_port_t)((v >> 8) | (v << 8)))
214
#define A_x_256(a) (a)
215
216
#else
217
#error unknown ENDIAN
218
#endif
219
220
#ifndef __STRING
221
#define __STRING(x) #x
222
#endif
223
/* Let's see how long-lived this is... */
224
#define __STRINGIFY_MACRO(x) __STRING(x)
225
226
#ifndef BIND_ADDRESS
227
#define BIND_ADDRESS	0.0.0.0
228
#endif
229
#ifndef BIND_ADDRESS6
230
#define BIND_ADDRESS6	::
231
#endif
141
#define IDENT_PORT	113
232
#define IDENT_PORT	113
142
#define IDENT_SUBSTR	": USERID : UNIX :"
143
#define MAXCONNS	20
233
#define MAXCONNS	20
144
#define MAXIDLETIME	45
234
#define MAXIDLETIME	45
145
#define IDSTR_BUFLEN	128 /*could be dropped down to 64 if tight in memory */
146
235
147
/*
236
#ifndef USE_UNIX_OS
148
 * format string is: "%d, %d " IDENT_SUBSTR " %.*s\r\n"
237
static const char ident_substr[] = " : USERID : OTHER : ";
149
 * %d is max 999999999 (allowed by this identd, 
238
#else
150
 */
239
static const char ident_substr[] = " : USERID : UNIX : ";
151
#define IDSTR_MAX	(IDSTR_BUFLEN - 1) - \
240
#endif
152
	9 - 2 - 9 - 1 - (sizeof IDENT_SUBSTR - 1) - 1 - 2
241
static const int ident_substr_len = sizeof ident_substr - 1;
153
242
243
#if !defined __cplusplus
244
typedef enum { false = 0, true = 1 } bool;
245
#endif
246
247
#if (__GNUC__ >= 3)
248
#define GCCATTR_UNUSED	 __attribute ((unused))
249
250
#define from_type(ft, v) \
251
  __builtin_choose_expr (__builtin_types_compatible_p (typeof (v), ft), \
252
			 (v), (void)0)
253
254
#define checked_cast(ft, tt, v) \
255
  __builtin_choose_expr (__builtin_types_compatible_p (typeof (v), ft), \
256
			 ((tt)(v)), (void)0)
257
#else
258
#define GCCATTR_UNUSED
259
260
#define from_type(ft, v) (v)
261
#define checked_cast(ft, tt, v) ((tt)(v))
262
#endif
263
264
/* ... */
265
#define CVP (const void *)
266
154
#ifndef DEBUG
267
#ifndef DEBUG
155
#define FCS		2	/* First Connection Socket */
268
#define FCS		2	/* First Connection Socket */
156
#define TRACE(x);
269
#define TRACE(x, y);
157
#else
270
#else
158
#define FCS		4
271
#define FCS		4
159
#define TRACE(x)	printf x
272
#define TRACE(x, y)	if (x) printf y
160
#endif
273
#endif
161
274
162
/* descriptors when debugging:
275
/* descriptors when debugging:
Lines 163-169 Link Here
163
 *  0 = server socket
276
 *  0 = server socket
164
 *  1 = standard output (debugging output)
277
 *  1 = standard output (debugging output)
165
 *  2 = standard error
278
 *  2 = standard error
166
 *  3 = syslog fd (hopefully -- otherwise this won't work)
279
 *  3 = syslog fd (hopefully -- otherwise may work a bit wierdly)
167
 *  4 - 4 + MAXCONNS = connection sockets
280
 *  4 - 4 + MAXCONNS = connection sockets
168
 *
281
 *
169
 * descriptors when not debugging
282
 * descriptors when not debugging
Lines 171-176 Link Here
171
 *  1 = syslog fd (hopefully -- otherwise this won't work)
284
 *  1 = syslog fd (hopefully -- otherwise this won't work)
172
 *  2 = connection socket after detached from tty. standard error before that
285
 *  2 = connection socket after detached from tty. standard error before that
173
 *  3 - 2 + MAXCONNS = rest connection sockets
286
 *  3 - 2 + MAXCONNS = rest connection sockets
287
 *
288
 * To try to make sure that syslog fd is what is "requested", the that fd
289
 * is closed before openlog() call. It can only severely fail if fd 0
290
 * is initially closed.
174
 */
291
 */
175
292
176
/*
293
/*
Lines 191-201 Link Here
191
 * XXX NOTE: multi currently only slightly tested XXXX.
308
 * XXX NOTE: multi currently only slightly tested XXXX.
192
 */
309
 */
193
#ifdef XXXMULTI
310
#ifdef XXXMULTI
194
#define IU_IN_STRUCT char ** identuserlist; int identusers
311
#define IU_IN_STRUCT const char * const * identuserlist; int identusers
195
#define SET_IU(s, c) do { G.identuserlist = &(s); G.identusers = c; } while (0)
312
#define SET_IU(s, c) do { G.identuserlist = &(s); G.identusers = c; } while (0)
196
#define IU_IN_USAGESTR "[identuser [identuser2...]]"
313
#define IU_IN_USAGESTR "[identuser [identuser2...]]"
197
#else
314
#else
198
#define IU_IN_STRUCT char * identuser
315
#define IU_IN_STRUCT const char * identuser
199
#define SET_IU(s, c) G.identuser = (s)
316
#define SET_IU(s, c) G.identuser = (s)
200
#define IU_IN_USAGESTR "[identuser]"
317
#define IU_IN_USAGESTR "[identuser]"
201
#endif
318
#endif
Lines 205-273 Link Here
205
  IU_IN_STRUCT;
322
  IU_IN_STRUCT;
206
  fd_set	readfds;
323
  fd_set	readfds;
207
  int		conncnt;
324
  int		conncnt;
325
  bool		randident;
208
} G;
326
} G;
209
327
210
static const char rcs_id[] =
211
/* */ "$Id: identd.c,v 1.7 2002/09/29 07:50:20 too Stab $";
212
213
214
/*
328
/*
215
 * Prototypes
329
 * Prototypes
216
 */
330
 */
217
static void reply(int s, char * buf);
331
static void reply(int s, char * buf);
218
static void replyError(int s, char * buf);
332
static void replyError(int s, const char * buf);
219
static const char * strerrno(void);
333
static const char * strerrno(void);
220
334
221
const int one = 1;
335
static const int one = 1;
222
char *	  nobodystr = "nobody";
336
static const char * const nobodystr = "nobody";
337
static const char * alphanum =
338
  "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
223
339
224
/* a more general name would be `movefd',but we are only moving sockets here */
340
static inline void movefd(int from, int to)
225
static inline void movesocket(int from, int to)
226
{
341
{
227
  TRACE(("movesocket(from = %d, to = %d)\n", from, to));
342
  TRACE(1, ("movefd(from = %d, to = %d)\n", from, to));
228
  dup2(from, to);
343
  if (from != to)
229
  close(from);
344
    {
345
      dup2(from, to);
346
      close(from);
347
    }
230
}
348
}
231
349
232
/*
350
/*
233
 * inetbind() must always return 0 or value < 0.
351
 * inetbind() must always return 0 or value < 0.
352
 * ... i.e. this version -- saves need for storage of the return value.
234
 */
353
 */
354
355
#if 0 /* unused */
235
static int inetbind(int port)
356
static int inetbind(int port)
236
{
357
{
237
  int			s;
358
  return inetbind(htons(port));
238
  struct sockaddr_in	addr = { 0 };
359
}
239
  int			len = sizeof addr;
360
#endif
240
  
361
362
static int inetbind(int ipport)
363
{
364
  int s, len;
365
  union {
366
    struct sockaddr_in	sin4;
367
    struct sockaddr_in6 sin6;
368
  } addr;
369
241
  close(0);
370
  close(0);
242
  
371
  memset(&addr, 0, sizeof addr);
243
  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
372
244
  {
373
  if ((s = socket(AF_INET6, SOCK_STREAM, 0)) >= 0)
245
      syslog(LOG_CRIT, "cannot create server socket: %s.", strerrno());
374
    {
375
      len = sizeof addr.sin6;
376
      inet_pton(AF_INET6, __STRINGIFY_MACRO(BIND_ADDRESS6), &addr.sin6.sin6_addr);
377
      addr.sin6.sin6_family = AF_INET6;
378
      addr.sin6.sin6_port = ipport;
379
    }
380
  else
381
  if ((s = socket(AF_INET, SOCK_STREAM, 0)) >= 0)
382
    {
383
      len = sizeof addr.sin4;
384
      addr.sin4.sin_addr.s_addr = inet_addr(__STRINGIFY_MACRO(BIND_ADDRESS));
385
      addr.sin4.sin_family = AF_INET;
386
      addr.sin4.sin_port = ipport;
387
    }
388
  else
389
    {
390
      syslog(LOG_CRIT, "Can not create server socket: %s.", strerrno());
246
      return -1;
391
      return -1;
247
  }
392
    }
248
  
393
249
  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
394
  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
250
  
395
251
  addr.sin_family = AF_INET;
252
  addr.sin_port = htons(port);
253
  
254
  if (bind(s, (struct sockaddr *)&addr, len) < 0)
396
  if (bind(s, (struct sockaddr *)&addr, len) < 0)
255
  {
397
    {
256
      syslog(LOG_CRIT, "cannot bind() server socket: %s.", strerrno());
398
      syslog(LOG_CRIT, "Can not bind() server socket: %s.", strerrno());
257
      return -1;
399
      return -1;
258
  }
400
    }
259
  
401
260
  if (listen(s, 5) < 0)
402
  if (listen(s, 5) < 0)
261
  {
403
    {
262
      syslog(LOG_CRIT, "cannot listen() server socket: %s.", strerrno());
404
      syslog(LOG_CRIT, "Can not listen() server socket: %s.", strerrno());
263
      return -1;
405
      return -1;
264
  }
406
    }
265
  
407
266
  if (s != 0)
408
  movefd(s, 0);
267
  {
409
268
      movesocket(s, 0);
269
  }
270
  
271
  return 0;
410
  return 0;
272
}
411
}
273
412
Lines 274-286 Link Here
274
static void deleteConn(int s)
413
static void deleteConn(int s)
275
{
414
{
276
  int i = s - FCS;
415
  int i = s - FCS;
277
  
416
278
  TRACE(("deleteConn(): socket %d, conncnt %d\n", s, G.conncnt));
417
  TRACE(1, ("deleteConn(): socket %d, conncnt %d\n", s, G.conncnt));
279
  
418
280
  close(s);
419
  close(s);
281
  
420
282
  G.conncnt--;
421
  G.conncnt--;
283
  
422
284
  /*
423
  /*
285
   * Most of the time there is 0 connections. Most often that there
424
   * Most of the time there is 0 connections. Most often that there
286
   * is connections, there is just one connection. When this one connection
425
   * is connections, there is just one connection. When this one connection
Lines 294-307 Link Here
294
   * to be copied over the time all these connections are deleted.
433
   * to be copied over the time all these connections are deleted.
295
   */
434
   */
296
  if (i != G.conncnt)
435
  if (i != G.conncnt)
297
  {
436
    {
298
      memcpy(&conns[i], &conns[G.conncnt], sizeof conns[0]);
437
      memcpy(&conns[i], &conns[G.conncnt], sizeof conns[0]);
299
      movesocket(G.conncnt + FCS, s);
438
      movefd(G.conncnt + FCS, s);
300
  }
439
    }
301
  
440
302
  TRACE(("Clearing fd %d, readfds now 0x%x\n\n",
441
  TRACE(1, ("Clearing fd %d, readfds now 0x%x\n\n",
303
	 G.conncnt + FCS, *(int *)&G.readfds));
442
	    G.conncnt + FCS, *(int *)&G.readfds));
304
  
443
305
  FD_CLR(G.conncnt + FCS, &G.readfds);
444
  FD_CLR(G.conncnt + FCS, &G.readfds);
306
}
445
}
307
446
Lines 310-344 Link Here
310
  time_t min = conns[0].lasttime;
449
  time_t min = conns[0].lasttime;
311
  int	 idx = 0;
450
  int	 idx = 0;
312
  int	 i;
451
  int	 i;
313
  
452
314
  for (i = 1; i < MAXCONNS; i++)
453
  for (i = 1; i < MAXCONNS; i++)
315
  {
454
    if (conns[i].lasttime < min)
316
      if (conns[i].lasttime < min)
455
      idx = i;
317
      {
456
318
	  idx = i;
457
  TRACE(1, ("closeOldest(): index %d, socket %d\n", idx, idx + FCS));
319
      }
458
320
  }
321
  TRACE(("closeOldest(): index %d, socket %d\n", idx, idx + FCS));
322
  
323
  replyError(idx + FCS, "X-SERVER-TOO-BUSY");
459
  replyError(idx + FCS, "X-SERVER-TOO-BUSY");
324
  close(idx + FCS);
460
  close(idx + FCS);
325
  
461
326
  return idx;
462
  return idx;
327
}
463
}
328
464
329
465
330
static inline int checkInput(char * buf, int len, int l)
466
static int checkInput(char * buf, int len, int l)
331
{
467
{
332
  int	i;
468
  int	i;
333
  
469
334
  for (i = len; i < len + l; i++)
470
  for (i = len; i < len + l; i++)
335
  {
471
    if (buf[i] == '\n')
336
      if (buf[i] == '\n')
472
      return 1;
337
      {
473
338
	  return 1;
339
      }
340
  }
341
  
342
  return 0;
474
  return 0;
343
}
475
}
344
476
Lines 346-402 Link Here
346
static int getport(void)
478
static int getport(void)
347
{
479
{
348
  struct servent * se;
480
  struct servent * se;
349
  
481
350
  if ((se = getservbyname("identd", "tcp")) == NULL)
482
  if ((se = getservbyname("auth", "tcp")) == NULL)
351
  {
483
    return IPPORT(IDENT_PORT);
352
      return IDENT_PORT;
353
  }
354
  else
484
  else
355
  {
485
    return se->s_port;
356
      return se->s_port;
357
  }
358
}
486
}
359
487
360
static const char * strerrno()
488
static const char * strerrno()
361
{
489
{
490
#if 1
491
  return strerror(errno);
492
#else
493
  extern char * sys_errlist[];
362
  return sys_errlist[errno];
494
  return sys_errlist[errno];
495
#endif
363
}
496
}
364
497
365
/* here we trust no-one in this program overflows our data buffer. */
498
#define WriteCS(f, s) write(f, s, sizeof s - 1)
366
static void fdprintf(int fd, char * format, ...)
499
500
static void writestrings(int fd, const char * str, ...)
367
{
501
{
368
  va_list	ap;
502
  va_list ap;
369
  char		buf[IDSTR_BUFLEN];
503
370
  
504
  va_start(ap, str);
371
  va_start(ap, format);
505
372
  vsprintf(buf, format, ap);
506
  while (str)
507
    {
508
      write(fd, str, strlen(str));
509
      str = va_arg(ap, const char *);
510
    }
373
  va_end(ap);
511
  va_end(ap);
374
  
375
  write(fd, buf, strlen(buf));
376
}
512
}
377
513
378
379
#ifndef DEBUG
514
#ifndef DEBUG
380
static void godaemon(void)
515
static void godaemon(void)
381
{
516
{
382
  switch(fork())
517
  switch(fork())
383
  {
518
    {
384
  case -1:
519
    case -1:	exit(-1);
385
    exit(-1);
520
    case 0:	close(1); close(2); setsid();  break;
386
    
521
    default:	exit(0);
387
  case 0:
522
    }
388
    close(1);
389
    close(2);
390
    setsid();
391
    break;
392
    
393
  default:
394
    exit(0);
395
  }
396
}
523
}
397
#endif
524
#endif
398
525
526
#ifdef TRG
527
#define PIDFILE "/var/run/" TRG ".pid"
528
#else
399
#define PIDFILE "/var/run/identd.pid"
529
#define PIDFILE "/var/run/identd.pid"
530
#endif
400
531
401
static void delpidfile(void)
532
static void delpidfile(void)
402
{
533
{
Lines 405-413 Link Here
405
   * therefore if file cannot be deleted, it is truncated
536
   * therefore if file cannot be deleted, it is truncated
406
   */
537
   */
407
  if (unlink(PIDFILE) < 0)
538
  if (unlink(PIDFILE) < 0)
408
  {
539
    close(open(PIDFILE, O_WRONLY|O_CREAT|O_TRUNC, 0644));
409
      close(open(PIDFILE, O_WRONLY|O_CREAT|O_TRUNC, 0644));
410
  }
411
}
540
}
412
541
413
static void handlexitsigs(void)
542
static void handlexitsigs(void)
Lines 420-435 Link Here
420
     /* May succeed. If not, won't care. */
549
     /* May succeed. If not, won't care. */
421
{
550
{
422
  int fd = open(PIDFILE, O_WRONLY|O_CREAT|O_TRUNC, 0664);
551
  int fd = open(PIDFILE, O_WRONLY|O_CREAT|O_TRUNC, 0664);
423
  
552
  char buf[24];
553
424
  if (fd < 0)
554
  if (fd < 0)
425
  {
555
    return;
426
      return;
556
427
  }
557
  /* we don't use snprintf() here since it is not so portable...*/
428
  
558
  /* Anyway, 64-bit integer is at max 20 characters long. */
429
  fdprintf(fd, "%d\n", getpid());
559
  sprintf(buf, "%d\n", getpid());
560
  buf[23] = '\0';
561
  write(fd, buf, strlen(buf));
430
  fchown(fd, nobody, nogrp);
562
  fchown(fd, nobody, nogrp);
431
  close(fd);
563
  close(fd);
432
  
564
433
  signal(SIGTERM, (void(*)(int))handlexitsigs);
565
  signal(SIGTERM, (void(*)(int))handlexitsigs);
434
  signal(SIGINT, (void(*)(int))handlexitsigs);
566
  signal(SIGINT, (void(*)(int))handlexitsigs);
435
  signal(SIGQUIT, (void(*)(int))handlexitsigs);
567
  signal(SIGQUIT, (void(*)(int))handlexitsigs);
Lines 436-570 Link Here
436
  /* should this handle ILL, ... (see signal(7)) */
568
  /* should this handle ILL, ... (see signal(7)) */
437
}
569
}
438
570
439
/* parses the `rcs_id' string for version information and prints the info. */
571
static void printversion(void)
440
static void printversion(char nameterm)
441
{
572
{
442
  struct {
573
  struct iovec iv[4];
443
    const char * p;
444
    int		 l;
445
574
446
  } s[4] = { { 0 } };
575
  iv[0].iov_base = TRG;
576
  iv[0].iov_len = sizeof TRG - 1;
447
577
448
  int		i;
578
  iv[1].iov_base = " ";
449
  const char *	p;
579
  iv[1].iov_len = 1;
450
  
580
451
  for (i = 0, p = rcs_id; *p && i < 4 ; i++)
581
  iv[2].iov_base = VERSION;
452
  {
582
  iv[2].iov_len = sizeof VERSION - 1;
453
      while (*p != ' ' && *p != '\0')
583
454
      {
584
  iv[3].iov_base = ".\n";
455
	  p++;
585
  iv[3].iov_len = 2;
456
      }
586
457
      if (*p++ == ' ' && *p != '\0')
587
  writev(1, iv, 4);
458
      {
459
	  s[i].p = p;
460
      }
461
  }
462
  
463
  if (s[0].p)
464
  {
465
      p = s[0].p;
466
      while (*p != nameterm && *p != ' ')
467
      {
468
	  p++;
469
      }
470
      s[0].l = p - s[0].p;
471
  }
472
  else
473
  {
474
      s[0].p = "unknown";
475
      s[0].l = 7;
476
  }
477
  
478
  for (i = 1; i < 3; i++)
479
  {
480
      if (s[i+1].p)
481
      {
482
	  s[i].l = s[i+1].p - s[i].p - 1;
483
      }
484
      else
485
      {
486
	  s[i].p = "unknown"; s[i].l = 7;
487
      }
488
  }
489
  
490
  fdprintf(1, "%.*s %.*s (%.*s)\n",
491
	   s[0].l, s[0].p, /**/ s[1].l, s[1].p, /**/ s[2].l, s[2].p);
492
}
588
}
493
589
494
int main(int argc, char * argv[])
590
int main(int argc GCCATTR_UNUSED, const char * argv[])
495
{
591
{
496
  uid_t nobody, nogrp;
592
  uid_t nobody, nogrp;
497
  
593
498
  memset(conns, 0, sizeof conns);
594
  memset(conns, 0, sizeof conns);
499
  memset(&G, 0, sizeof G);
595
  memset(&G, 0, sizeof G);
500
  FD_ZERO(&G.readfds);
596
  FD_ZERO(&G.readfds);
501
  FD_SET(0, &G.readfds);
597
  FD_SET(0, &G.readfds);
502
  
598
599
  TRACE(1, ("s: `%s', l = %d\n", ident_substr, ident_substr_len));
600
503
  if (argv[1])
601
  if (argv[1])
504
  {
602
    if (argv[1][0] == '-') {
505
      if (argv[1][0] == '-')
603
      if (argv[1][1] == 'V')
506
      {
604
	{
507
	  if (argv[1][1] == 'V')
605
	  printversion();
606
	  return 0;
607
	}
608
      else
609
	{
610
        if (argv[1][1] == 'r')
508
	  {
611
	  {
509
	      printversion('.');
612
	    G.randident = true;
510
	      return 0;
613
	    srand(time(0));
511
	  }
614
	  }
512
	  else
615
	else
513
	  {
616
	  {
514
	      fdprintf(2, "%s: invalid option -- %c\n", argv[0], argv[1][1]);
617
            char b[2]; b[0] = argv[1][1]; b[1]= '\0';
515
	      fdprintf(2, "Usage: %s [-V] " IU_IN_USAGESTR "\n", argv[0]);
618
516
	      return 1;
619
            writestrings(2, argv[0], ": invalid option -- ", b, ".\n",
620
                         "Usage: ", argv[0], " [-rV] ", IU_IN_USAGESTR "\n",
621
                         NULL);
622
            return 1;
517
	  }
623
	  }
518
      }
624
	}}
519
      else
625
    else
520
      {
626
      SET_IU(argv[1], argc - 1);
521
	  SET_IU(argv[1], argc - 1);
522
      }
523
  }
524
  else
627
  else
525
  {
628
    SET_IU(nobodystr, 1);
526
      SET_IU(nobodystr, 1);
629
527
  }
630
528
  
529
  
530
#ifndef DEBUG
631
#ifndef DEBUG
531
  close(1); /* not debugging, openlog() hopefully uses fd 1. */
632
  close(1); /* not debugging, openlog() hopefully uses fd 1. */
532
#else
633
#else
533
  close(3); /* debugging, TRACE uses fd 1, openlog() hopefully fd 3 */
634
  close(3); /* debugging, TRACE uses fd 1, openlog() hopefully fd 3 */
534
#endif
635
#endif
535
  
636
536
  openlog("identd", LOG_CONS, LOG_DAEMON);
637
  openlog("identd", LOG_CONS, LOG_DAEMON);
537
  
638
538
  {
639
  {
539
      struct passwd * pw = getpwnam(nobodystr);
640
    struct passwd * pw = getpwnam(nobodystr);
540
      
641
541
      if (pw)
642
    if (pw)
542
      {
643
      {
543
	  nobody = pw->pw_uid;
644
	nobody = pw->pw_uid;
544
	  nogrp = pw->pw_gid;
645
	nogrp = pw->pw_gid;
545
      }
646
      }
546
      else
647
    else
547
      {
648
      {
548
	  syslog(LOG_CRIT, "Cannot find user `nobody': %s", strerrno());
649
	syslog(LOG_CRIT, "Can not find user `nobody': %s,", strerrno());
549
	  return -1;
650
	return -1;
550
      }
651
      }
551
  }
652
  }
552
  
653
553
  if (inetbind(getport()) < 0)
654
  if (inetbind(getport()) < 0)
554
  {
555
      return -1;
655
      return -1;
556
  }
656
557
  
558
  /* */
657
  /* */
559
  {
658
  {
560
      int			 i;
659
    int i;
561
      
660
562
      for (i = FCS; i < MAXCONNS + FCS; i++)
661
    for (i = FCS; i < MAXCONNS + FCS; i++)
563
      {
662
      close(i);
564
	  close(i);
565
      }
566
  }
663
  }
567
  
664
568
#ifdef DEBUG
665
#ifdef DEBUG
569
#ifndef LOG_PERROR
666
#ifndef LOG_PERROR
570
#define LOG_PERROR 0
667
#define LOG_PERROR 0
Lines 576-818 Link Here
576
  close(2);
673
  close(2);
577
  signal(SIGHUP, SIG_IGN);
674
  signal(SIGHUP, SIG_IGN);
578
#endif /* DEBUG */
675
#endif /* DEBUG */
579
  
676
580
  signal(SIGPIPE, SIG_IGN); /* connection closed when writing (raises ???) */
677
  signal(SIGPIPE, SIG_IGN); /* connection closed when writing (raises ???) */
581
  
678
582
  writepid(nobody, nogrp);
679
  writepid(nobody, nogrp);
583
  
680
584
  setegid(nogrp); setgid(nogrp); setuid(nobody); seteuid(nobody);
681
  setegid(nogrp); setgid(nogrp); setuid(nobody); seteuid(nobody);
585
  
682
586
  {
683
  {
587
      int i;
684
    int i;
588
      
685
589
      for (i = 0; i < 4; i++)
686
    for (i = 0; i < 4; i++)
590
      {
687
      {
591
	  char *	id = (char)NULL;
688
	const char *	id = NULL;
592
	  unsigned int	rv = 0;
689
	unsigned int	rv = 0;
593
	  
690
594
	  switch (i)
691
	switch (i)
595
	  {
692
	  {
596
	  case 0:
693
	  case 0: rv = (unsigned int)getegid(); id = "egid"; break;
597
	    rv = (unsigned int)getegid();
694
	  case 1: rv = (unsigned int)getgid();  id = "gid";  break;
598
	    id = "egid";
695
	  case 2: rv = (unsigned int)geteuid(); id = "euid"; break;
599
	    break;
696
	  case 3: rv = (unsigned int)getuid();  id = "uid";  break;
600
	  case 1:
601
	    rv = (unsigned int)getgid();
602
	    id = "gid";
603
	    break;
604
	  case 2:
605
	    rv = (unsigned int)geteuid();
606
	    id = "euid";
607
	    break;
608
	  case 3:
609
	    rv = (unsigned int)getuid();
610
	    id = "uid";
611
	    break;
612
	  }
697
	  }
613
	  
698
614
	  if (rv == 0)
699
	if (rv == 0)
615
	  {
700
	  {
616
	      syslog(LOG_ERR,
701
	    syslog(LOG_ERR,
617
		     "Can not drop all root privileges (%s) !!! %s !!!",
702
		   "Can not drop all root privileges (%s) !!! %s !!!",
618
		     id, strerrno());
703
		   id, strerrno());
619
	      delpidfile();
704
	    delpidfile();
620
	      return -1;
705
	    return -1;
621
	  }
706
	  }
622
      }
707
      }
623
  }
708
  }
624
  
709
625
  while (2)
710
  while (2)
626
  {
711
  {
627
      fd_set		rfds = G.readfds;
712
    fd_set		rfds = G.readfds;
628
      struct timeval	tv = { 15, 0 };
713
    struct timeval	tv = { 15, 0 };
629
      int		i;
714
    int			i;
630
      int		tim = time(NULL);
715
    int			tim = time(NULL);
631
      
716
632
      TRACE(("calling select(): n = %d, rfds = 0x%x\n\n",
717
    TRACE(1, ("calling select(): n = %d, rfds = 0x%x\n\n",
633
	     G.conncnt + FCS, *(int *)&rfds));
718
	      G.conncnt + FCS, *(int *)&rfds));
634
      
719
635
      select(G.conncnt + FCS, &rfds, NULL, NULL, G.conncnt? &tv: NULL);
720
    select(G.conncnt + FCS, &rfds, NULL, NULL, G.conncnt? &tv: NULL);
636
      
721
637
      for (i = G.conncnt - 1; i >= 0; i--)
722
    for (i = G.conncnt - 1; i >= 0; i--)
638
      {
723
      {
639
	  int s = i + FCS;
724
	int s = i + FCS;
640
	  
725
641
	  if (FD_ISSET(s, &rfds))
726
	if (FD_ISSET(s, &rfds))
642
	  {
727
	  {
643
	      char *		buf = conns[i].buf;
728
	    char *		buf = conns[i].buf;
644
	      unsigned int	len = conns[i].len;
729
	    unsigned int	len = conns[i].len;
645
	      unsigned int	l;
730
	    unsigned int	l;
646
	      
731
647
	      TRACE(("data socket fd_isset %d\n", s));
732
	    TRACE(1, ("data socket fd_isset %d\n", s));
648
	      
733
649
	      if ((int)(l = read(s, buf + len, sizeof conns[0].buf - len)) > 0)
734
	    if ((int)(l = read(s, buf + len, sizeof conns[0].buf - len)) > 0)
650
	      {
735
	      {
651
		  if (checkInput(buf, len, l))
736
		if (checkInput(buf, len, l))
652
		  {
737
		  {
653
		      reply(s, buf);
738
		    reply(s, buf);
654
		      goto deleteconn;
739
		    goto deleteconn;
655
		  }
740
		  }
656
		  else if (len + l >= sizeof conns[0].buf)
741
		else if (len + l >= sizeof conns[0].buf)
657
		  {
742
		  {
658
		      replyError(s, "X-INVALID-REQUEST");
743
		    replyError(s, "X-INVALID-REQUEST");
659
		      goto deleteconn;
744
		    goto deleteconn;
660
		  }
745
		  }
661
		  else
746
		else
662
		  {
747
		  conns[i].len += l;
663
		      conns[i].len += l;
664
		  }
665
	      }
748
	      }
666
	      else
749
	    else
667
	      {
750
	      goto deleteconn;
668
		  goto deleteconn;
751
669
	      }
752
	    conns[i].lasttime = tim;
670
	      
753
	    continue;
671
	      conns[i].lasttime = tim;
754
672
	      continue;
673
	      
674
	  deleteconn:
755
	  deleteconn:
675
	      deleteConn(s);
756
	    deleteConn(s);
676
	  }
757
	  }
677
	  else
758
	else
678
	  {
759
	  {
679
	      /* implement as time_after() in linux kernel sources ... */
760
	    /* implement as time_after() in linux kernel sources ... */
680
	      if (conns[i].lasttime + MAXIDLETIME <= tim)
761
	    if (conns[i].lasttime + MAXIDLETIME <= tim)
681
	      {
762
	      {
682
		  replyError(s, "X-TIMEOUT");
763
		replyError(s, "X-TIMEOUT");
683
		  deleteConn(s);
764
		deleteConn(s);
684
	      }
765
	      }
685
	  }
766
	  }
686
      }
767
      }
687
      
768
688
      if (FD_ISSET(0, &rfds))
769
    if (FD_ISSET(0, &rfds))
689
      {
770
      {
690
	  int s = accept(0, NULL, 0);
771
	int s = accept(0, NULL, 0);
691
	  
772
692
	  TRACE(("server socket fd_isset, %d accepted\n", s));
773
	TRACE(1, ("server socket fd_isset, %d accepted\n", s));
693
	  
774
694
	  if (s < 0)
775
	if (s < 0)
695
	  {
776
	  {
696
	      if (errno != EINTR) /* EINTR */
777
	    if (errno != EINTR) /* EINTR */
697
	      {
778
	      syslog(LOG_ERR, "accept: %s", strerrno());
698
		  syslog(LOG_ERR, "accept: %s", strerrno());
699
	      }
700
	  }
779
	  }
701
	  else
780
	else
702
	  {
781
	  {
703
	      if (G.conncnt == MAXCONNS)
782
	    if (G.conncnt == MAXCONNS)
704
	      {
783
	      i = closeOldest();
705
		  i = closeOldest();
784
	    else
706
	      }
785
	      i = G.conncnt++;
707
	      else
786
708
	      {
787
	    movefd(s, i + FCS); /* move if not already there */
709
		  i = G.conncnt++;
788
710
	      }
789
	    FD_SET(i + FCS, &G.readfds);
711
	      
790
712
	      if (s != i + FCS)
791
	    conns[i].len = 0;
713
	      {
792
	    conns[i].lasttime = time(NULL);
714
		  movesocket(s, i + FCS);
715
	      }
716
	      
717
	      FD_SET(i + FCS, &G.readfds);
718
	      
719
	      conns[i].len = 0;
720
	      conns[i].lasttime = time(NULL);
721
	  }
793
	  }
722
      }
794
      }
723
  }
795
  }
724
}
796
}
725
797
726
static int parseAddrs(char * ptr, int * myaddr, int * heraddr);
798
static int parseAddrs(char * ptr, char ** myaddr, char ** heraddr);
727
799
728
static void replyError(int s, char * buf)
800
static void replyError(int s, const char * buf)
729
{
801
{
730
  fdprintf(s, "0, 0 : ERROR : %s\r\n", buf);
802
  struct iovec iv[3];
803
804
  iv[0].iov_base = "0, 0 : ERROR : ";	iv[0].iov_len = 15;
805
  iv[1].iov_base = buf;			iv[1].iov_len = strlen(buf);
806
  iv[2].iov_base = "\r\n";		iv[2].iov_len = 2;
807
808
  writev(s, iv, 3);
731
}
809
}
732
810
733
static void reply(int s, char * buf)
811
static void reply(int s, char * buf)
734
{
812
{
735
  int myaddr, heraddr;
813
  char * myaddr, *heraddr;
736
  
814
737
  myaddr = heraddr = 0;
815
  myaddr = heraddr = NULL;
738
  
816
739
  if (parseAddrs(buf, &myaddr, &heraddr))
817
  if (parseAddrs(buf, &myaddr, &heraddr))
740
  {
818
    replyError(s, "X-INVALID-REQUEST");
741
      replyError(s, "X-INVALID-REQUEST");
742
  }
743
  else
819
  else
744
  {
820
    {
745
      fdprintf(s, "%d, %d " IDENT_SUBSTR " %.*s\r\n",
821
      struct iovec iv[6];
746
	       myaddr, heraddr, IDSTR_MAX,
747
#ifdef XXXMULTI
822
#ifdef XXXMULTI
748
	       G.identuserlist[random() % G.identusers]
823
      const char * iul = G.identuserlist[random() % G.identusers];
824
#endif
825
826
      iv[0].iov_base = myaddr;		iv[0].iov_len = strlen(myaddr);
827
      iv[1].iov_base = ", ";		iv[1].iov_len = 2;
828
      iv[2].iov_base = heraddr;		iv[2].iov_len = strlen(heraddr);
829
      iv[3].iov_base = checked_cast(const char[], void *, ident_substr);
830
      iv[3].iov_len = ident_substr_len;
831
#ifdef XXXMULTI
832
      iv[4].iov_base = checked_cast(const char *, void *, iul);
833
      iv[4].iov_len = strlen(iul);
749
#else
834
#else
750
       	       G.identuser
835
      if (G.randident)
836
	{
837
	  /* generate random string as reply: */
838
	  int i;
839
	  char randomstring[8];
840
	  int randlen = (random() % 6) + 3; /* random string length 3-8 */
841
842
	  /* have first char letter... */
843
	  randomstring[0] = alphanum[10 + random() % 52];
844
845
	  for (i = 1; i < randlen; i++)
846
	    randomstring[i] = alphanum[random() % 62];
847
848
	  iv[4].iov_base = checked_cast(char [], void *, randomstring);
849
	  iv[4].iov_len = randlen;
850
	}
851
      else
852
	{
853
          /* use usual behaviour */
854
          iv[4].iov_base = checked_cast(const char *, void *, G.identuser);
855
          iv[4].iov_len = strlen(G.identuser);
856
	}
751
#endif
857
#endif
752
	       );
858
      iv[5].iov_base = "\r\n";	iv[5].iov_len = 2;
753
  }
859
860
      writev(s, iv, 6);
861
    }
754
}
862
}
755
863
756
864
static int chmatch(char c, const char * chars)
757
static int chmatch(char c, char * chars)
758
{
865
{
759
  while (*chars)
866
  for (; *chars; chars++)
760
  {
761
    if (c == *chars)
867
    if (c == *chars)
762
    {
868
      return 1;
763
	return 1;
764
    }
765
    else
766
    {
767
	chars++;
768
    }
769
  }
770
869
771
  return 0;
870
  return 0;
772
}
871
}
773
872
774
static int skipchars(char ** p, char * chars)
873
static int skipchars(char ** p, const char * chars)
775
{
874
{
776
  while (chmatch(**p, chars))
875
  while (chmatch(**p, chars))
777
  {
876
    (*p)++;
778
      (*p)++;
779
  }
780
877
781
  if (**p == '\r' || **p == '\n')
878
  if (**p == '\r' || **p == '\n')
782
  {
879
    return 0;
783
      return -1;
784
  }
785
880
786
  return 0;
881
  return 1;
787
}
882
}
788
883
789
static int parseAddrs(char * ptr, int * myaddr, int * heraddr)
884
static int parseAddrs(char * ptr, char ** myaddr, char ** heraddr)
790
{
885
{
791
  /* parse <port-on-server> , <port-on-client> */
886
  /* parse <port-on-server> , <port-on-client> */
792
887
793
  if (skipchars(&ptr, " \t") ||
888
  if (! skipchars(&ptr, " \t"))
794
      (*myaddr = atoi(ptr)) <= 0 ||
889
    return -1;
795
      skipchars(&ptr, "1234567890") ||
796
      skipchars(&ptr, " \t,") ||
797
      (*heraddr = atoi(ptr)) <= 0)
798
  {
799
      return -1;
800
  }
801
890
891
  *myaddr = ptr;
892
893
  if (! skipchars(&ptr, "1234567890"))
894
    return -1;
895
896
  if (! chmatch(*ptr, " \t,"))
897
    return -1;
898
899
  *ptr++ = '\0';
900
901
  if (! skipchars(&ptr, " \t,") )
902
    return -1;
903
904
  *heraddr = ptr;
905
906
  skipchars(&ptr, "1234567890");
907
908
  if (! chmatch(*ptr, " \n\r"))
909
    return -1;
910
911
  *ptr = '\0';
912
802
  return 0;
913
  return 0;
803
}
914
}
804
915
805
806
/*
807
 * Variables for Emacs
808
 *
809
 * Local variables:
810
 * mode: c
811
 * c-file-style: "gnu"
812
 * c-file-offsets: ( (substatement-open . 0) (statement-block-intro . ++) )
813
 * tab-width: 8
814
 * compile-command: "sh identd.c"
815
 * End:
816
 */
817
818
/* EOF */
916
/* EOF */
(-)security/fakeident/pkg-descr (-4 / +8 lines)
Lines 1-5 Link Here
1
Fake Identd is a tool that replies with a standard answer to all incoming
1
This program is standalone 'fake' ident daemon. This program does
2
identd requests on a host, making it nearly perfect for a masquerading
2
not fork() but is configured to handle up to 20 concurrent connections.
3
router.
3
Since one connection should not last long, if all 20 connections are
4
in use, the next connection will close the oldest connection data
5
has been read. This way this program is not very vulnerable to so
6
called `denial of service' attack, thus making this ideal "identd"
7
to be used in a firewall, IP masquerading hosts etc.
4
8
5
WWW: http://hangout.de/fakeidentd/index.html
9
WWW: http://www.guru-group.fi/~too/sw/identd.readme

Return to bug 240175