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

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