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