Annotation of ansh/src/daemon2.c, revision 1.1.1.1.2.8
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.8! misho 6: * $Id: daemon2.c,v 1.1.1.1.2.7 2011/10/14 07:47:21 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, ð)) == 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, ð.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:
1.1.1.1.2.8! misho 177: /*
1.1 misho 178: if (waitpid(proc->proc_pid, &wlen, WNOHANG)) {
179: ioFreePTY(TASK_FD(task), proc->proc_ttyname);
1.1.1.1.2.1 misho 180: schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
1.1 misho 181:
182: proc->proc_pid = 0;
1.1.1.1.2.4 misho 183: proc->proc_seq = 0;
1.1 misho 184: proc->proc_flg = ANSH_FLG_EOF;
185: proc->proc_rlen_[FD2NET] = 0;
186:
1.1.1.1.2.2 misho 187: schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1 misho 188: return NULL;
189: }
1.1.1.1.2.8! misho 190: */
1.1 misho 191:
1.1.1.1.2.1 misho 192: /* if Timeout defined, disarm timer */
193: if (Timeout)
194: schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
195:
1.1 misho 196: wlen = write(TASK_FD(task), proc->proc_buf_[NET2FD], proc->proc_rlen_[NET2FD]);
197: switch (wlen) {
198: case -1:
199: ERR("write2tty #%d - %s", errno, strerror(errno));
200: /* exit from shell and release tty */
1.1.1.1.2.8! misho 201: /*
1.1 misho 202: waitpid(proc->proc_pid, &wlen, 0);
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.1.1.2.8! misho 212: */
1.1 misho 213: return NULL;
214: default:
215: proc->proc_flg = ANSH_FLG_OK;
216: proc->proc_rlen_[NET2FD] = 0;
217: }
218: VERB(3) LOG("Writed %d bytes - %s", wlen, proc->proc_buf_[NET2FD]);
219:
1.1.1.1.2.1 misho 220: /* if Timeout defined, go arm timer */
221: if (Timeout) {
222: tv.tv_sec = Timeout;
223: schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
224: }
1.1 misho 225: return NULL;
226: }
227:
228: void *
229: fdRx(sched_task_t *task)
230: {
231: struct tagProc *proc;
1.1.1.1.2.1 misho 232: struct timeval tv = { 0 };
1.1 misho 233: int rlen;
234:
235: FTRACE(3);
236:
237: /* not found argument, drop data */
238: if (!(proc = TASK_ARG(task)))
239: return (void*) -1;
1.1.1.1.2.1 misho 240: if (!proc->proc_pid)
241: return NULL;
1.1 misho 242:
1.1.1.1.2.8! misho 243: /*
1.1 misho 244: if (waitpid(proc->proc_pid, &rlen, WNOHANG)) {
245: ioFreePTY(TASK_FD(task), proc->proc_ttyname);
1.1.1.1.2.1 misho 246: schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
1.1 misho 247:
248: proc->proc_pid = 0;
1.1.1.1.2.4 misho 249: proc->proc_seq = 0;
1.1 misho 250: proc->proc_flg = ANSH_FLG_EOF;
251: proc->proc_rlen_[FD2NET] = 0;
252:
1.1.1.1.2.2 misho 253: schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1 misho 254: return NULL;
255: }
1.1.1.1.2.8! misho 256: */
1.1 misho 257:
1.1.1.1.2.1 misho 258: /* if Timeout defined, disarm timer */
259: if (Timeout)
260: schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
261:
1.1 misho 262: memset(proc->proc_buf_[FD2NET], 0, proc->proc_blen);
1.1.1.1.2.3 misho 263: rlen = read(TASK_FD(task), proc->proc_buf_[FD2NET],
264: proc->proc_blen - ETHER_HDR_LEN + sizeof(struct ansh_hdr));
1.1 misho 265: switch (rlen) {
266: case -1:
267: ERR("readtty #%d - %s", errno, strerror(errno));
268: case 0:
269: /* exit from shell and release tty */
1.1.1.1.2.8! misho 270: /*
1.1 misho 271: waitpid(proc->proc_pid, &rlen, 0);
272: ioFreePTY(TASK_FD(task), proc->proc_ttyname);
1.1.1.1.2.1 misho 273: schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
274: VERB(3) LOG("EOF process status %d", rlen);
1.1 misho 275:
276: proc->proc_pid = 0;
1.1.1.1.2.4 misho 277: proc->proc_seq = 0;
1.1 misho 278: proc->proc_flg = ANSH_FLG_EOF;
279: proc->proc_rlen_[FD2NET] = 0;
280:
1.1.1.1.2.2 misho 281: schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1.1.1.2.8! misho 282: */
1.1 misho 283: return NULL;
284: default:
285: proc->proc_flg = ANSH_FLG_OK;
286: proc->proc_rlen_[FD2NET] = rlen;
287: }
288: VERB(3) LOG("Readed %d bytes - %s", rlen, proc->proc_buf_[FD2NET]);
289:
1.1.1.1.2.2 misho 290: schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1 misho 291: schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
1.1.1.1.2.1 misho 292:
293: /* if Timeout defined, go arm timer */
294: if (Timeout) {
295: tv.tv_sec = Timeout;
296: schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
297: }
1.1 misho 298: return NULL;
299: }
300:
301: int
302: spawnLogin(sched_task_t *task, struct tagProc *proc)
303: {
1.1.1.1.2.1 misho 304: int flg;
305: struct timeval tv = { 0 };
306: char str[STRSIZ] = { 0 };
307:
1.1 misho 308: FTRACE(3);
309:
310: assert(proc);
311:
312: switch ((proc->proc_pid = ioForkPTY(&proc->proc_pty, proc->proc_ttyname,
313: sizeof proc->proc_ttyname, NULL, NULL, NULL))) {
314: case -1:
315: ERR("ioForkPTY() #%d - %s", io_GetErrno(), io_GetError());
316: return -1;
317: case 0:
1.1.1.1.2.1 misho 318: printf("anshd ELWIX remote management system (%s)\n\n", proc->proc_ttyname);
319: strlcpy(str, "-hansh@", sizeof str);
1.1.1.1.2.7 misho 320: io_ether_ntoa((const struct io_ether_addr*) &proc->proc_ea, str + 7, 18);
1.1.1.1.2.1 misho 321:
322: execl("/usr/bin/login", "login", str, NULL);
1.1 misho 323: /* never reached */
324: return -1;
325: default:
1.1.1.1.2.1 misho 326: flg = fcntl(proc->proc_pty, F_GETFL);
327: fcntl(proc->proc_pty, F_SETFL, flg | O_NONBLOCK);
328:
329: VERB(3) LOG("Parent know child pid %d", proc->proc_pid);
1.1 misho 330: schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
1.1.1.1.2.1 misho 331:
332: /* if Timeout defined, go arm timer */
333: if (Timeout) {
334: tv.tv_sec = Timeout;
335: schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
336: }
1.1 misho 337: break;
338: }
339:
340: return 0;
341: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>