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