int telnet_test_login(ZBX_SOCKET socket_fd) { const char *__function_name = "telnet_test_login"; char buf[MAX_BUFFER_LEN]; size_t sz, offset; int rc, ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); sz = sizeof(buf); offset = 0; while (ZBX_TCP_ERROR != (rc = telnet_read(socket_fd, buf, &sz, &offset))) { if (':' == telnet_lastchar(buf, offset)) break; } convert_telnet_to_unix_eol(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() login prompt:'%.*s'", __function_name, offset, buf); if (ZBX_TCP_ERROR != rc) ret = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
static gboolean telnet_client_read(ZStream *stream, GIOCondition cond G_GNUC_UNUSED, gpointer user_data) { TelnetProxy *self = Z_CAST(user_data, TelnetProxy); gboolean res; z_proxy_enter(self); res = telnet_read(self, stream, EP_CLIENT); z_proxy_return(self, res); }
/* Called on head of multibus group */ GOOD_OR_BAD COM_read( BYTE * data, size_t length, struct connection_in *connection) { struct port_in * pin ; if ( length == 0 ) { return gbGOOD ; } if ( connection == NO_CONNECTION || data == NULL ) { // bad parameters return gbBAD ; } pin = connection->pown ; // unlike write or open, a closed connection isn't automatically opened. // the reason is that reopening won't have the data waiting. We really need // to restart the transaction from the "write" portion if ( FILE_DESCRIPTOR_NOT_VALID( pin->file_descriptor ) ) { return gbBAD ; } switch ( pin->type ) { // test the type of connection case ct_unknown: case ct_none: LEVEL_DEBUG("Unknown type"); break ; case ct_telnet: return telnet_read( data, length, connection ) ; case ct_tcp: // network is ok return COM_read_get_size( data, length, connection ) == (ssize_t) length ? gbGOOD : gbBAD ; case ct_i2c: case ct_netlink: case ct_usb: LEVEL_DEBUG("Unimplemented"); break ; case ct_serial: // serial is ok // printf("Serial read fd=%d length=%d\n",pin->file_descriptor, (int) length); { ssize_t actual = COM_read_get_size( data, length, connection ) ; if ( FILE_DESCRIPTOR_VALID( pin->file_descriptor ) ) { // tcdrain only works on serial conections tcdrain( pin->file_descriptor ); return actual == (ssize_t) length ? gbGOOD : gbBAD ; } break ; } } return gbBAD ; }
int telnet_execute(ZBX_SOCKET socket_fd, const char *command, AGENT_RESULT *result, const char *encoding) { const char *__function_name = "telnet_execute"; char buf[MAX_BUFFER_LEN]; size_t sz, offset; int rc, ret = FAIL; char *command_lf = NULL, *command_crlf = NULL; size_t i, offset_lf, offset_crlf; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); /* `command' with multiple lines may contain CR+LF from the browser; */ /* it should be converted to plain LF to remove echo later on properly */ offset_lf = strlen(command); command_lf = zbx_malloc(command_lf, offset_lf + 1); zbx_strlcpy(command_lf, command, offset_lf + 1); convert_telnet_to_unix_eol(command_lf, &offset_lf); /* telnet protocol requires that end-of-line is transferred as CR+LF */ command_crlf = zbx_malloc(command_crlf, offset_lf * 2 + 1); convert_unix_to_telnet_eol(command_lf, offset_lf, command_crlf, &offset_crlf); telnet_socket_write(socket_fd, command_crlf, offset_crlf); telnet_socket_write(socket_fd, "\r\n", 2); sz = sizeof(buf); offset = 0; while (ZBX_TCP_ERROR != (rc = telnet_read(socket_fd, buf, &sz, &offset))) { if (prompt_char == telnet_lastchar(buf, offset)) break; } convert_telnet_to_unix_eol(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() command output:'%.*s'", __function_name, offset, buf); if (ZBX_TCP_ERROR == rc) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No prompt: %s", zbx_tcp_strerror())); goto fail; } telnet_rm_echo(buf, &offset, command_lf, offset_lf); /* multi-line commands may have returned additional prompts; */ /* this is not a perfect solution, because in case of multiple */ /* multi-line shell statements these prompts might appear in */ /* the middle of the output, but we still try to be helpful by */ /* removing additional prompts at least from the beginning */ for (i = 0; i < offset_lf; i++) { if ('\n' == command_lf[i]) if (SUCCEED != telnet_rm_echo(buf, &offset, "$ ", 2) && SUCCEED != telnet_rm_echo(buf, &offset, "# ", 2) && SUCCEED != telnet_rm_echo(buf, &offset, "> ", 2) && SUCCEED != telnet_rm_echo(buf, &offset, "% ", 2)) { break; } } telnet_rm_echo(buf, &offset, "\n", 1); telnet_rm_prompt(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() stripped command output:'%.*s'", __function_name, offset, buf); if (MAX_BUFFER_LEN == offset) offset--; buf[offset] = '\0'; SET_STR_RESULT(result, convert_to_utf8(buf, offset, encoding)); ret = SUCCEED; fail: zbx_free(command_lf); zbx_free(command_crlf); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int telnet_login(ZBX_SOCKET socket_fd, const char *username, const char *password, AGENT_RESULT *result) { const char *__function_name = "telnet_login"; char buf[MAX_BUFFER_LEN], c; size_t sz, offset; int rc, ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); sz = sizeof(buf); offset = 0; while (ZBX_TCP_ERROR != (rc = telnet_read(socket_fd, buf, &sz, &offset))) { if (':' == telnet_lastchar(buf, offset)) break; } convert_telnet_to_unix_eol(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() login prompt:'%.*s'", __function_name, offset, buf); if (ZBX_TCP_ERROR == rc) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No login prompt")); goto fail; } telnet_socket_write(socket_fd, username, strlen(username)); telnet_socket_write(socket_fd, "\r\n", 2); sz = sizeof(buf); offset = 0; while (ZBX_TCP_ERROR != (rc == telnet_read(socket_fd, buf, &sz, &offset))) { if (':' == telnet_lastchar(buf, offset)) break; } convert_telnet_to_unix_eol(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() password prompt:'%.*s'", __function_name, offset, buf); if (ZBX_TCP_ERROR == rc) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No password prompt")); goto fail; } telnet_socket_write(socket_fd, password, strlen(password)); telnet_socket_write(socket_fd, "\r\n", 2); sz = sizeof(buf); offset = 0; while (ZBX_TCP_ERROR != (rc = telnet_read(socket_fd, buf, &sz, &offset))) { if ('$' == (c = telnet_lastchar(buf, offset)) || '#' == c || '>' == c || '%' == c) { prompt_char = c; break; } } convert_telnet_to_unix_eol(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() prompt:'%.*s'", __function_name, offset, buf); if (ZBX_TCP_ERROR == rc) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Login failed")); goto fail; } ret = SUCCEED; fail: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
z_proxy_enter(self); res = telnet_read(self, stream, EP_CLIENT); z_proxy_return(self, res); } static gboolean telnet_server_read(ZStream *stream G_GNUC_UNUSED, GIOCondition cond G_GNUC_UNUSED, gpointer user_data) { TelnetProxy *self = Z_CAST(user_data, TelnetProxy); gboolean res; z_proxy_enter(self); res = telnet_read(self, stream, EP_SERVER); z_proxy_return(self, res); } static void telnet_init_stream(TelnetProxy *self, ZEndpoint ep, ZStreamCallback cb, gpointer user_data, GDestroyNotify data_notify) { ZStream *stream = self->super.endpoints[ep] = z_stream_push(self->super.endpoints[ep], z_stream_buf_new(NULL, 256 * 1024, Z_SBF_IMMED_FLUSH)); /* FIXME: provide a wrapper for this */ int fd = z_stream_get_fd(stream); int one = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));