Annotation of ansh/src/daemon3.c, revision 1.1.1.1.2.5

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.5! misho       6:  * $Id: daemon3.c,v 1.1.1.1.2.4 2011/10/13 14:29:30 misho Exp $
1.1       misho       7:  *
                      8:  *************************************************************************/
                      9: #include "global.h"
                     10: #include "anshd.h"
                     11: 
                     12: 
                     13: void *
                     14: icmpTx(sched_task_t *task)
                     15: {
                     16:        struct tagProc *proc;
                     17:        int wlen;
1.1.1.1.2.1  misho      18:        u_char *str;
1.1       misho      19: 
                     20:        FTRACE(3);
                     21: 
                     22:        /* not found argument, drop data */
                     23:        if (!(proc = TASK_ARG(task)))
                     24:                return (void*) -1;
                     25: 
1.1.1.1.2.1  misho      26:        if (Crypted) {
                     27:                str = cryptBuffer(proc->proc_buf_[FD2NET], proc->proc_rlen_[FD2NET], Crypted);
                     28:                if (str) {
                     29:                        memcpy(proc->proc_buf_[FD2NET], str, proc->proc_rlen_[FD2NET]);
                     30:                        free(str);
                     31:                }
                     32:        }
                     33: 
1.1.1.1.2.4  misho      34:        if ((wlen = icmpSend(TASK_FD(task), ++proc->proc_seq, proc->proc_id, proc->proc_flg, Crypted, 
                     35:                                        proc->proc_buf_[FD2NET], proc->proc_rlen_[FD2NET], &proc->proc_cli, 
                     36:                                        sizeof proc->proc_cli)) != ANSH_FLG_ERR) {
1.1       misho      37:                proc->proc_flg = ANSH_FLG_OK;
                     38:                proc->proc_rlen_[FD2NET] = 0;
                     39:        }
                     40:        VERB(5) LOG("Sended %d bytes", wlen);
                     41: 
                     42:        return NULL;
                     43: }
                     44: 
                     45: void *
                     46: icmpRx(sched_task_t *task)
                     47: {
1.1.1.1.2.1  misho      48:        u_char *buf, *str;
1.1       misho      49:        struct sockaddr sa;
                     50:        int rlen, n = 0, salen = sizeof sa;
                     51:        struct tagProc *proc = NULL;
                     52:        char ret;
                     53:        u_short id, *b;
1.1.1.1.2.4  misho      54:        u_int seq;
1.1       misho      55: 
                     56:        FTRACE(3);
                     57: 
                     58:        rlen = bpfLEN;
                     59:        if (!(buf = malloc(rlen)))
                     60:                goto end;
1.1.1.1.2.5! misho      61:        else
        !            62:                memset(buf, 0, rlen);
1.1       misho      63: 
1.1.1.1.2.4  misho      64:        if ((ret = icmpRecv(TASK_FD(task), &seq, &id, &Crypted, buf, &rlen, &sa, 
                     65:                                        (socklen_t *) &salen)) == ANSH_FLG_ERR)
1.1       misho      66:                goto end;
1.1.1.1.2.4  misho      67:        VERB(5) LOG("Received %d bytes %d", rlen, seq);
1.1       misho      68:        if (!(ret & ANSH_FLG_CPOUT))
                     69:                goto end;
                     70: 
                     71:        /* packet is ok find active session */
                     72:        SLIST_FOREACH(proc, &pH, proc_next)
                     73:                if (proc->proc_id == id) {
                     74:                        n = ANSH_CODE;
                     75:                        break;
                     76:                }
                     77:        /* not found in sessions, drop packet */
                     78:        if (n != ANSH_CODE) {
                     79:                proc = NULL;
                     80:                goto end;
                     81:        }
                     82: 
1.1.1.1.2.1  misho      83:        if (Crypted) {
                     84:                str = cryptBuffer(buf, rlen, Crypted);
                     85:                if (str) {
                     86:                        memcpy(buf, str, rlen);
                     87:                        free(str);
                     88:                }
                     89:        }
                     90: 
1.1       misho      91:        switch (ret) {
                     92:                case ANSH_FLG_EOF:
                     93:                case ANSH_FLG_CPOUT:
1.1.1.1.2.4  misho      94:                        if (seq <= proc->proc_seq)
                     95:                                goto end;
                     96:                        else if (seq > (proc->proc_seq + 1))
                     97:                                LOG("LOST PACKET(s) detect: %d; received seq=%d - %d", 
                     98:                                                seq - proc->proc_seq + 1, seq, proc->proc_seq);
                     99:                        proc->proc_seq = seq;
1.1       misho     100:                        break;
                    101:                case ANSH_FLG_WINZ:
                    102:                        b = (u_short*) buf;
                    103:                        ioChgWinPTY(proc->proc_pty, ntohs(b[0]), ntohs(b[1]), ntohs(b[2]), ntohs(b[3]));
                    104:                        /* if not started login, lets start & go! */
                    105:                        if (!proc->proc_pid) {
                    106:                                memcpy(&proc->proc_cli, &sa, sizeof sa);
                    107:                                spawnLogin(task, proc);
                    108:                        }
                    109:                default:
                    110:                        goto end;
                    111:        }
                    112: 
                    113:        proc->proc_flg = ret;
                    114:        proc->proc_rlen_[NET2FD] = rlen;
                    115:        memset(proc->proc_buf_[NET2FD], 0, proc->proc_blen);
                    116:        memcpy(proc->proc_buf_[NET2FD], buf, proc->proc_rlen_[NET2FD]);
                    117:        schedWrite(TASK_ROOT(task), fdTx, proc, proc->proc_pty);
                    118: end:
                    119:        free(buf);
                    120:        schedRead(TASK_ROOT(task), icmpRx, NULL, proc ? proc->proc_sock : TASK_FD(task));
                    121:        return NULL;
                    122: }
                    123: 
                    124: void *
                    125: fdTx(sched_task_t *task)
                    126: {
                    127:        struct tagProc *proc;
                    128:        struct timeval tv = { 0 };
                    129:        int wlen;
                    130: 
                    131:        FTRACE(3);
                    132: 
                    133:        /* not found argument, drop data */
                    134:        if (!(proc = TASK_ARG(task)))
                    135:                return (void*) -1;
                    136: 
                    137:        /* if != ANSH_FLG_CPOUT isnt received from client */
                    138:        if (proc->proc_flg != ANSH_FLG_CPOUT || !proc->proc_pid)
                    139:                return NULL;
                    140: 
                    141:        if (waitpid(proc->proc_pid, &wlen, WNOHANG)) {
                    142:                ioFreePTY(TASK_FD(task), proc->proc_ttyname);
                    143:                schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
                    144: 
                    145:                proc->proc_pid = 0;
1.1.1.1.2.4  misho     146:                proc->proc_seq = 0;
1.1       misho     147:                proc->proc_flg = ANSH_FLG_EOF;
                    148:                proc->proc_rlen_[FD2NET] = 0;
                    149: 
                    150:                schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
                    151:                return NULL;
                    152:        }
                    153: 
                    154:        /* if Timeout defined, disarm timer */
                    155:        if (Timeout)
                    156:                schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
                    157: 
                    158:        wlen = write(TASK_FD(task), proc->proc_buf_[NET2FD], proc->proc_rlen_[NET2FD]);
                    159:        switch (wlen) {
                    160:                case -1:
                    161:                        ERR("write2tty #%d - %s", errno, strerror(errno));
                    162:                        /* exit from shell and release tty */
                    163:                        waitpid(proc->proc_pid, &wlen, 0);
                    164:                        ioFreePTY(TASK_FD(task), proc->proc_ttyname);
                    165:                        schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
                    166: 
                    167:                        proc->proc_pid = 0;
1.1.1.1.2.4  misho     168:                        proc->proc_seq = 0;
1.1       misho     169:                        proc->proc_flg = ANSH_FLG_EOF;
                    170:                        proc->proc_rlen_[FD2NET] = 0;
                    171: 
                    172:                        schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
                    173:                        return NULL;
                    174:                default:
                    175:                        proc->proc_flg = ANSH_FLG_OK;
                    176:                        proc->proc_rlen_[NET2FD] = 0;
                    177:        }
                    178:        VERB(3) LOG("Writed %d bytes - %s", wlen, proc->proc_buf_[NET2FD]);
                    179: 
                    180:        /* if Timeout defined, go arm timer */
                    181:        if (Timeout) {
                    182:                tv.tv_sec = Timeout;
                    183:                schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
                    184:        }
                    185:        return NULL;
                    186: }
                    187: 
                    188: void *
                    189: fdRx(sched_task_t *task)
                    190: {
                    191:        struct tagProc *proc;
                    192:        struct timeval tv = { 0 };
                    193:        int rlen;
                    194: 
                    195:        FTRACE(3);
                    196: 
                    197:        /* not found argument, drop data */
                    198:        if (!(proc = TASK_ARG(task)))
                    199:                return (void*) -1;
                    200:        if (!proc->proc_pid)
                    201:                return NULL;
                    202: 
                    203:        if (waitpid(proc->proc_pid, &rlen, WNOHANG)) {
                    204:                ioFreePTY(TASK_FD(task), proc->proc_ttyname);
                    205:                schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
                    206: 
                    207:                proc->proc_pid = 0;
1.1.1.1.2.4  misho     208:                proc->proc_seq = 0;
1.1       misho     209:                proc->proc_flg = ANSH_FLG_EOF;
                    210:                proc->proc_rlen_[FD2NET] = 0;
                    211: 
                    212:                schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
                    213:                return NULL;
                    214:        }
                    215: 
                    216:        /* if Timeout defined, disarm timer */
                    217:        if (Timeout)
                    218:                schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
                    219: 
                    220:        memset(proc->proc_buf_[FD2NET], 0, proc->proc_blen);
1.1.1.1.2.3  misho     221:        rlen = read(TASK_FD(task), proc->proc_buf_[FD2NET], 
                    222:                        proc->proc_blen - sizeof(struct icmp) + sizeof(struct ansh_hdr));
1.1       misho     223:        switch (rlen) {
                    224:                case -1:
                    225:                        ERR("readtty #%d - %s", errno, strerror(errno));
                    226:                case 0:
                    227:                        /* exit from shell and release tty */
                    228:                        waitpid(proc->proc_pid, &rlen, 0);
                    229:                        ioFreePTY(TASK_FD(task), proc->proc_ttyname);
                    230:                        schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
                    231:                        VERB(3) LOG("EOF process status %d", rlen);
                    232: 
                    233:                        proc->proc_pid = 0;
1.1.1.1.2.4  misho     234:                        proc->proc_seq = 0;
1.1       misho     235:                        proc->proc_flg = ANSH_FLG_EOF;
                    236:                        proc->proc_rlen_[FD2NET] = 0;
                    237: 
                    238:                        schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
                    239:                        return NULL;
                    240:                default:
                    241:                        proc->proc_flg = ANSH_FLG_OK;
                    242:                        proc->proc_rlen_[FD2NET] = rlen;
                    243:        }
                    244:        VERB(3) LOG("Readed %d bytes - %s", rlen, proc->proc_buf_[FD2NET]);
                    245: 
                    246:        schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
                    247:        schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
                    248: 
                    249:        /* if Timeout defined, go arm timer */
                    250:        if (Timeout) {
                    251:                tv.tv_sec = Timeout;
                    252:                schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
                    253:        }
                    254:        return NULL;
                    255: }
                    256: 
                    257: int
                    258: spawnLogin(sched_task_t *task, struct tagProc *proc)
                    259: {
                    260:        int flg;
                    261:        struct timeval tv = { 0 };
                    262:        char str[STRSIZ] = { 0 };
                    263:        struct sockaddr_in *sin;
                    264:        struct sockaddr_in6 *sin6;
                    265: 
                    266:        FTRACE(3);
                    267: 
                    268:        assert(proc);
                    269: 
                    270:        switch ((proc->proc_pid = ioForkPTY(&proc->proc_pty, proc->proc_ttyname, 
                    271:                                        sizeof proc->proc_ttyname, NULL, NULL, NULL))) {
                    272:                case -1:
                    273:                        ERR("ioForkPTY() #%d - %s", io_GetErrno(), io_GetError());
                    274:                        return -1;
                    275:                case 0:
                    276:                        printf("ansh3d ELWIX remote management system over ICMP (%s)\n\n", 
                    277:                                        proc->proc_ttyname);
                    278:                        strlcpy(str, "-hansh3@", sizeof str);
                    279:                        if (proc->proc_cli.sa_family == AF_INET) {
                    280:                                sin = (struct sockaddr_in*) &proc->proc_cli;
                    281:                                inet_ntop(AF_INET, &sin->sin_addr, str + 8, INET_ADDRSTRLEN);
1.1.1.1.2.2  misho     282:                        } else if (proc->proc_cli.sa_family == AF_INET6) {
1.1       misho     283:                                sin6 = (struct sockaddr_in6*) &proc->proc_cli;
                    284:                                inet_ntop(AF_INET6, &sin6->sin6_addr, str + 8, INET6_ADDRSTRLEN);
                    285:                        }
                    286:                        execl("/usr/bin/login", "login", str, NULL);
                    287:                        /* never reached */
                    288:                        return -1;
                    289:                default:
                    290:                        flg = fcntl(proc->proc_pty, F_GETFL);
                    291:                        fcntl(proc->proc_pty, F_SETFL, flg | O_NONBLOCK);
                    292: 
                    293:                        VERB(3) LOG("Parent know child pid %d", proc->proc_pid);
                    294:                        schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
                    295: 
                    296:                        /* if Timeout defined, go arm timer */
                    297:                        if (Timeout) {
                    298:                                tv.tv_sec = Timeout;
                    299:                                schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
                    300:                        }
                    301:                        break;
                    302:        }
                    303: 
                    304:        return 0;
                    305: }

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