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

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

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