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

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