Пример #1
0
void TelnetConnection::handleRead(const boost::system::error_code &err, size_t bytesTransfered) {
    if (!err) {
        std::vector<std::string> input;
        {boost::lock_guard<boost::mutex> guard(mTelnetMutex);
            telnet_recv(mTelnet, mInputBuffer.begin(), bytesTransfered);
            if (mIncompleteMessage && mInputQueue.size() == 1) {
                startReceive();
                return;
            }
            input = std::move(mInputQueue);
            mInputQueue.clear();
            if (mIncompleteMessage) {
                mInputQueue.emplace_back(std::move(input.back()));
                input.erase(input.end() - 1);
            }
        }
        for (const std::string &str : input) {
            mMessageHandler(shared_from_this(), str);
        }
    }
    else {
        std::cerr << "handleRead: " << err.message() << std::endl;
        /*if (err == boost::asio::error::connection_reset || err == boost::asio::error::eof) {

        }*/
        mDisconnectHandler(shared_from_this());
        return;
    }

    startReceive();
}
Пример #2
0
int main(int argc, char** argv) {
	FILE *fh;
	telnet_t *telnet;
	char buffer[4096];
	size_t len;

	/* check for a requested input file */
	if (argc != 2) {
		fprintf(stderr, "Usage: telnet-test [test file]\n");
		return 1;
	}

	/* open requested file */
	if ((fh = fopen(argv[1], "rt")) == NULL) {
		fprintf(stderr, "Failed to open %s: %s\n",
				argv[1], strerror(errno));
		return 2;
	}

	/* create telnet parser instance */
	if ((telnet = telnet_init(telopts, event_print, 0,
			NULL)) == 0) {
		fprintf(stderr, "Failed to initialize libtelnet: %s\n",
				strerror(errno));
		return 3;
	}

	/* read input until we hit EOF or marker */
	while (fgets(buffer, sizeof(buffer), fh) != NULL && strcmp(buffer, "%%\n") != 0) {
		if (buffer[0] != '#') {
			len = strlen(buffer);
			decode(buffer, &len);
			telnet_recv(telnet, buffer, len);
		}
	}

	/* clean up */
	telnet_free(telnet);
	fclose(fh);

	return 0;
}
Пример #3
0
static void _process(telnet_t *telnet, const char *buffer, size_t size) {
	telnet_event_t ev;
	unsigned char byte;
	size_t i, start;
	for (i = start = 0; i != size; ++i) {
		byte = buffer[i];
		switch (telnet->state) {
		/* regular data */
		case TELNET_STATE_DATA:
			/* on an IAC byte, pass through all pending bytes and
			 * switch states */
			if (byte == TELNET_IAC) {
				if (i != start) {
					ev.type = TELNET_EV_DATA;
					ev.data.buffer = buffer + start;
					ev.data.size = i - start;
					telnet->eh(telnet, &ev, telnet->ud);
				}
				telnet->state = TELNET_STATE_IAC;
			}
			break;

		/* IAC command */
		case TELNET_STATE_IAC:
			switch (byte) {
			/* subnegotiation */
			case TELNET_SB:
				telnet->state = TELNET_STATE_SB;
				break;
			/* negotiation commands */
			case TELNET_WILL:
				telnet->state = TELNET_STATE_WILL;
				break;
			case TELNET_WONT:
				telnet->state = TELNET_STATE_WONT;
				break;
			case TELNET_DO:
				telnet->state = TELNET_STATE_DO;
				break;
			case TELNET_DONT:
				telnet->state = TELNET_STATE_DONT;
				break;
			/* IAC escaping */
			case TELNET_IAC:
				/* event */
				ev.type = TELNET_EV_DATA;
				ev.data.buffer = (char*)&byte;
				ev.data.size = 1;
				telnet->eh(telnet, &ev, telnet->ud);

				/* state update */
				start = i + 1;
				telnet->state = TELNET_STATE_DATA;
				break;
			/* some other command */
			default:
				/* event */
				ev.type = TELNET_EV_IAC;
				ev.iac.cmd = byte;
				telnet->eh(telnet, &ev, telnet->ud);

				/* state update */
				start = i + 1;
				telnet->state = TELNET_STATE_DATA;
			}
			break;

		/* negotiation commands */
		case TELNET_STATE_WILL:
		case TELNET_STATE_WONT:
		case TELNET_STATE_DO:
		case TELNET_STATE_DONT:
			_negotiate(telnet, byte);
			start = i + 1;
			telnet->state = TELNET_STATE_DATA;
			break;

		/* subnegotiation -- determine subnegotiation telopt */
		case TELNET_STATE_SB:
			telnet->sb_telopt = byte;
			telnet->buffer_pos = 0;
			telnet->state = TELNET_STATE_SB_DATA;
			break;

		/* subnegotiation -- buffer bytes until end request */
		case TELNET_STATE_SB_DATA:
			/* IAC command in subnegotiation -- either IAC SE or IAC IAC */
			if (byte == TELNET_IAC) {
				telnet->state = TELNET_STATE_SB_DATA_IAC;
			} else if (telnet->sb_telopt == TELNET_TELOPT_COMPRESS && byte == TELNET_WILL) {
				/* In 1998 MCCP used TELOPT 85 and the protocol defined an invalid
				 * subnegotiation sequence (IAC SB 85 WILL SE) to start compression.
				 * Subsequently MCCP version 2 was created in 2000 using TELOPT 86
				 * and a valid subnegotiation (IAC SB 86 IAC SE). libtelnet for now
				 * just captures and discards MCCPv1 sequences.
				 */
				start = i + 2;
				telnet->state = TELNET_STATE_DATA;
			/* buffer the byte, or bail if we can't */
			} else if (_buffer_byte(telnet, byte) != TELNET_EOK) {
				start = i + 1;
				telnet->state = TELNET_STATE_DATA;
			}
			break;

		/* IAC escaping inside a subnegotiation */
		case TELNET_STATE_SB_DATA_IAC:
			switch (byte) {
			/* end subnegotiation */
			case TELNET_SE:
				/* return to default state */
				start = i + 1;
				telnet->state = TELNET_STATE_DATA;

				/* process subnegotiation */
				if (_subnegotiate(telnet) != 0) {
					/* any remaining bytes in the buffer are compressed.
					 * we have to re-invoke telnet_recv to get those
					 * bytes inflated and abort trying to process the
					 * remaining compressed bytes in the current _process
					 * buffer argument
					 */
					telnet_recv(telnet, &buffer[start], size - start);
					return;
				}
				break;
			/* escaped IAC byte */
			case TELNET_IAC:
				/* push IAC into buffer */
				if (_buffer_byte(telnet, TELNET_IAC) !=
						TELNET_EOK) {
					start = i + 1;
					telnet->state = TELNET_STATE_DATA;
				} else {
					telnet->state = TELNET_STATE_SB_DATA;
				}
				break;
			/* something else -- protocol error.  attempt to process
			 * content in subnegotiation buffer, then evaluate the
			 * given command as an IAC code.
			 */
			default:
				_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
						"unexpected byte after IAC inside SB: %d",
						byte);

				/* enter IAC state */
				start = i + 1;
				telnet->state = TELNET_STATE_IAC;

				/* process subnegotiation; see comment in
				 * TELNET_STATE_SB_DATA_IAC about invoking telnet_recv()
				 */
				if (_subnegotiate(telnet) != 0) {
					telnet_recv(telnet, &buffer[start], size - start);
					return;
				} else {
					/* recursive call to get the current input byte processed
					 * as a regular IAC command.  we could use a goto, but
					 * that would be gross.
					 */
					_process(telnet, (char *)&byte, 1);
				}
				break;
			}
			break;
		}
	}

	/* pass through any remaining bytes */ 
	if (telnet->state == TELNET_STATE_DATA && i != start) {
		ev.type = TELNET_EV_DATA;
		ev.data.buffer = buffer + start;
		ev.data.size = i - start;
		telnet->eh(telnet, &ev, telnet->ud);
	}
}
Пример #4
0
Файл: clc.c Проект: elanthis/clc
int main (int argc, char** argv) {
	const char* default_port = "23";
	struct sigaction sa;
	int i;

	/* process command line args */
	for (i = 1; i < argc; ++i) {
		/* help */
		if (strcmp(argv[i], "-h") == 0) {
			printf(
				"CLC %s by Sean Middleditch <*****@*****.**>\n"
				"This program has been released into the PUBLIC DOMAIN.\n\n"
				"Usage:\n"
				"  clc [-h] <host> [<port>]\n\n"
				"Options:\n"
				"  -h   display help\n", CLC_VERSION
			);
			return 0;
		}

		/* other unknown option */
		if (argv[i][0] == '-') {
			fprintf(stderr, "Unknown option %s.\nUse -h to see available options.\n", argv[i]);
			exit(1);
		}

		/* if host is unset, this is the host */
		if (host == NULL) {
			host = argv[i];
		/* otherwise, it's a port */
		} else {
			port = argv[i];
		}
	}

	/* ensure we have a host */
	if (host == NULL) {
		fprintf(stderr, "No host was given.\nUse -h to see command format.\n");
		exit(1);
	}

	/* set default port if none was given */
	if (port == NULL)
		port = default_port;

	/* cleanup on any failure */
	atexit(cleanup);

	/* set terminal defaults */
	memset(&terminal, 0, sizeof(struct TERMINAL));
	terminal.state = TERM_ASCII;
	terminal.flags = TERM_FLAGS_DEFAULT;
	terminal.color = TERM_COLOR_DEFAULT;

	/* initial telnet handler */
	telnet = telnet_init(telnet_telopts, telnet_event, 0, 0);

	/* connect to server */
	sock = do_connect(host, port);
	if (sock == -1) {
		fprintf(stderr, "Failed to connect to %s:%s\n", host, port);
		exit(1);
	}
	printf("Connected to %s:%s\n", host, port);

	/* set initial banner */
	snprintf(banner, sizeof(banner), "CLC - %s:%s (connected)", host, port);

	/* configure curses */
	initscr();
	start_color();
	nonl();
	cbreak();
	noecho();

	win_main = newwin(LINES-2, COLS, 0, 0);
	win_banner = newwin(1, COLS, LINES-2, 0);
	win_input = newwin(1, COLS, LINES-1, 0);

	idlok(win_main, TRUE);
	scrollok(win_main, TRUE);

	nodelay(win_input, FALSE);
	keypad(win_input, TRUE);

	use_default_colors();

	init_pair(COLOR_RED, COLOR_RED, -1);
	init_pair(COLOR_BLUE, COLOR_BLUE, -1);
	init_pair(COLOR_GREEN, COLOR_GREEN, -1);
	init_pair(COLOR_CYAN, COLOR_CYAN, -1);
	init_pair(COLOR_MAGENTA, COLOR_MAGENTA, -1);
	init_pair(COLOR_YELLOW, COLOR_YELLOW, -1);
	init_pair(COLOR_WHITE, COLOR_WHITE, -1);

	init_pair(TERM_COLOR_DEFAULT, -1, -1);
	wbkgd(win_main, COLOR_PAIR(TERM_COLOR_DEFAULT));
	wclear(win_main);
	init_pair(10, COLOR_WHITE, COLOR_BLUE);
	wbkgd(win_banner, COLOR_PAIR(10));
	wclear(win_banner);
	init_pair(11, -1, -1);
	wbkgd(win_input, COLOR_PAIR(11));
	wclear(win_input);

	redraw_display();

	/* set signal handlers */
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = handle_signal;
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGWINCH, &sa, NULL);

	/* initial edit buffer */
	memset(&editbuf, 0, sizeof(struct EDITBUF));

	/* setup poll info */
	struct pollfd fds[2];
	fds[0].fd = 1;
	fds[0].events = POLLIN;
	fds[1].fd = sock;
	fds[1].events = POLLIN;

	/* main loop */
	while (running) {
		/* poll sockets */
		if (poll(fds, 2, -1) == -1) {
			if (errno != EAGAIN && errno != EINTR) {
				endwin();
				fprintf(stderr, "poll() failed: %s\n", strerror(errno));
				return 1;
			}
		}

		/* resize event? */
		if (have_sigwinch) {
			have_sigwinch = 0;
			redraw_display();
		}

		/* escape? */
		if (have_sigint) {
			exit(0);
		}

		/* input? */
		if (fds[0].revents & POLLIN) {
			int key = wgetch(win_input);
			if (key != ERR)
				on_key(key);
		}

		/* process input data */
		if (fds[1].revents & POLLIN) {
			char buffer[2048];
			int ret = recv(sock, buffer, sizeof(buffer), 0);
			if (ret == -1) {
				if (errno != EAGAIN && errno != EINTR) {
					endwin();
					fprintf(stderr, "recv() failed: %s\n", strerror(errno));
					return 1;
				}
			} else if (ret == 0) {
				running = 0;
			} else {
				recv_bytes += ret;
				telnet_recv(telnet, buffer, ret);
			}
		}

		/* flush output */
		paint_banner();
		wnoutrefresh(win_main);
		wnoutrefresh(win_banner);
		wnoutrefresh(win_input);
		doupdate();
	}

	/* final display, pause */
	sock = -1;
	autobanner = 1;
	paint_banner();
	wnoutrefresh(win_banner);
	doupdate();
	wgetch(win_input);

	/* clean up */
	endwin();
	printf("Disconnected.\n");

	/* free memory (so Valgrind leak detection is useful) */
	telnet_free(telnet);

	return 0;
}
Пример #5
0
int main(int argc, char *argv[])
{
	int listen_sock;
	struct sockaddr_in addr;
	//telnet_t *telnet;
	//struct sockaddr_in client_addr;
	socklen_t addrlen;
	int rs;
	struct pollfd pfd[2];

	char buffer[512];

	memset(&pfd, 0, sizeof(pfd));
	if((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("cant open socket\n");
		exit(errno);
	}
	setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (void*)&rs, sizeof(rs));
	rs = 1;

	//bzero(&self, sizeof(self));
	memset(&addr, 0, sizeof(addr));

	addr.sin_family = AF_INET;
	addr.sin_port = htons(MY_PORT);
	addr.sin_addr.s_addr = INADDR_ANY;

	if( bind(listen_sock, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
	{
		perror("cant bind");
		exit(errno);
	}

	if( listen(listen_sock, 20) != 0 )
	{
		perror("cant listen");
		exit(errno);
	}

	pfd[1].fd = listen_sock;
	pfd[1].events = POLLIN;


	while(1)
	{
		if(user.sock != -1)
		{
			pfd[0].fd = user.sock;
			pfd[0].events = POLLIN;
		}
		else
		{
			pfd[0].fd = -1;
			pfd[0].events = 0;
		}

		rs = poll(pfd, 2, -1);
		if(rs == -1 && errno == EINTR)
		{
			printf("Poll failed\n");
			return 1;
		}

		if(pfd[1].revents & POLLIN)
		{
		
			addrlen = sizeof(addr);

			if((rs = accept(listen_sock, (struct sockaddr*)&addr, &addrlen)) == -1)
			{
				fprintf(stderr, "accept() failed %d.\n", errno);
				return 1;
			}

			printf("Connected client: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

			user.sock = rs;
			user.telnet = telnet_init(telopts, _event_handler, 0, &user);

			telnet_negotiate(user.telnet, TELNET_DO, TELNET_TELOPT_NAWS);
		}

		if(pfd[0].revents & POLLIN)
		{
			if( (rs = recv(user.sock, buffer, sizeof(buffer), 0)) > 0)
			{
				telnet_recv(user.telnet, buffer, sizeof(buffer));
			}
			else if(rs == 0)
			{
				printf("connection closed\n");
				close(user.sock);
				telnet_free(user.telnet);
				user.sock = -1;
				break;
			}
			else if(errno != EINTR)
			{
				fprintf(stderr, "recv() failed\n");
				exit(1);
			}
		}
		//send(clientfd, "Hello, world!", sizeof("Hello, world!"), 0);

	}

	close(listen_sock);

	return 0;
}
Пример #6
0
int main(int argc, char **argv) {
	char buffer[512];
	int rs;
	int sock;
	struct sockaddr_in addr;
	struct pollfd pfd[2];
	struct addrinfo *ai;
	struct addrinfo hints;
	struct termios tios;

	/* check usage */
	if (argc != 3) {
		fprintf(stderr, "Usage:\n ./telnet-client <host> <port>\n");
		return 1;
	}

	/* look up server host */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	if ((rs = getaddrinfo(argv[1], argv[2], &hints, &ai)) != 0) {
		fprintf(stderr, "getaddrinfo() failed for %s: %s\n", argv[1],
				gai_strerror(rs));
		return 1;
	}
	
	/* create server socket */
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		fprintf(stderr, "socket() failed: %s\n", strerror(errno));
		return 1;
	}

	/* bind server socket */
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
		fprintf(stderr, "bind() failed: %s\n", strerror(errno));
		return 1;
	}

	/* connect */
	if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
		fprintf(stderr, "connect() failed: %s\n", strerror(errno));
		return 1;
	}

	/* free address lookup info */
	freeaddrinfo(ai);

	/* get current terminal settings, set raw mode, make sure we
	 * register atexit handler to restore terminal settings
	 */
	tcgetattr(STDOUT_FILENO, &orig_tios);
	atexit(_cleanup);
	tios = orig_tios;
	cfmakeraw(&tios);
	tcsetattr(STDOUT_FILENO, TCSADRAIN, &tios);

	/* set input echoing on by default */
	do_echo = 1;

	/* initialize telnet box */
	telnet = telnet_init(telopts, _event_handler, 0, &sock);

	/* initialize poll descriptors */
	memset(pfd, 0, sizeof(pfd));
	pfd[0].fd = STDIN_FILENO;
	pfd[0].events = POLLIN;
	pfd[1].fd = sock;
	pfd[1].events = POLLIN;

	/* loop while both connections are open */
	while (poll(pfd, 2, -1) != -1) {
		/* read from stdin */
		if (pfd[0].revents & POLLIN) {
			if ((rs = read(STDIN_FILENO, buffer, sizeof(buffer))) > 0) {
				_input(buffer, rs);
			} else if (rs == 0) {
				break;
			} else {
				fprintf(stderr, "recv(server) failed: %s\n",
						strerror(errno));
				exit(1);
			}
		}

		/* read from client */
		if (pfd[1].revents & POLLIN) {
			if ((rs = recv(sock, buffer, sizeof(buffer), 0)) > 0) {
				telnet_recv(telnet, buffer, rs);
			} else if (rs == 0) {
				break;
			} else {
				fprintf(stderr, "recv(client) failed: %s\n",
						strerror(errno));
				exit(1);
			}
		}
	}

	/* clean up */
	telnet_free(telnet);
	close(sock);

	return 0;
}
Пример #7
0
int main(int argc, char **argv) {
	char buffer[512];
	short listen_port;
	int listen_sock;
	int rs;
	int i;
	struct sockaddr_in addr;
	socklen_t addrlen;
	struct pollfd pfd[MAX_USERS + 1];

	/* initialize Winsock */
#if defined(_WIN32)
	WSADATA wsd;
	WSAStartup(MAKEWORD(2, 2), &wsd);
#endif

	/* check usage */
	if (argc != 2) {
		fprintf(stderr, "Usage:\n ./telnet-chatd <port>\n");
		return 1;
	}

	/* initialize data structures */
	memset(&pfd, 0, sizeof(pfd));
	memset(users, 0, sizeof(users));
	for (i = 0; i != MAX_USERS; ++i)
		users[i].sock = -1;

	/* parse listening port */
	listen_port = (short)strtol(argv[1], 0, 10);

	/* create listening socket */
	if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		fprintf(stderr, "socket() failed: %s\n", strerror(errno));
		return 1;
	}

	/* reuse address option */
	rs = 1;
	setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (void*)&rs, sizeof(rs));

	/* bind to listening addr/port */
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(listen_port);
	if (bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
		fprintf(stderr, "bind() failed: %s\n", strerror(errno));
		return 1;
	}

	/* listen for clients */
	if (listen(listen_sock, 5) == -1) {
		fprintf(stderr, "listen() failed: %s\n", strerror(errno));
		return 1;
	}

	printf("LISTENING ON PORT %d\n", listen_port);

	/* initialize listening descriptors */
	pfd[MAX_USERS].fd = listen_sock;
	pfd[MAX_USERS].events = POLLIN;

	/* loop for ever */
	for (;;) {
		/* prepare for poll */
		for (i = 0; i != MAX_USERS; ++i) {
			if (users[i].sock != -1) {
				pfd[i].fd = users[i].sock;
				pfd[i].events = POLLIN;
			} else {
				pfd[i].fd = -1;
				pfd[i].events = 0;
			}
		}

		/* poll */
		rs = poll(pfd, MAX_USERS + 1, -1);
		if (rs == -1 && errno != EINTR) {
			fprintf(stderr, "poll() failed: %s\n", strerror(errno));
			return 1;
		}

		/* new connection */
		if (pfd[MAX_USERS].revents & POLLIN) {
			/* acept the sock */
			addrlen = sizeof(addr);
			if ((rs = accept(listen_sock, (struct sockaddr *)&addr,
					&addrlen)) == -1) {
				fprintf(stderr, "accept() failed: %s\n", strerror(errno));
				return 1;
			}

			printf("Connection received.\n");

			/* find a free user */
			for (i = 0; i != MAX_USERS; ++i)
				if (users[i].sock == -1)
					break;
			if (i == MAX_USERS) {
				printf("  rejected (too many users)\n");
				_send(rs, "Too many users.\r\n", 14);
				close(rs);
			}

			/* init, welcome */
			users[i].sock = rs;
			users[i].telnet = telnet_init(telopts, _event_handler, 0,
					&users[i]);
			telnet_negotiate(users[i].telnet, TELNET_WILL,
					TELNET_TELOPT_COMPRESS2);
			telnet_printf(users[i].telnet, "Enter name: ");
		}

		/* read from client */
		for (i = 0; i != MAX_USERS; ++i) {
			/* skip users that aren't actually connected */
			if (users[i].sock == -1)
				continue;

			if (pfd[i].revents & POLLIN) {
				if ((rs = recv(users[i].sock, buffer, sizeof(buffer), 0)) > 0) {
					telnet_recv(users[i].telnet, buffer, rs);
				} else if (rs == 0) {
					printf("Connection closed.\n");
					close(users[i].sock);
					if (users[i].name != 0) {
						_message(users[i].name, "** HAS DISCONNECTED **");
						free(users[i].name);
						users[i].name = 0;
					}
					telnet_free(users[i].telnet);
					users[i].sock = -1;
					break;
				} else if (errno != EINTR) {
					fprintf(stderr, "recv(client) failed: %s\n",
							strerror(errno));
					exit(1);
				}
			}
		}
	}

	/* not that we can reach this, but GCC will cry if it's not here */
	return 0;
}