File:  [ELWIX - Embedded LightWeight unIX -] / ansh / src / ansh3d.c
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Tue May 19 23:25:30 2015 UTC (9 years ago) by misho
Branches: MAIN
CVS tags: ansh2_1, HEAD, ANSH2_0
version 2.0

    1: /*************************************************************************
    2:  * (C) 2011 AITNET - Sofia/Bulgaria - <office@aitnet.org>
    3:  *  by Michael Pounov <misho@elwix.org>
    4:  *
    5:  * $Author: misho $
    6:  * $Id: ansh3d.c,v 1.5 2015/05/19 23:25:30 misho Exp $
    7:  *
    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, 2012
   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: */
   46: #include "global.h"
   47: #include "anshd.h"
   48: #include "proc.h"
   49: 
   50: 
   51: intptr_t Kill;
   52: int Verbose;
   53: u_int Crypted = 1;
   54: proc_head_t pH;
   55: int bpfLEN, Timeout = 300, Daemon = 1;
   56: char Key[STRSIZ];
   57: 
   58: static struct tagProc *proc;
   59: static sched_root_task_t *root;
   60: 
   61: extern char compiled[], compiledby[], compilehost[];
   62: 
   63: static void
   64: Usage()
   65: {
   66: 	printf(	" -= anshd =- ELWIX Layer3 remote management service over ICMP\n"
   67: 		"=== %s === %s@%s ===\n\n"
   68: 		" Syntax: ansh3d [options]\n\n"
   69: 		"\t-a <host>\tBind to host address (default is *any*)\n"
   70: 		"\t-i <id>\tService ID (default is 42)\n"
   71: 		"\t-U <user>\tRun service with other user\n"
   72: 		"\t-C <dir>\tRun service into chroot directory\n"
   73: 		"\t-t <timeout>\tTimeout of login if no activity (default is 300 sec)\n"
   74: 		"\t-k <key>\tService cipher key\n"
   75: 		"\t-u\t\tSwitch to unencrypted traffic between hosts\n"
   76: 		"\t-b\t\tRun into batch mode (default is daemon mode)\n"
   77: 		"\t-v\t\tVerbose (more -v, more verbosity ...)\n"
   78: 		"\t-h\t\tThis help screen!\n"
   79: 		"\n", compiled, compiledby, compilehost);
   80: }
   81: 
   82: static void
   83: sig(int s)
   84: {
   85: 	int state;
   86: 	pid_t pid;
   87: 
   88: 	switch (s) {
   89: 		case SIGHUP:
   90: 			VERB(1) LOG("Got SIGHUP!\n");
   91: 			break;
   92: 		case SIGTERM:
   93: 			Kill++;
   94: 			VERB(1) LOG("Got SIGTERM!\n");
   95: 			break;
   96: 		case SIGPIPE:
   97: 			VERB(1) LOG("Got SIGPIPE!\n");
   98: 			break;
   99: 		case SIGCHLD:
  100: 			VERB(1) LOG("Got SIGCHLD!\n");
  101: 			while ((pid = waitpid(-1, &state, WNOHANG)) > 0)
  102: 				stopProcess(root, &pH, pid, icmpTx);
  103: 			break;
  104: 	}
  105: }
  106: 
  107: static void *
  108: hook_error(void *root, void *arg)
  109: {
  110: /*	sched_root_task_t *r = root; */
  111: 
  112: 	if (!root)
  113: 		return (void*) -1;
  114: 
  115: 	if (arg == (void*) EINTR)
  116: 		return (void*) -1;
  117: 
  118: 	return NULL;
  119: }
  120: 
  121: int
  122: main(int argc, char **argv)
  123: {
  124: 	sockaddr_t sa;
  125: 	struct hostent *host;
  126: 	struct passwd *pass;
  127: 	int fd, h = 0, uid = 0, gid = 0;
  128: 	long id = ANSH_ID;
  129: 	char ch, szUser[STRSIZ] = "root", szChroot[STRSIZ] = "/";
  130: 	struct sigaction sact;
  131: 
  132: 	memset(&sa, 0, sizeof sa);
  133: 	strlcpy(Key, DEFAULT_KEY, sizeof Key);
  134: 
  135: 	while ((ch = getopt(argc, argv, "hvubt:a:i:U:C:k:")) != -1)
  136: 		switch (ch) {
  137: 			case 'U':
  138: 				pass = getpwnam(optarg);
  139: 				if (!pass) {
  140: 					printf("Error:: User %s not found!\n", optarg);
  141: 					return 1;
  142: 				} else {
  143: 					strlcpy(szUser, optarg, sizeof szUser);
  144: 					uid = pass->pw_uid;
  145: 					gid = pass->pw_gid;
  146: 				}
  147: 				endpwent();
  148: 				break;
  149: 			case 'C':
  150: 				if (access(optarg, R_OK)) {
  151: 					printf("Error:: in chroot %s #%d - %s\n", optarg, errno, strerror(errno));
  152: 					return 1;
  153: 				} else
  154: 					strlcpy(szChroot, optarg, sizeof szChroot);
  155: 				break;
  156: 			case 'i':
  157: 				id = strtol(optarg, NULL, 0);
  158: 				break;
  159: 			case 't':
  160: 				Timeout = abs(strtol(optarg, NULL, 0));
  161: 				break;
  162: 			case 'k':
  163: 				strlcpy(Key, optarg, sizeof Key);
  164: 				break;
  165: 			case 'a':
  166: 				host = gethostbyname(optarg);
  167: 				if (!host) {
  168: 					printf("Error:: in bind address '%s' #%d - %s\n", 
  169: 							optarg, h_errno, hstrerror(h_errno));
  170: 					return 1;
  171: 				}
  172: 				switch (host->h_addrtype) {
  173: 					case AF_INET:
  174: 						sa.sin.sin_len = sizeof(struct sockaddr_in);
  175: 						sa.sin.sin_family = AF_INET;
  176: 						memcpy(&sa.sin.sin_addr.s_addr, host->h_addr, host->h_length);
  177: 						break;
  178: 					case AF_INET6:
  179: 						sa.sin6.sin6_len = sizeof(struct sockaddr_in6);
  180: 						sa.sin6.sin6_family = AF_INET6;
  181: 						memcpy(&sa.sin6.sin6_addr.s6_addr, host->h_addr, host->h_length);
  182: 						break;
  183: 					default:
  184: 						printf("Error:: Unknown address type %d !!!\n", host->h_addrtype);
  185: 						return 1;
  186: 				}
  187: 				break;
  188: 			case 'u':
  189: 				Crypted ^= Crypted;
  190: 				break;
  191: 			case 'b':
  192: 				Daemon ^= Daemon;
  193: 				break;
  194: 			case 'v':
  195: 				Verbose++;
  196: 				break;
  197: 			case 'h':
  198: 			default:
  199: 				Usage();
  200: 				return 1;
  201: 		}
  202: 	argc -= optind;
  203: 	argv += optind;
  204: 
  205: 	/* sanity check for openned descriptor */
  206: 	if (!sa.sa.sa_family) {
  207: 		sa.sin.sin_len = sizeof(struct sockaddr_in);
  208: 		sa.sin.sin_family = AF_INET;
  209: 	}
  210: 
  211: 	/* catch signals */
  212: 	memset(&sact, 0, sizeof sact);
  213: 	sigemptyset(&sact.sa_mask);
  214: 	sact.sa_handler = sig;
  215: 	sigaction(SIGPIPE, &sact, NULL);
  216: 	sigaction(SIGCHLD, &sact, NULL);
  217: 	sigaction(SIGTERM, &sact, NULL);
  218: 	sigaction(SIGHUP, &sact, NULL);
  219: 
  220: 	openlog("ansh3d", LOG_CONS | LOG_PID, LOG_DAEMON);
  221: 
  222: 	if (Daemon) {
  223: 		switch (fork()) {
  224: 			case -1:
  225: 				ERR("Daemon mode #%d - %s\n", errno, strerror(errno));
  226: 				closelog();
  227: 				return 1;
  228: 			case 0:
  229: 				VERB(1) LOG("Welcome to dark ...\n");
  230: 
  231: 				setsid();
  232: 
  233: 				fd = open("/dev/null", O_WRONLY);
  234: 				if (fd) {
  235: 					dup2(fd, STDIN_FILENO);
  236: 					dup2(fd, STDOUT_FILENO);
  237: 					dup2(fd, STDERR_FILENO);
  238: 					if (fd > 2)
  239: 						close(fd);
  240: 				}
  241: 				break;
  242: 			default:
  243: 				VERB(1) LOG("Going to shadow land ...\n");
  244: 				closelog();
  245: 				return 0;
  246: 		}
  247: 	}
  248: 
  249: 	if (ioCreatePIDFile(PIDFILE_ANSH3D, 42)) {
  250: 		ERR("Error:: already started ansh3d service ...\n");
  251: 		closelog();
  252: 		return 1;
  253: 	}
  254: 
  255: 	h = PrepareL3(&sa, &bpfLEN);
  256: 	if (h == -1) {
  257: 		ERR("Error:: Descriptor not opened ... abort!\n");
  258: 		unlink(PIDFILE_ANSH3D);
  259: 		closelog();
  260: 		return 2;
  261: 	}
  262: 
  263: 	SLIST_INIT(&pH);
  264: 	if (!(proc = InitProc(h, NULL, id, bpfLEN))) {
  265: 		ERR("Error:: Not enough memory ...\n");
  266: 		close(h);
  267: 		unlink(PIDFILE_ANSH3D);
  268: 		closelog();
  269: 		return 3;
  270: 	}
  271: 
  272: 	root = schedBegin();
  273: 	if (!root) {
  274: 		ERR("Scheduler not init #%d - %s\n", sched_GetErrno(), sched_GetError());
  275: 		DestroyProc(id);
  276: 		close(h);
  277: 		unlink(PIDFILE_ANSH3D);
  278: 		closelog();
  279: 		return 4;
  280: 	} else
  281: 		root->root_hooks.hook_root.error = hook_error;
  282: 
  283: 	chdir("/");
  284: 	chroot(szChroot);
  285: 
  286: 	setgid(gid);
  287: 	setuid(uid);
  288: 
  289: 	if (schedRead(root, icmpRx, (void*) id, h, NULL, 0)) {
  290: 		schedRun(root, &Kill);
  291: 	} else
  292: 		ERR("Failed to add reader task #%d - %s\n", sched_GetErrno(), sched_GetError());
  293: 
  294: 	VERB(1) LOG("Finish process.");
  295: 	schedEnd(&root);
  296: 	DestroyProc(id);
  297: 	close(h);
  298: 	unlink(PIDFILE_ANSH3D);
  299: 	closelog();
  300: 	return 0;
  301: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>