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