Annotation of ansh/src/daemon2.c, revision 1.1.1.1.2.7

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.7! misho       6:  * $Id: daemon2.c,v 1.1.1.1.2.6 2011/10/13 16:08:52 misho Exp $
1.1       misho       7:  *
1.1.1.1.2.6  misho       8:  *************************************************************************
                      9: The ELWIX and AITNET software is distributed under the following
                     10: terms:
                     11: 
                     12: All of the documentation and software included in the ELWIX and AITNET
                     13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
                     14: 
                     15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
                     16:        by Michael Pounov <misho@elwix.org>.  All rights reserved.
                     17: 
                     18: Redistribution and use in source and binary forms, with or without
                     19: modification, are permitted provided that the following conditions
                     20: are met:
                     21: 1. Redistributions of source code must retain the above copyright
                     22:    notice, this list of conditions and the following disclaimer.
                     23: 2. Redistributions in binary form must reproduce the above copyright
                     24:    notice, this list of conditions and the following disclaimer in the
                     25:    documentation and/or other materials provided with the distribution.
                     26: 3. All advertising materials mentioning features or use of this software
                     27:    must display the following acknowledgement:
                     28: This product includes software developed by Michael Pounov <misho@elwix.org>
                     29: ELWIX - Embedded LightWeight unIX and its contributors.
                     30: 4. Neither the name of AITNET nor the names of its contributors
                     31:    may be used to endorse or promote products derived from this software
                     32:    without specific prior written permission.
                     33: 
                     34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
                     35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     44: SUCH DAMAGE.
                     45: */
1.1       misho      46: #include "global.h"
                     47: #include "anshd.h"
                     48: 
                     49: 
                     50: void *
                     51: pktTx(sched_task_t *task)
                     52: {
                     53:        struct tagProc *proc;
                     54:        int wlen;
1.1.1.1.2.1  misho      55:        u_char *str;
1.1       misho      56: 
                     57:        FTRACE(3);
                     58: 
                     59:        /* not found argument, drop data */
                     60:        if (!(proc = TASK_ARG(task)))
                     61:                return (void*) -1;
                     62: 
1.1.1.1.2.1  misho      63:        if (Crypted) {
                     64:                str = cryptBuffer(proc->proc_buf_[FD2NET], proc->proc_rlen_[FD2NET], Crypted);
                     65:                if (str) {
                     66:                        memcpy(proc->proc_buf_[FD2NET], str, proc->proc_rlen_[FD2NET]);
                     67:                        free(str);
                     68:                }
                     69:        }
                     70: 
1.1.1.1.2.4  misho      71:        if ((wlen = pktSend(TASK_FD(task), ++proc->proc_seq, proc->proc_flg, Crypted, 
                     72:                                        proc->proc_buf_[FD2NET], proc->proc_rlen_[FD2NET], 
                     73:                                        &proc->proc_ea)) != ANSH_FLG_ERR) {
1.1       misho      74:                proc->proc_flg = ANSH_FLG_OK;
                     75:                proc->proc_rlen_[FD2NET] = 0;
                     76:        }
                     77:        VERB(5) LOG("Sended %d bytes", wlen);
                     78: 
                     79:        return NULL;
                     80: }
                     81: 
                     82: void *
                     83: pktRx(sched_task_t *task)
                     84: {
1.1.1.1.2.1  misho      85:        u_char *buf, *str;
1.1       misho      86:        struct ether_header eth;
                     87:        int rlen, n = 0;
                     88:        struct tagProc *proc = NULL;
                     89:        char ret;
                     90:        u_short *b;
1.1.1.1.2.4  misho      91:        u_int seq;
1.1       misho      92: 
                     93:        FTRACE(3);
                     94: 
                     95:        rlen = bpfLEN;
                     96:        if (!(buf = malloc(rlen)))
                     97:                goto end;
1.1.1.1.2.5  misho      98:        else
                     99:                memset(buf, 0, rlen);
1.1       misho     100: 
1.1.1.1.2.4  misho     101:        if ((ret = pktRecv(TASK_FD(task), &seq, &Crypted, buf, &rlen, &eth)) == ANSH_FLG_ERR)
1.1       misho     102:                goto end;
                    103:        VERB(5) LOG("Received %d bytes", rlen);
1.1.1.1.2.1  misho     104:        if (!(ret & ANSH_FLG_CPOUT))
                    105:                goto end;
1.1       misho     106: 
                    107:        /* packet is ok find active session */
                    108:        SLIST_FOREACH(proc, &pH, proc_next)
                    109:                if (proc->proc_id == ntohs(eth.ether_type)) {
                    110:                        n = ANSH_CODE;
                    111:                        break;
                    112:                }
                    113:        /* not found in sessions, drop packet */
1.1.1.1.2.1  misho     114:        if (n != ANSH_CODE) {
                    115:                proc = NULL;
1.1       misho     116:                goto end;
1.1.1.1.2.1  misho     117:        }
                    118: 
                    119:        if (Crypted) {
                    120:                str = cryptBuffer(buf, rlen, Crypted);
                    121:                if (str) {
                    122:                        memcpy(buf, str, rlen);
                    123:                        free(str);
                    124:                }
                    125:        }
1.1       misho     126: 
                    127:        switch (ret) {
                    128:                case ANSH_FLG_EOF:
                    129:                case ANSH_FLG_CPOUT:
1.1.1.1.2.4  misho     130:                        if (seq <= proc->proc_seq)
                    131:                                goto end;
                    132:                        else if (seq > (proc->proc_seq + 1))
                    133:                                LOG("LOST PACKET(s) detect: %d; received seq=%d - %d", 
                    134:                                                seq - proc->proc_seq + 1, seq, proc->proc_seq);
                    135:                        proc->proc_seq = seq;
1.1       misho     136:                        break;
                    137:                case ANSH_FLG_WINZ:
                    138:                        b = (u_short*) buf;
1.1.1.1.2.1  misho     139:                        ioChgWinPTY(proc->proc_pty, ntohs(b[0]), ntohs(b[1]), ntohs(b[2]), ntohs(b[3]));
1.1       misho     140:                        /* if not started login, lets start & go! */
                    141:                        if (!proc->proc_pid) {
1.1.1.1.2.7! misho     142:                                memcpy(&proc->proc_ea, &eth.ether_shost, ETHER_ADDR_LEN);
1.1       misho     143:                                spawnLogin(task, proc);
                    144:                        }
                    145:                default:
                    146:                        goto end;
                    147:        }
                    148: 
                    149:        proc->proc_flg = ret;
                    150:        proc->proc_rlen_[NET2FD] = rlen;
                    151:        memset(proc->proc_buf_[NET2FD], 0, proc->proc_blen);
                    152:        memcpy(proc->proc_buf_[NET2FD], buf, proc->proc_rlen_[NET2FD]);
                    153:        schedWrite(TASK_ROOT(task), fdTx, proc, proc->proc_pty);
                    154: end:
                    155:        free(buf);
                    156:        schedRead(TASK_ROOT(task), pktRx, NULL, proc ? proc->proc_sock : TASK_FD(task));
                    157:        return NULL;
                    158: }
                    159: 
                    160: void *
                    161: fdTx(sched_task_t *task)
                    162: {
                    163:        struct tagProc *proc;
1.1.1.1.2.1  misho     164:        struct timeval tv = { 0 };
1.1       misho     165:        int wlen;
                    166: 
                    167:        FTRACE(3);
                    168: 
                    169:        /* not found argument, drop data */
                    170:        if (!(proc = TASK_ARG(task)))
                    171:                return (void*) -1;
                    172: 
                    173:        /* if != ANSH_FLG_CPOUT isnt received from client */
1.1.1.1.2.1  misho     174:        if (proc->proc_flg != ANSH_FLG_CPOUT || !proc->proc_pid)
1.1       misho     175:                return NULL;
                    176: 
                    177:        if (waitpid(proc->proc_pid, &wlen, WNOHANG)) {
                    178:                ioFreePTY(TASK_FD(task), proc->proc_ttyname);
1.1.1.1.2.1  misho     179:                schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
1.1       misho     180: 
                    181:                proc->proc_pid = 0;
1.1.1.1.2.4  misho     182:                proc->proc_seq = 0;
1.1       misho     183:                proc->proc_flg = ANSH_FLG_EOF;
                    184:                proc->proc_rlen_[FD2NET] = 0;
                    185: 
1.1.1.1.2.2  misho     186:                schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1       misho     187:                return NULL;
                    188:        }
                    189: 
1.1.1.1.2.1  misho     190:        /* if Timeout defined, disarm timer */
                    191:        if (Timeout)
                    192:                schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
                    193: 
1.1       misho     194:        wlen = write(TASK_FD(task), proc->proc_buf_[NET2FD], proc->proc_rlen_[NET2FD]);
                    195:        switch (wlen) {
                    196:                case -1:
                    197:                        ERR("write2tty #%d - %s", errno, strerror(errno));
                    198:                        /* exit from shell and release tty */
                    199:                        waitpid(proc->proc_pid, &wlen, 0);
                    200:                        ioFreePTY(TASK_FD(task), proc->proc_ttyname);
1.1.1.1.2.1  misho     201:                        schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
1.1       misho     202: 
                    203:                        proc->proc_pid = 0;
1.1.1.1.2.4  misho     204:                        proc->proc_seq = 0;
1.1       misho     205:                        proc->proc_flg = ANSH_FLG_EOF;
                    206:                        proc->proc_rlen_[FD2NET] = 0;
                    207: 
1.1.1.1.2.2  misho     208:                        schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1       misho     209:                        return NULL;
                    210:                default:
                    211:                        proc->proc_flg = ANSH_FLG_OK;
                    212:                        proc->proc_rlen_[NET2FD] = 0;
                    213:        }
                    214:        VERB(3) LOG("Writed %d bytes - %s", wlen, proc->proc_buf_[NET2FD]);
                    215: 
1.1.1.1.2.1  misho     216:        /* if Timeout defined, go arm timer */
                    217:        if (Timeout) {
                    218:                tv.tv_sec = Timeout;
                    219:                schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
                    220:        }
1.1       misho     221:        return NULL;
                    222: }
                    223: 
                    224: void *
                    225: fdRx(sched_task_t *task)
                    226: {
                    227:        struct tagProc *proc;
1.1.1.1.2.1  misho     228:        struct timeval tv = { 0 };
1.1       misho     229:        int rlen;
                    230: 
                    231:        FTRACE(3);
                    232: 
                    233:        /* not found argument, drop data */
                    234:        if (!(proc = TASK_ARG(task)))
                    235:                return (void*) -1;
1.1.1.1.2.1  misho     236:        if (!proc->proc_pid)
                    237:                return NULL;
1.1       misho     238: 
                    239:        if (waitpid(proc->proc_pid, &rlen, WNOHANG)) {
                    240:                ioFreePTY(TASK_FD(task), proc->proc_ttyname);
1.1.1.1.2.1  misho     241:                schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
1.1       misho     242: 
                    243:                proc->proc_pid = 0;
1.1.1.1.2.4  misho     244:                proc->proc_seq = 0;
1.1       misho     245:                proc->proc_flg = ANSH_FLG_EOF;
                    246:                proc->proc_rlen_[FD2NET] = 0;
                    247: 
1.1.1.1.2.2  misho     248:                schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1       misho     249:                return NULL;
                    250:        }
                    251: 
1.1.1.1.2.1  misho     252:        /* if Timeout defined, disarm timer */
                    253:        if (Timeout)
                    254:                schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
                    255: 
1.1       misho     256:        memset(proc->proc_buf_[FD2NET], 0, proc->proc_blen);
1.1.1.1.2.3  misho     257:        rlen = read(TASK_FD(task), proc->proc_buf_[FD2NET], 
                    258:                        proc->proc_blen - ETHER_HDR_LEN + sizeof(struct ansh_hdr));
1.1       misho     259:        switch (rlen) {
                    260:                case -1:
                    261:                        ERR("readtty #%d - %s", errno, strerror(errno));
                    262:                case 0:
                    263:                        /* exit from shell and release tty */
                    264:                        waitpid(proc->proc_pid, &rlen, 0);
                    265:                        ioFreePTY(TASK_FD(task), proc->proc_ttyname);
1.1.1.1.2.1  misho     266:                        schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
                    267:                        VERB(3) LOG("EOF process status %d", rlen);
1.1       misho     268: 
                    269:                        proc->proc_pid = 0;
1.1.1.1.2.4  misho     270:                        proc->proc_seq = 0;
1.1       misho     271:                        proc->proc_flg = ANSH_FLG_EOF;
                    272:                        proc->proc_rlen_[FD2NET] = 0;
                    273: 
1.1.1.1.2.2  misho     274:                        schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1       misho     275:                        return NULL;
                    276:                default:
                    277:                        proc->proc_flg = ANSH_FLG_OK;
                    278:                        proc->proc_rlen_[FD2NET] = rlen;
                    279:        }
                    280:        VERB(3) LOG("Readed %d bytes - %s", rlen, proc->proc_buf_[FD2NET]);
                    281: 
1.1.1.1.2.2  misho     282:        schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1       misho     283:        schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
1.1.1.1.2.1  misho     284: 
                    285:        /* if Timeout defined, go arm timer */
                    286:        if (Timeout) {
                    287:                tv.tv_sec = Timeout;
                    288:                schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
                    289:        }
1.1       misho     290:        return NULL;
                    291: }
                    292: 
                    293: int
                    294: spawnLogin(sched_task_t *task, struct tagProc *proc)
                    295: {
1.1.1.1.2.1  misho     296:        int flg;
                    297:        struct timeval tv = { 0 };
                    298:        char str[STRSIZ] = { 0 };
                    299: 
1.1       misho     300:        FTRACE(3);
                    301: 
                    302:        assert(proc);
                    303: 
                    304:        switch ((proc->proc_pid = ioForkPTY(&proc->proc_pty, proc->proc_ttyname, 
                    305:                                        sizeof proc->proc_ttyname, NULL, NULL, NULL))) {
                    306:                case -1:
                    307:                        ERR("ioForkPTY() #%d - %s", io_GetErrno(), io_GetError());
                    308:                        return -1;
                    309:                case 0:
1.1.1.1.2.1  misho     310:                        printf("anshd ELWIX remote management system (%s)\n\n", proc->proc_ttyname);
                    311:                        strlcpy(str, "-hansh@", sizeof str);
1.1.1.1.2.7! misho     312:                        io_ether_ntoa((const struct io_ether_addr*) &proc->proc_ea, str + 7, 18);
1.1.1.1.2.1  misho     313: 
                    314:                        execl("/usr/bin/login", "login", str, NULL);
1.1       misho     315:                        /* never reached */
                    316:                        return -1;
                    317:                default:
1.1.1.1.2.1  misho     318:                        flg = fcntl(proc->proc_pty, F_GETFL);
                    319:                        fcntl(proc->proc_pty, F_SETFL, flg | O_NONBLOCK);
                    320: 
                    321:                        VERB(3) LOG("Parent know child pid %d", proc->proc_pid);
1.1       misho     322:                        schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
1.1.1.1.2.1  misho     323: 
                    324:                        /* if Timeout defined, go arm timer */
                    325:                        if (Timeout) {
                    326:                                tv.tv_sec = Timeout;
                    327:                                schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
                    328:                        }
1.1       misho     329:                        break;
                    330:        }
                    331: 
                    332:        return 0;
                    333: }

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