|
|
| version 1.1.1.1.2.3, 2011/10/13 11:01:37 | version 1.4, 2012/07/22 22:41:33 |
|---|---|
| Line 5 | Line 5 |
| * $Author$ | * $Author$ |
| * $Id$ | * $Id$ |
| * | * |
| *************************************************************************/ | ************************************************************************* |
| The ELWIX and AITNET software is distributed under the following | |
| terms: | |
| All of the documentation and software included in the ELWIX and AITNET | |
| Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> | |
| Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | |
| by Michael Pounov <misho@elwix.org>. All rights reserved. | |
| Redistribution and use in source and binary forms, with or without | |
| modification, are permitted provided that the following conditions | |
| are met: | |
| 1. Redistributions of source code must retain the above copyright | |
| notice, this list of conditions and the following disclaimer. | |
| 2. Redistributions in binary form must reproduce the above copyright | |
| notice, this list of conditions and the following disclaimer in the | |
| documentation and/or other materials provided with the distribution. | |
| 3. All advertising materials mentioning features or use of this software | |
| must display the following acknowledgement: | |
| This product includes software developed by Michael Pounov <misho@elwix.org> | |
| ELWIX - Embedded LightWeight unIX and its contributors. | |
| 4. Neither the name of AITNET nor the names of its contributors | |
| may be used to endorse or promote products derived from this software | |
| without specific prior written permission. | |
| THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND | |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| SUCH DAMAGE. | |
| */ | |
| #include "global.h" | #include "global.h" |
| #include "anshd.h" | #include "anshd.h" |
| Line 27 icmpTx(sched_task_t *task) | Line 64 icmpTx(sched_task_t *task) |
| str = cryptBuffer(proc->proc_buf_[FD2NET], proc->proc_rlen_[FD2NET], Crypted); | str = cryptBuffer(proc->proc_buf_[FD2NET], proc->proc_rlen_[FD2NET], Crypted); |
| if (str) { | if (str) { |
| memcpy(proc->proc_buf_[FD2NET], str, proc->proc_rlen_[FD2NET]); | memcpy(proc->proc_buf_[FD2NET], str, proc->proc_rlen_[FD2NET]); |
| free(str); | io_free(str); |
| } | } |
| } | } |
| if ((wlen = icmpSend(TASK_FD(task), proc->proc_id, proc->proc_flg, Crypted, proc->proc_buf_[FD2NET], | if ((wlen = icmpSend(TASK_FD(task), ++proc->proc_seq, proc->proc_id, proc->proc_flg, Crypted, |
| proc->proc_rlen_[FD2NET], &proc->proc_cli, sizeof proc->proc_cli)) != ANSH_FLG_ERR) { | proc->proc_buf_[FD2NET], proc->proc_rlen_[FD2NET], &proc->proc_cli, |
| sizeof proc->proc_cli)) != ANSH_FLG_ERR) { | |
| proc->proc_flg = ANSH_FLG_OK; | proc->proc_flg = ANSH_FLG_OK; |
| proc->proc_rlen_[FD2NET] = 0; | proc->proc_rlen_[FD2NET] = 0; |
| } | } |
| Line 45 void * | Line 83 void * |
| icmpRx(sched_task_t *task) | icmpRx(sched_task_t *task) |
| { | { |
| u_char *buf, *str; | u_char *buf, *str; |
| struct sockaddr sa; | io_sockaddr_t sa; |
| int rlen, n = 0, salen = sizeof sa; | int rlen, n = 0, salen = sizeof sa; |
| struct tagProc *proc = NULL; | struct tagProc *proc = NULL; |
| char ret; | char ret; |
| u_short id, *b; | u_short id, *b; |
| u_int seq; | |
| FTRACE(3); | FTRACE(3); |
| rlen = bpfLEN; | rlen = bpfLEN; |
| if (!(buf = malloc(rlen))) | if (!(buf = io_malloc(rlen))) |
| goto end; | goto end; |
| else | |
| memset(buf, 0, rlen); | |
| if ((ret = icmpRecv(TASK_FD(task), &id, &Crypted, buf, &rlen, &sa, (socklen_t *) &salen)) == ANSH_FLG_ERR) | if ((ret = icmpRecv(TASK_FD(task), &seq, &id, &Crypted, buf, &rlen, &sa, |
| (socklen_t *) &salen)) == ANSH_FLG_ERR) | |
| goto end; | goto end; |
| VERB(5) LOG("Received %d bytes", rlen); | VERB(5) LOG("Received %d bytes %d", rlen, seq); |
| if (!(ret & ANSH_FLG_CPOUT)) | if (!(ret & ANSH_FLG_CPOUT)) |
| goto end; | goto end; |
| Line 79 icmpRx(sched_task_t *task) | Line 121 icmpRx(sched_task_t *task) |
| str = cryptBuffer(buf, rlen, Crypted); | str = cryptBuffer(buf, rlen, Crypted); |
| if (str) { | if (str) { |
| memcpy(buf, str, rlen); | memcpy(buf, str, rlen); |
| free(str); | io_free(str); |
| } | } |
| } | } |
| switch (ret) { | switch (ret) { |
| case ANSH_FLG_EOF: | case ANSH_FLG_EOF: |
| case ANSH_FLG_CPOUT: | case ANSH_FLG_CPOUT: |
| if (seq <= proc->proc_seq) | |
| goto end; | |
| else if (seq > (proc->proc_seq + 1)) | |
| LOG("LOST PACKET(s) detect: %d; received seq=%d - %d", | |
| seq - proc->proc_seq + 1, seq, proc->proc_seq); | |
| proc->proc_seq = seq; | |
| break; | break; |
| case ANSH_FLG_WINZ: | case ANSH_FLG_WINZ: |
| b = (u_short*) buf; | b = (u_short*) buf; |
| Line 103 icmpRx(sched_task_t *task) | Line 151 icmpRx(sched_task_t *task) |
| proc->proc_rlen_[NET2FD] = rlen; | proc->proc_rlen_[NET2FD] = rlen; |
| memset(proc->proc_buf_[NET2FD], 0, proc->proc_blen); | memset(proc->proc_buf_[NET2FD], 0, proc->proc_blen); |
| memcpy(proc->proc_buf_[NET2FD], buf, proc->proc_rlen_[NET2FD]); | memcpy(proc->proc_buf_[NET2FD], buf, proc->proc_rlen_[NET2FD]); |
| schedWrite(TASK_ROOT(task), fdTx, proc, proc->proc_pty); | schedWrite(TASK_ROOT(task), fdTx, proc, proc->proc_pty, NULL, 0); |
| end: | end: |
| free(buf); | io_free(buf); |
| schedRead(TASK_ROOT(task), icmpRx, NULL, proc ? proc->proc_sock : TASK_FD(task)); | schedRead(TASK_ROOT(task), icmpRx, NULL, proc ? proc->proc_sock : TASK_FD(task), NULL, 0); |
| return NULL; | return NULL; |
| } | } |
| Line 114 void * | Line 162 void * |
| fdTx(sched_task_t *task) | fdTx(sched_task_t *task) |
| { | { |
| struct tagProc *proc; | struct tagProc *proc; |
| struct timeval tv = { 0 }; | struct timespec ts = { 0 }; |
| int wlen; | int wlen; |
| FTRACE(3); | FTRACE(3); |
| Line 127 fdTx(sched_task_t *task) | Line 175 fdTx(sched_task_t *task) |
| if (proc->proc_flg != ANSH_FLG_CPOUT || !proc->proc_pid) | if (proc->proc_flg != ANSH_FLG_CPOUT || !proc->proc_pid) |
| return NULL; | return NULL; |
| if (waitpid(proc->proc_pid, &wlen, WNOHANG)) { | |
| ioFreePTY(TASK_FD(task), proc->proc_ttyname); | |
| schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL); | |
| proc->proc_pid = 0; | |
| proc->proc_flg = ANSH_FLG_EOF; | |
| proc->proc_rlen_[FD2NET] = 0; | |
| schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock); | |
| return NULL; | |
| } | |
| /* if Timeout defined, disarm timer */ | /* if Timeout defined, disarm timer */ |
| if (Timeout) | if (Timeout) |
| schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL); | schedCancelby(TASK_ROOT(task), taskTIMER, CRITERIA_CALL, TOfunc, NULL); |
| wlen = write(TASK_FD(task), proc->proc_buf_[NET2FD], proc->proc_rlen_[NET2FD]); | wlen = write(TASK_FD(task), proc->proc_buf_[NET2FD], proc->proc_rlen_[NET2FD]); |
| switch (wlen) { | switch (wlen) { |
| case -1: | case -1: |
| ERR("write2tty #%d - %s", errno, strerror(errno)); | ERR("write2tty #%d - %s", errno, strerror(errno)); |
| /* exit from shell and release tty */ | /* exit from shell and release tty */ |
| waitpid(proc->proc_pid, &wlen, 0); | |
| ioFreePTY(TASK_FD(task), proc->proc_ttyname); | |
| schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL); | |
| proc->proc_pid = 0; | |
| proc->proc_flg = ANSH_FLG_EOF; | |
| proc->proc_rlen_[FD2NET] = 0; | |
| schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock); | |
| return NULL; | return NULL; |
| default: | default: |
| proc->proc_flg = ANSH_FLG_OK; | proc->proc_flg = ANSH_FLG_OK; |
| Line 166 fdTx(sched_task_t *task) | Line 193 fdTx(sched_task_t *task) |
| /* if Timeout defined, go arm timer */ | /* if Timeout defined, go arm timer */ |
| if (Timeout) { | if (Timeout) { |
| tv.tv_sec = Timeout; | ts.tv_sec = Timeout; |
| schedTimer(TASK_ROOT(task), TOfunc, proc, tv); | schedTimer(TASK_ROOT(task), TOfunc, proc, ts, NULL, 0); |
| } | } |
| return NULL; | return NULL; |
| } | } |
| Line 176 void * | Line 203 void * |
| fdRx(sched_task_t *task) | fdRx(sched_task_t *task) |
| { | { |
| struct tagProc *proc; | struct tagProc *proc; |
| struct timeval tv = { 0 }; | struct timespec ts = { 0 }; |
| int rlen; | int rlen; |
| FTRACE(3); | FTRACE(3); |
| Line 187 fdRx(sched_task_t *task) | Line 214 fdRx(sched_task_t *task) |
| if (!proc->proc_pid) | if (!proc->proc_pid) |
| return NULL; | return NULL; |
| if (waitpid(proc->proc_pid, &rlen, WNOHANG)) { | |
| ioFreePTY(TASK_FD(task), proc->proc_ttyname); | |
| schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL); | |
| proc->proc_pid = 0; | |
| proc->proc_flg = ANSH_FLG_EOF; | |
| proc->proc_rlen_[FD2NET] = 0; | |
| schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock); | |
| return NULL; | |
| } | |
| /* if Timeout defined, disarm timer */ | /* if Timeout defined, disarm timer */ |
| if (Timeout) | if (Timeout) |
| schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL); | schedCancelby(TASK_ROOT(task), taskTIMER, CRITERIA_CALL, TOfunc, NULL); |
| memset(proc->proc_buf_[FD2NET], 0, proc->proc_blen); | memset(proc->proc_buf_[FD2NET], 0, proc->proc_blen); |
| rlen = read(TASK_FD(task), proc->proc_buf_[FD2NET], | rlen = read(TASK_FD(task), proc->proc_buf_[FD2NET], |
| Line 211 fdRx(sched_task_t *task) | Line 226 fdRx(sched_task_t *task) |
| ERR("readtty #%d - %s", errno, strerror(errno)); | ERR("readtty #%d - %s", errno, strerror(errno)); |
| case 0: | case 0: |
| /* exit from shell and release tty */ | /* exit from shell and release tty */ |
| waitpid(proc->proc_pid, &rlen, 0); | |
| ioFreePTY(TASK_FD(task), proc->proc_ttyname); | |
| schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL); | |
| VERB(3) LOG("EOF process status %d", rlen); | |
| proc->proc_pid = 0; | |
| proc->proc_flg = ANSH_FLG_EOF; | |
| proc->proc_rlen_[FD2NET] = 0; | |
| schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock); | |
| return NULL; | return NULL; |
| default: | default: |
| proc->proc_flg = ANSH_FLG_OK; | proc->proc_flg = ANSH_FLG_OK; |
| Line 228 fdRx(sched_task_t *task) | Line 233 fdRx(sched_task_t *task) |
| } | } |
| VERB(3) LOG("Readed %d bytes - %s", rlen, proc->proc_buf_[FD2NET]); | VERB(3) LOG("Readed %d bytes - %s", rlen, proc->proc_buf_[FD2NET]); |
| schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock); | schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock, NULL, 0); |
| schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty); | schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty, NULL, 0); |
| /* if Timeout defined, go arm timer */ | /* if Timeout defined, go arm timer */ |
| if (Timeout) { | if (Timeout) { |
| tv.tv_sec = Timeout; | ts.tv_sec = Timeout; |
| schedTimer(TASK_ROOT(task), TOfunc, proc, tv); | schedTimer(TASK_ROOT(task), TOfunc, proc, ts, NULL, 0); |
| } | } |
| return NULL; | return NULL; |
| } | } |
| Line 243 int | Line 248 int |
| spawnLogin(sched_task_t *task, struct tagProc *proc) | spawnLogin(sched_task_t *task, struct tagProc *proc) |
| { | { |
| int flg; | int flg; |
| struct timeval tv = { 0 }; | struct timespec ts = { 0 }; |
| char str[STRSIZ] = { 0 }; | char str[STRSIZ] = { 0 }; |
| struct sockaddr_in *sin; | |
| struct sockaddr_in6 *sin6; | |
| FTRACE(3); | FTRACE(3); |
| Line 261 spawnLogin(sched_task_t *task, struct tagProc *proc) | Line 264 spawnLogin(sched_task_t *task, struct tagProc *proc) |
| printf("ansh3d ELWIX remote management system over ICMP (%s)\n\n", | printf("ansh3d ELWIX remote management system over ICMP (%s)\n\n", |
| proc->proc_ttyname); | proc->proc_ttyname); |
| strlcpy(str, "-hansh3@", sizeof str); | strlcpy(str, "-hansh3@", sizeof str); |
| if (proc->proc_cli.sa_family == AF_INET) { | if (proc->proc_cli.sa.sa_family == AF_INET) |
| sin = (struct sockaddr_in*) &proc->proc_cli; | inet_ntop(AF_INET, &proc->proc_cli.sin.sin_addr, str + 8, INET_ADDRSTRLEN); |
| inet_ntop(AF_INET, &sin->sin_addr, str + 8, INET_ADDRSTRLEN); | else if (proc->proc_cli.sa.sa_family == AF_INET6) |
| } else if (proc->proc_cli.sa_family == AF_INET6) { | inet_ntop(AF_INET6, &proc->proc_cli.sin6.sin6_addr, str + 8, INET6_ADDRSTRLEN); |
| sin6 = (struct sockaddr_in6*) &proc->proc_cli; | |
| inet_ntop(AF_INET6, &sin6->sin6_addr, str + 8, INET6_ADDRSTRLEN); | |
| } | |
| execl("/usr/bin/login", "login", str, NULL); | execl("/usr/bin/login", "login", str, NULL); |
| /* never reached */ | /* never reached */ |
| return -1; | return -1; |
| Line 276 spawnLogin(sched_task_t *task, struct tagProc *proc) | Line 276 spawnLogin(sched_task_t *task, struct tagProc *proc) |
| fcntl(proc->proc_pty, F_SETFL, flg | O_NONBLOCK); | fcntl(proc->proc_pty, F_SETFL, flg | O_NONBLOCK); |
| VERB(3) LOG("Parent know child pid %d", proc->proc_pid); | VERB(3) LOG("Parent know child pid %d", proc->proc_pid); |
| schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty); | schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty, NULL, 0); |
| /* if Timeout defined, go arm timer */ | /* if Timeout defined, go arm timer */ |
| if (Timeout) { | if (Timeout) { |
| tv.tv_sec = Timeout; | ts.tv_sec = Timeout; |
| schedTimer(TASK_ROOT(task), TOfunc, proc, tv); | schedTimer(TASK_ROOT(task), TOfunc, proc, ts, NULL, 0); |
| } | } |
| break; | break; |
| } | } |