Exemplo n.º 1
0
static void
process_cmdline(void)
{
	void (*handler)(int);
	char *s, *cmd;
	u_short fwd_port, fwd_host_port;
	char buf[1024], sfwd_port[6], sfwd_host_port[6];
	int local = 0;

	leave_raw_mode();
	handler = signal(SIGINT, SIG_IGN);
	cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
	if (s == NULL)
		goto out;
	while (*s && isspace(*s))
		s++;
	if (*s == 0)
		goto out;
	if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) {
		logit("Invalid command.");
		goto out;
	}
	if (s[1] == 'L')
		local = 1;
	if (!local && !compat20) {
		logit("Not supported for SSH protocol version 1.");
		goto out;
	}
	s += 2;
	while (*s && isspace(*s))
		s++;

	if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
	    sfwd_port, buf, sfwd_host_port) != 3 &&
	    sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
	    sfwd_port, buf, sfwd_host_port) != 3) {
		logit("Bad forwarding specification.");
		goto out;
	}
	if ((fwd_port = a2port(sfwd_port)) == 0 ||
	    (fwd_host_port = a2port(sfwd_host_port)) == 0) {
		logit("Bad forwarding port(s).");
		goto out;
	}
	if (local) {
		if (channel_setup_local_fwd_listener(fwd_port, buf,
		    fwd_host_port, options.gateway_ports) < 0) {
			logit("Port forwarding failed.");
			goto out;
		}
	} else
		channel_request_remote_forwarding(fwd_port, buf,
		    fwd_host_port);
	logit("Forwarding port.");
out:
	signal(SIGINT, handler);
	enter_raw_mode();
	if (cmd)
		xfree(cmd);
}
Exemplo n.º 2
0
/*
 * suspendSelf
 *
 * Put ourself in the background
 *
 * param bRestoreTty specifies whether we will put our self back
 *       in raw mode when we resume
 */
static void
suspendSelf(int bRestoreTty)
{
	leave_raw_mode();
	kill(getpid(), SIGTSTP);

	if (bRestoreTty)
		enter_raw_mode();
}
Exemplo n.º 3
0
static void
suspend_self(int restore_tty)
{
	leave_raw_mode();
	kill(getpid(), SIGTSTP);
	if (restore_tty) {
		enter_raw_mode();
	}
}
Exemplo n.º 4
0
static void
client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
{
	struct winsize oldws, newws;

	/* Flush stdout and stderr buffers. */
	if (buffer_len(bout) > 0)
		atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout));
	if (buffer_len(berr) > 0)
		atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr));

	leave_raw_mode();

	/*
	 * Free (and clear) the buffer to reduce the amount of data that gets
	 * written to swap.
	 */
	buffer_free(bin);
	buffer_free(bout);
	buffer_free(berr);

	/* Save old window size. */
	ioctl(fileno(stdin), TIOCGWINSZ, &oldws);

	/* Send the suspend signal to the program itself. */
	kill(getpid(), SIGTSTP);

	/* Check if the window size has changed. */
	if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 &&
	    (oldws.ws_row != newws.ws_row ||
	    oldws.ws_col != newws.ws_col ||
	    oldws.ws_xpixel != newws.ws_xpixel ||
	    oldws.ws_ypixel != newws.ws_ypixel))
		received_window_change_signal = 1;

	/* OK, we have been continued by the user. Reinitialize buffers. */
	buffer_init(bin);
	buffer_init(bout);
	buffer_init(berr);

	enter_raw_mode();
}
Exemplo n.º 5
0
/*
 * ipmi_isol_red_pill
 */
static int
ipmi_isol_red_pill(struct ipmi_intf * intf)
{
	char   * buffer;
	int    numRead;
	int    bShouldExit       = 0;
	int    bBmcClosedSession = 0;
	fd_set read_fds;
	struct timeval tv;
	int    retval;
	int    buffer_size = 255;
	int    timedout = 0;

	buffer = (char*)malloc(buffer_size);
	if (buffer == NULL) {
		lprintf(LOG_ERR, "ipmitool: malloc failure");
		return -1;
	}

	enter_raw_mode();

	while (! bShouldExit)
	{
		FD_ZERO(&read_fds);
		FD_SET(0, &read_fds);
		FD_SET(intf->fd, &read_fds);

		/* Wait up to half a second */
		tv.tv_sec =  0;
		tv.tv_usec = 500000;

		retval = select(intf->fd + 1, &read_fds, NULL, NULL, &tv);

		if (retval)
		{
			if (retval == -1)
			{
				/* ERROR */
				perror("select");
				return -1;
			}

			timedout = 0;

			/*
			 * Process input from the user
			 */
			if (FD_ISSET(0, &read_fds))
	 		{
				memset(buffer, 0, buffer_size);
				numRead = read(fileno(stdin),
							   buffer,
							   buffer_size);
				
				if (numRead > 0)
				{
					int rc = processiSolUserInput(intf, buffer, numRead);
					
					if (rc)
					{
						if (rc < 0)
							bShouldExit = bBmcClosedSession = 1;
						else
							bShouldExit = 1;
					}
				}
				else
				{
					bShouldExit = 1;
				}
			}


			/*
			 * Process input from the BMC
			 */
			else if (FD_ISSET(intf->fd, &read_fds))
			{
				struct ipmi_rs * rs = intf->recv_sol(intf);
				if (! rs)
				{
					bShouldExit = bBmcClosedSession = 1;
				}
				else
					output(rs);
 			}

			
			/*
			 * ERROR in select
			 */
 			else
			{
				lprintf(LOG_ERR, "Error: Select returned with nothing to read");
				bShouldExit = 1;
			}
		}
		else
		{
			if ((++timedout) == 20) /* Every 10 seconds we send a keepalive */
			{
				intf->keepalive(intf);
				timedout = 0;
			}
		}
	}		

	leave_raw_mode();

	if (bBmcClosedSession)
	{
		lprintf(LOG_ERR, "SOL session closed by BMC");
	}
	else
		ipmi_isol_deactivate(intf);

	return 0;
}
Exemplo n.º 6
0
int
ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv)
{
	struct pollfd fds_wait[3], fds_data_wait[3], *fds;
	struct sockaddr_in sin, myaddr, *sa_in;
	socklen_t mylen;
	char *recvip = NULL;
	char out_buff[IPMI_BUF_SIZE * 8], in_buff[IPMI_BUF_SIZE];
	char buff[IPMI_BUF_SIZE + 4];
	int fd_socket, result, i;
	int out_buff_fill, in_buff_fill;
	int ip1, ip2, ip3, ip4;
	int read_only = 0, rows = 0, cols = 0;
	int port = IPMI_TSOL_DEF_PORT;

	if (strlen(intf->name) < 3 || strncmp(intf->name, "lan", 3) != 0) {
		lprintf(LOG_ERR, "Error: Tyan SOL is only available over lan interface");
		return -1;
	}

	for (i = 0; i<argc; i++) {
		if (sscanf(argv[i], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) == 4) {
			/* not free'd ...*/
			/* recvip = strdup(argv[i]); */
			recvip = argv[i];
		} 
		else if (sscanf(argv[i], "port=%d", &ip1) == 1)
			port = ip1;
		else if (sscanf(argv[i], "rows=%d", &ip1) == 1)
			rows = ip1;
		else if (sscanf(argv[i], "cols=%d", &ip1) == 1)
			cols = ip1;
		else if (strlen(argv[i]) == 2 && strncmp(argv[i], "ro", 2) == 0)
			read_only = 1;
		else if (strlen(argv[i]) == 2 && strncmp(argv[i], "rw", 2) == 0)
			read_only = 0;
		else if (strlen(argv[i]) == 7 && strncmp(argv[i], "altterm", 7) == 0)
			_altterm = 1;
		else if (strlen(argv[i]) == 4 && strncmp(argv[i], "help", 4) == 0) {
			print_tsol_usage();
			return 0;
		}
		else {
			print_tsol_usage();
			return 0;
		}
	}

	/* create udp socket to receive the packet */
	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);

	sa_in = (struct sockaddr_in *)&intf->session->addr;
	result = inet_pton(AF_INET, (const char *)intf->session->hostname,
			   &sa_in->sin_addr);

	if (result <= 0) {
		struct hostent *host = gethostbyname((const char *)intf->session->hostname);
		if (host == NULL ) {
			lprintf(LOG_ERR, "Address lookup for %s failed",
				intf->session->hostname);
			return -1;
		}
		if (host->h_addrtype != AF_INET) {
			lprintf(LOG_ERR,
					"Address lookup for %s failed. Got %s, expected IPv4 address.",
					intf->session->hostname,
					(host->h_addrtype == AF_INET6) ? "IPv6" : "Unknown");
			return (-1);
		}
		sa_in->sin_family = host->h_addrtype;
		memcpy(&sa_in->sin_addr, host->h_addr, host->h_length);
	}

	fd_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (fd_socket < 0) {
		lprintf(LOG_ERR, "Can't open port %d", port);
		return -1;
	}
	if (-1 == bind(fd_socket, (struct sockaddr *)&sin, sizeof(sin))) {
		lprintf(LOG_ERR, "Failed to bind socket.");
		close(fd_socket);
		return -1;
	}

	/*
	 * retrieve local IP address if not supplied on command line
	 */
	if (recvip == NULL) {
		result = intf->open(intf);	/* must connect first */
		if (result < 0) {
			close(fd_socket);
			return -1;
		}

		mylen = sizeof(myaddr);
		if (getsockname(intf->fd, (struct sockaddr *)&myaddr, &mylen) < 0) {
			lperror(LOG_ERR, "getsockname failed");
			close(fd_socket);
			return -1;
		}

		recvip = inet_ntoa(myaddr.sin_addr);
		if (recvip == NULL) {
			lprintf(LOG_ERR, "Unable to find local IP address");
			close(fd_socket);
			return -1;
		}
	}

	printf("[Starting %sSOL with receiving address %s:%d]\n",
	       read_only ? "Read-only " : "", recvip, port);

	set_terminal_size(rows, cols);
	enter_raw_mode();

	/*
	 * talk to smdc to start Console redirect - IP address and port as parameter
	 * ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x06 0xC0 0xA8 0xA8 0x78 0x1A 0x0A
	 */
	result = ipmi_tsol_start(intf, recvip, port);
        if (result < 0) {
		lprintf(LOG_ERR, "Error starting SOL");
		close(fd_socket);
                return -1;
        }

	printf("[SOL Session operational.  Use %c? for help]\n",
	       intf->session->sol_escape_char);

	gettimeofday(&_start_keepalive, 0);

	fds_wait[0].fd = fd_socket;
	fds_wait[0].events = POLLIN;
	fds_wait[0].revents = 0;
	fds_wait[1].fd = fileno(stdin);
	fds_wait[1].events = POLLIN;
	fds_wait[1].revents = 0;
	fds_wait[2].fd = -1;
	fds_wait[2].events = 0;
	fds_wait[2].revents = 0;

	fds_data_wait[0].fd = fd_socket;
	fds_data_wait[0].events = POLLIN | POLLOUT;
	fds_data_wait[0].revents = 0;
	fds_data_wait[1].fd = fileno(stdin);
	fds_data_wait[1].events = POLLIN;
	fds_data_wait[1].revents = 0;
	fds_data_wait[2].fd = fileno(stdout);
	fds_data_wait[2].events = POLLOUT;
	fds_data_wait[2].revents = 0;

	out_buff_fill = 0;
	in_buff_fill = 0;
	fds = fds_wait;

	for (;;) {
		result = poll(fds, 3, 15*1000);
		if (result < 0)
			break;

		/* send keepalive packet */
		tsol_keepalive(intf);

		if ((fds[0].revents & POLLIN) && (sizeof(out_buff) > out_buff_fill)){
			socklen_t sin_len = sizeof(sin);
			result = recvfrom(fd_socket, buff, sizeof(out_buff) - out_buff_fill + 4, 0,
					  (struct sockaddr *)&sin, &sin_len);

			/* read the data from udp socket, skip some bytes in the head */
			if((result - 4) > 0 ){
				int length = result - 4;
#if 1
		 		length = (unsigned char)buff[2] & 0xff;
			       	length *= 256;
				length += ((unsigned char)buff[3] & 0xff);
				if ((length <= 0) || (length > (result - 4)))
			              length = result - 4;
#endif
				memcpy(out_buff + out_buff_fill, buff + 4, length);
				out_buff_fill += length;
			}
		}
		if ((fds[1].revents & POLLIN) && (sizeof(in_buff) > in_buff_fill)) {
			result = read(fileno(stdin), in_buff + in_buff_fill,
				      sizeof(in_buff) - in_buff_fill); // read from keyboard
			if (result > 0) {
				int bytes;
				bytes = do_inbuf_actions(intf, in_buff + in_buff_fill, result);
				if(bytes < 0) {
					result = ipmi_tsol_stop(intf, recvip, port);
					do_terminal_cleanup();
					return result;
				}
				if (read_only)
					bytes = 0;
				in_buff_fill += bytes;
			}
		}
		if ((fds[2].revents & POLLOUT) && out_buff_fill) {
			result = write(fileno(stdout), out_buff, out_buff_fill); // to screen
			if (result > 0) {
				out_buff_fill -= result;
				if (out_buff_fill) {
					memmove(out_buff, out_buff + result, out_buff_fill);
				}
			}
		}
		if ((fds[0].revents & POLLOUT) && in_buff_fill) {
			/*
			 * translate key and send that to SMDC using IPMI
			 * ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x03 0x04 0x1B 0x5B 0x43
			 */
			result = ipmi_tsol_send_keystroke(intf, in_buff, __min(in_buff_fill,14));
			if (result > 0) {
				gettimeofday(&_start_keepalive, 0);
				in_buff_fill -= result;
				if (in_buff_fill) {
					memmove(in_buff, in_buff + result, in_buff_fill);
				}
			}
		}
		fds = (in_buff_fill || out_buff_fill )?
			fds_data_wait : fds_wait;
	}

	return 0;
}