Annotation of ansh/src/ansh3d.c, revision 1.1.1.1.2.3
1.1 misho 1: /*************************************************************************
2: * (C) 2011 AITNET - Sofia/Bulgaria - <office@aitnet.org>
3: * by Michael Pounov <misho@elwix.org>
4: *
5: * $Author: misho $
1.1.1.1.2.3! misho 6: * $Id: ansh3d.c,v 1.1.1.1.2.2 2011/10/13 16:08:52 misho Exp $
1.1 misho 7: *
1.1.1.1.2.2 misho 8: *************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
1.1 misho 46: #include "global.h"
47: #include "anshd.h"
48: #include "proc.h"
49:
50:
51: intptr_t Kill;
1.1.1.1.2.1 misho 52: int Verbose;
53: u_int Crypted = 1;
1.1 misho 54: proc_head_t pH;
55: int bpfLEN, Timeout, Daemon = 1;
1.1.1.1.2.3! misho 56: char Key[STRSIZ];
1.1 misho 57:
58: extern char compiled[], compiledby[], compilehost[];
59:
60: static void
61: Usage()
62: {
63: printf( " -= anshd =- ELWIX Layer3 remote management service over ICMP\n"
64: "=== %s === %s@%s ===\n\n"
65: " Syntax: ansh3d [options]\n\n"
66: "\t-a <host>\tBind to host address (default is *any*)\n"
67: "\t-i <id>\tService ID (default is 42)\n"
68: "\t-U <user>\tRun service with other user\n"
69: "\t-C <dir>\tRun service into chroot directory\n"
70: "\t-t <timeout>\tTimeout of login if no activity (default is 0 sec)\n"
1.1.1.1.2.3! misho 71: "\t-k <key>\tService cipher key\n"
1.1 misho 72: "\t-u\t\tSwitch to unencrypted traffic between hosts\n"
73: "\t-b\t\tRun into batch mode (default is daemon mode)\n"
74: "\t-v\t\tVerbose (more -v, more verbosity ...)\n"
75: "\t-h\t\tThis help screen!\n"
76: "\n", compiled, compiledby, compilehost);
77: }
78:
79: static void
80: sig(int s)
81: {
82: int state;
83:
84: switch (s) {
85: case SIGHUP:
86: VERB(1) LOG("Got SIGHUP!\n");
87: break;
88: case SIGTERM:
89: Kill++;
90: VERB(1) LOG("Got SIGTERM!\n");
91: break;
92: case SIGPIPE:
93: VERB(1) LOG("Got SIGPIPE!\n");
94: break;
95: case SIGCHLD:
96: VERB(1) LOG("Got SIGCHLD!\n");
97: while (waitpid(-1, &state, WNOHANG) > 0);
98: break;
99: }
100: }
101:
102: static void *
103: hook_error(void *root, void *arg)
104: {
105: /* sched_root_task_t *r = root; */
106:
107: if (!root)
108: return (void*) -1;
109:
110: if (arg == (void*) EINTR)
111: return (void*) -1;
112:
113: return NULL;
114: }
115:
116: int
117: main(int argc, char **argv)
118: {
119: struct sockaddr sa = { 0 };
120: struct sockaddr_in *sin4 = (struct sockaddr_in*) &sa;
121: struct sockaddr_in6 *sin6 = (struct sockaddr_in6*) &sa;
122: struct hostent *host;
123: struct passwd *pass;
124: int fd, h = 0, uid = 0, gid = 0;
125: long id = ANSH_ID;
126: char ch, szUser[STRSIZ] = "root", szChroot[STRSIZ] = "/";
127: struct sigaction sact;
128: sched_root_task_t *root = NULL;
129: struct tagProc *proc;
130:
1.1.1.1.2.3! misho 131: strlcpy(Key, DEFAULT_KEY, sizeof Key);
! 132:
! 133: while ((ch = getopt(argc, argv, "hvubt:a:i:U:C:k:")) != -1)
1.1 misho 134: switch (ch) {
135: case 'U':
136: pass = getpwnam(optarg);
137: if (!pass) {
138: printf("Error:: User %s not found!\n", optarg);
139: return 1;
140: } else {
141: strlcpy(szUser, optarg, sizeof szUser);
142: uid = pass->pw_uid;
143: gid = pass->pw_gid;
144: }
145: endpwent();
146: break;
147: case 'C':
148: if (access(optarg, R_OK)) {
149: printf("Error:: in chroot %s #%d - %s\n", optarg, errno, strerror(errno));
150: return 1;
151: } else
152: strlcpy(szChroot, optarg, sizeof szChroot);
153: break;
154: case 'i':
155: id = strtol(optarg, NULL, 0);
156: break;
157: case 't':
158: Timeout = abs(strtol(optarg, NULL, 0));
159: break;
1.1.1.1.2.3! misho 160: case 'k':
! 161: strlcpy(Key, optarg, sizeof Key);
! 162: break;
1.1 misho 163: case 'a':
164: host = gethostbyname(optarg);
165: if (!host) {
166: printf("Error:: in bind address '%s' #%d - %s\n",
167: optarg, h_errno, hstrerror(h_errno));
168: return 1;
169: }
170: switch (host->h_addrtype) {
171: case AF_INET:
172: sin4->sin_len = sizeof(struct sockaddr_in);
173: sin4->sin_family = AF_INET;
174: memcpy(&sin4->sin_addr.s_addr, host->h_addr, host->h_length);
175: break;
176: case AF_INET6:
177: sin6->sin6_len = sizeof(struct sockaddr_in6);
178: sin6->sin6_family = AF_INET6;
179: memcpy(&sin6->sin6_addr.s6_addr, host->h_addr, host->h_length);
180: break;
181: default:
182: printf("Error:: Unknown address type %d !!!\n", host->h_addrtype);
183: return 1;
184: }
185: break;
186: case 'u':
187: Crypted ^= Crypted;
188: break;
189: case 'b':
190: Daemon ^= Daemon;
191: break;
192: case 'v':
193: Verbose++;
194: break;
195: case 'h':
196: default:
197: Usage();
198: return 1;
199: }
200: argc -= optind;
201: argv += optind;
202:
203: /* sanity check for openned descriptor */
204: if (!sa.sa_family) {
205: sin4->sin_len = sizeof(struct sockaddr_in);
206: sin4->sin_family = AF_INET;
207: }
208:
209: /* catch signals */
210: memset(&sact, 0, sizeof sact);
211: sigemptyset(&sact.sa_mask);
212: sact.sa_handler = sig;
213: sigaction(SIGPIPE, &sact, NULL);
214: sigaction(SIGCHLD, &sact, NULL);
215: sigaction(SIGTERM, &sact, NULL);
216: sigaction(SIGHUP, &sact, NULL);
217:
218: openlog("ansh3d", LOG_CONS | LOG_PID, LOG_DAEMON);
219:
220: if (Daemon) {
221: switch (fork()) {
222: case -1:
223: ERR("Daemon mode #%d - %s\n", errno, strerror(errno));
224: closelog();
225: return 1;
226: case 0:
227: VERB(1) LOG("Welcome to dark ...\n");
228:
229: setsid();
230:
231: fd = open("/dev/null", O_WRONLY);
232: if (fd) {
233: dup2(fd, STDIN_FILENO);
234: dup2(fd, STDOUT_FILENO);
235: dup2(fd, STDERR_FILENO);
236: if (fd > 2)
237: close(fd);
238: }
239: break;
240: default:
241: VERB(1) LOG("Going to shadow land ...\n");
242: closelog();
243: return 0;
244: }
245: }
246:
247: if (ioCreatePIDFile(PIDFILE_ANSH3D, 42)) {
248: ERR("Error:: already started ansh3d service ...\n");
249: closelog();
250: return 1;
251: }
252:
253: h = PrepareL3(&sa, &bpfLEN);
254: if (h == -1) {
255: ERR("Error:: Descriptor not opened ... abort!\n");
256: unlink(PIDFILE_ANSH3D);
257: closelog();
258: return 2;
259: }
260:
261: SLIST_INIT(&pH);
262: if (!(proc = InitProc(h, NULL, id, bpfLEN))) {
263: ERR("Error:: Not enough memory ...\n");
264: close(h);
265: unlink(PIDFILE_ANSH3D);
266: closelog();
267: return 3;
268: }
269:
270: root = schedBegin();
271: if (!root) {
272: ERR("Scheduler not init #%d - %s\n", sched_GetErrno(), sched_GetError());
273: DestroyProc(id);
274: close(h);
275: unlink(PIDFILE_ANSH3D);
276: closelog();
277: return 4;
278: } else
279: root->root_hooks.hook_root.error = hook_error;
280:
281: chdir("/");
282: chroot(szChroot);
283:
284: setgid(gid);
285: setuid(uid);
286:
287: if (schedRead(root, icmpRx, (void*) id, h)) {
288: schedRun(root, &Kill);
289: } else
290: ERR("Failed to add reader task #%d - %s\n", sched_GetErrno(), sched_GetError());
291:
292: VERB(1) LOG("Finish process.");
293: schedEnd(&root);
294: DestroyProc(id);
295: close(h);
296: unlink(PIDFILE_ANSH3D);
297: closelog();
298: return 0;
299: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>