Annotation of ansh/src/ansh3d.c, revision 1.1

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

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