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

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