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