source: MondoRescue/branches/3.3/mindi-busybox/networking/isrv_identd.c@ 3734

Last change on this file since 3734 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 3.6 KB
RevLine 
[1765]1/* vi: set sw=4 ts=4: */
2/*
3 * Fake identd server.
4 *
[2725]5 * Copyright (C) 2007 Denys Vlasenko
[1765]6 *
[2725]7 * Licensed under GPLv2, see file LICENSE in this source tree.
[1765]8 */
9
[3232]10//usage:#define fakeidentd_trivial_usage
11//usage: "[-fiw] [-b ADDR] [STRING]"
12//usage:#define fakeidentd_full_usage "\n\n"
13//usage: "Provide fake ident (auth) service\n"
14//usage: "\n -f Run in foreground"
15//usage: "\n -i Inetd mode"
16//usage: "\n -w Inetd 'wait' mode"
17//usage: "\n -b ADDR Bind to specified address"
18//usage: "\n STRING Ident answer string (default: nobody)"
19
[2725]20#include "libbb.h"
[3621]21#include "common_bufsiz.h"
[1765]22#include <syslog.h>
23#include "isrv.h"
24
25enum { TIMEOUT = 20 };
26
27typedef struct identd_buf_t {
28 int pos;
[3621]29 char buf[64 - sizeof(int)];
[1765]30} identd_buf_t;
31
32#define bogouser bb_common_bufsiz1
33
34static int new_peer(isrv_state_t *state, int fd)
35{
36 int peer;
37 identd_buf_t *buf = xzalloc(sizeof(*buf));
38
39 peer = isrv_register_peer(state, buf);
40 if (peer < 0)
41 return 0; /* failure */
42 if (isrv_register_fd(state, peer, fd) < 0)
43 return peer; /* failure, unregister peer */
44
[3621]45 ndelay_on(fd);
[1765]46 isrv_want_rd(state, fd);
47 return 0;
48}
49
50static int do_rd(int fd, void **paramp)
51{
52 identd_buf_t *buf = *paramp;
53 char *cur, *p;
54 int sz;
55
56 cur = buf->buf + buf->pos;
57
[3621]58 sz = safe_read(fd, cur, sizeof(buf->buf) - 1 - buf->pos);
[1765]59
60 if (sz < 0) {
61 if (errno != EAGAIN)
[3621]62 goto term;
63 return 0; /* "session is ok" */
[1765]64 }
65
66 buf->pos += sz;
67 buf->buf[buf->pos] = '\0';
68 p = strpbrk(cur, "\r\n");
69 if (p)
70 *p = '\0';
[3621]71 if (!p && sz)
72 return 0; /* "session is ok" */
73
[1765]74 /* Terminate session. If we are in server mode, then
75 * fd is still in nonblocking mode - we never block here */
[3621]76 if (fd == 0)
77 fd++; /* inetd mode? then write to fd 1 */
[1765]78 fdprintf(fd, "%s : USERID : UNIX : %s\r\n", buf->buf, bogouser);
[3621]79 /*
80 * Why bother if we are going to close fd now anyway?
81 * if (server)
82 * ndelay_off(fd);
83 */
[1765]84 term:
85 free(buf);
[3621]86 return 1; /* "terminate" */
[1765]87}
88
[2725]89static int do_timeout(void **paramp UNUSED_PARAM)
[1765]90{
91 return 1; /* terminate session */
92}
93
94static void inetd_mode(void)
95{
96 identd_buf_t *buf = xzalloc(sizeof(*buf));
97 /* buf->pos = 0; - xzalloc did it */
98 do
99 alarm(TIMEOUT);
[3621]100 /* Note: we do NOT want nonblocking I/O here! */
[1765]101 while (do_rd(0, (void*)&buf) == 0);
102}
103
[2725]104int fakeidentd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
105int fakeidentd_main(int argc UNUSED_PARAM, char **argv)
[1765]106{
107 enum {
108 OPT_foreground = 0x1,
109 OPT_inetd = 0x2,
110 OPT_inetdwait = 0x4,
111 OPT_fiw = 0x7,
112 OPT_bindaddr = 0x8,
113 };
114
115 const char *bind_address = NULL;
116 unsigned opt;
117 int fd;
118
[3621]119 setup_common_bufsiz();
120
[1765]121 opt = getopt32(argv, "fiwb:", &bind_address);
122 strcpy(bogouser, "nobody");
123 if (argv[optind])
[3621]124 strncpy(bogouser, argv[optind], COMMON_BUFSIZE - 1);
[1765]125
126 /* Daemonize if no -f and no -i and no -w */
[2725]127 if (!(opt & OPT_fiw))
[1765]128 bb_daemonize_or_rexec(0, argv);
129
130 /* Where to log in inetd modes? "Classic" inetd
131 * probably has its stderr /dev/null'ed (we need log to syslog?),
132 * but daemontools-like utilities usually expect that children
133 * log to stderr. I like daemontools more. Go their way.
134 * (Or maybe we need yet another option "log to syslog") */
135 if (!(opt & OPT_fiw) /* || (opt & OPT_syslog) */) {
[2725]136 openlog(applet_name, LOG_PID, LOG_DAEMON);
[1765]137 logmode = LOGMODE_SYSLOG;
138 }
139
140 if (opt & OPT_inetd) {
141 inetd_mode();
142 return 0;
143 }
144
145 /* Ignore closed connections when writing */
146 signal(SIGPIPE, SIG_IGN);
147
148 fd = 0;
149 if (!(opt & OPT_inetdwait)) {
150 fd = create_and_bind_stream_or_die(bind_address,
151 bb_lookup_port("identd", "tcp", 113));
152 xlisten(fd, 5);
153 }
154
155 isrv_run(fd, new_peer, do_rd, /*do_wr:*/ NULL, do_timeout,
156 TIMEOUT, (opt & OPT_inetdwait) ? TIMEOUT : 0);
157 return 0;
158}
Note: See TracBrowser for help on using the repository browser.