[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re:Re: need help about how to use libssh to achieve the port forwardding


I have tried those functions, but I can't get any information about ipforwads. I send the part of the code with this mail. I would like to know where to use those functions to get the information what I need.







At 2012-08-23 15:58:22,"Andreas Schneider" <asn@xxxxxxxxxxxxxx> wrote:
>On Tuesday 21 August 2012 15:35:49 you wrote:
>> Hi,
>
>Hi,
>
>> I have written a ssh server program  based on libssh. It can achieve the
>> basic functions of the server. Now I want to join ssh port forwarding in
>> the program.But I do not know how to achieve the response of port
>> forwarding requests.Will libssh support response port forwarding the
>> request sent by the client?I would like to ask how to achieve and are there
>> some similar examples?
>
>there is no documentation for this code.
>
>See
>
>ssh_message_channel_request_open_originator()
>ssh_message_channel_request_open_originator_port()
>ssh_message_channel_request_open_destination()
>ssh_message_channel_request_open_destination_port()
>
>The to accecpt the request. The rest is up to you to connect the local socket 
>to the ssh channel.
>
>
>	-- andreas
>
>-- 
>Andreas Schneider                   GPG-ID: F33E3FC6
>www.cryptomilk.org                asn@xxxxxxxxxxxxxx
>
>
void* work_main(void *arg)
{
	ssh_session session = NULL;
	ssh_session client_session = NULL;
	ssh_message message = NULL;
	sftp_session sftp_client_session = NULL;
	sftp_session sftp_server_session = NULL;
	ssh_channel chan = 0;
	int auth = 0;
	int sftp_flag = 0;
	int shell = 0;
	ssh_channel channel = NULL;
	int ret = 0;
	int is_auth = 0;
	int subtype;
	//start time
	long login_timeout = g_config_val->login_timeout;
	proxy_session *p_proxy_session = 0;

	proxy_auth_info *proxyauth_info = 0;
	device_auth_info *deviceauth_info = 0;
	struct in_addr addr1;
	int i;

	session = (ssh_session) arg;

	ret = ssh_handle_key_exchange(session);
	if (ret != SSH_OK)
	{
		ERROR(
				"session[%ld] work_main: ssh_handle_key_exchange error.(workmain.c)(%s)\n",
				p_proxy_session->id, ssh_get_error(session));
		ret = SSHPROXY_SEVKEYEX_ERROR;
		goto END;
	}


	do
	{

		PRINT("session[%ld] login time: login timeout: %lds\n",
				p_proxy_session->id, login_timeout);
//		message = ssh_message_get(session);
		message = ssh_message_get_with_timeout(session, login_timeout);

		//check whether login is time out
		if (message == -1)
		{
			DEBUG("session[%ld] login is time out!.(work_main,workmain.c)\n",
					p_proxy_session->id);
			ret = SSHPROXY_LOGINTIMEOUT_ERROR;
			goto END;
		}
		
		if (!message)
			break;
		switch (ssh_message_type(message))
		{
		case SSH_REQUEST_AUTH:
			subtype = ssh_message_subtype(message);
			switch (subtype)
			{
			case SSH_AUTH_METHOD_PASSWORD:
				DEBUG(
						"session[%ld]:User %s, Pass %s\n",
						p_proxy_session->id, ssh_message_auth_user(message), ssh_message_auth_password(message));

				//session state: 16 get client username and password
				proxy_session_set_state(p_proxy_session,
						PROXY_SESSION_STATE_AUTH);

				

				if (auth_password_t(proxyauth_info,deviceauth_info,p_proxy_session))
				{
					DEBUG(
							"username = %s\npassword = %s\n",
							deviceauth_info->username, deviceauth_info->password);
					DEBUG("hostip = %s\nport = %d\n",
							deviceauth_info->deviceip, deviceauth_info->port);
					DEBUG("device_index = %d\n");

					auth = 1;
					ssh_message_auth_reply_success(message, 0);


					break;
				}
				//fixme exit password error
				else
				{
					is_auth = 1;
					break;
				}
			case SSH_AUTH_METHOD_NONE:
			default:
				ssh_message_auth_set_methods(message, SSH_AUTH_METHOD_PASSWORD);
				ssh_message_reply_default(message);
				break;
			}
			break;
		default:
			ssh_message_reply_default(message);
			break;
		}
		ssh_message_free(message);
		PRINT("session[%ld] auth: %d\n", p_proxy_session->id, auth);
		if (is_auth == 1)
			break;
	} while (!auth);

	if (!auth)
	{
		ERROR("session[%ld] work_main: authentication error.(workmain.c)(%s)\n",
				p_proxy_session->id, ssh_get_error(session));
		ret = SSHPROXY_SEVAUTH_ERROR;
		goto END;
	}


	do
	{
		message = ssh_message_get(session);
		
		if (message)
		{
			if (ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN
					&& ssh_message_subtype(message) == SSH_CHANNEL_SESSION)
			{
				chan = ssh_message_channel_request_open_reply_accept(message);
				ssh_message_free(message);
				break;
			}
			else
			{
				ssh_message_reply_default(message);
				ssh_message_free(message);
			}
		}
		else
		{
			break;
		}
	} while (!chan);

	if (!chan)
	{
		ERROR(
				"session[%ld] workmain: request a channel failed.(workmain.c)(%s)\n",
				p_proxy_session->id, ssh_get_error(session));
		ret = SSHPROXY_SEVCHANNEL_ERROR;
		goto END;
	}

	
	/* wait for a shell */
	do
	{
		message = ssh_message_get(session);
		//check whether session is time out
		if (proxy_session_is_timeout(p_proxy_session)
				|| proxy_session_is_killed(p_proxy_session))
		{
			DEBUG("session[%ld] is time out!(work_main,workmain.c)\n",
					p_proxy_session->id);
			ret = SSHPROXY_SESSIONTIMEOUT_ERROR;
			goto END;
		}
		if (message != NULL)
		{
			if (ssh_message_type(message) == SSH_REQUEST_CHANNEL)
			{
				subtype = ssh_message_subtype(message);
				if (subtype == SSH_CHANNEL_REQUEST_SHELL)
				{
					shell = 1;
					ssh_message_channel_request_reply_success(message);
					
					printf("originator = %d",ssh_message_channel_request_open_originator(message));

					ssh_message_free(message);
					break;
				}
				else if (subtype == SSH_CHANNEL_REQUEST_PTY)
				{
					ssh_message_channel_request_reply_success(message);

					printf("originator = %d",ssh_message_channel_request_open_originator(message));

					ssh_message_free(message);
					continue;
				}
				else if (subtype == SSH_CHANNEL_REQUEST_SUBSYSTEM)
				{

			
					printf("originator = %d",ssh_message_channel_request_open_originator(message));

					if (!strcmp(ssh_message_channel_request_subsystem(message),
							"sftp"))
					{
						ssh_message_channel_request_reply_success(message);
						ssh_message_free(message);
						sftp_flag = 1;
						shell = 1;
						break;
					}
					else
					{
						ERROR(
								"session[%ld] subsystem unknown:%s\n",
								p_proxy_session->id, ssh_message_channel_request_subsystem(message));
					}
				}
				else if (subtype == SSH_CHANNEL_REQUEST_EXEC)
				{
					ssh_message_channel_request_reply_success(message);
					//xxx:delete
					printf("originator = %d",ssh_message_channel_request_open_originator(message));
				}
			}
			ssh_message_reply_default(message);
			ssh_message_free(message);
		}
		else
		{
			break;
		}
	} while (!shell);

	if (!shell)
	{
		ERROR("session[%ld] workmain: request shell failed.(workmain.c)(%s)\n",
				p_proxy_session->id, ssh_get_error(session));
		ret = SSHPROXY_SEVSHELL_ERROR;
		goto END;
	}

	

	if (sftp_flag == 1)
	{
		INFO("session[%ld] is SFTP session.\n", p_proxy_session->id);
		INFO("SFTP session[%ld] connects the remote server...\n",
				p_proxy_session->id);
		proxy_session_delete(g_proxy_mod_ssh, p_proxy_session);
		p_proxy_session = proxy_session_add(g_proxy_mod_sftp);

		if (p_proxy_session == 0)
		{
			ERROR(
					"SFTP session work_main: proxy_session_add SFTP Failed.(workmain.c)\n");
			goto END;
		}
		else
		{
			
			inet_aton(deviceauth_info->deviceip,&addr1);
			p_proxy_session->device_ip = addr1.s_addr;
			proxy_session_db_log_update(p_proxy_session,0,0,0);
			DEBUG(
					"SFTP session[%ld]: client ip(%d), client port(%d)\n",
					p_proxy_session->id, p_proxy_session->client_ip, p_proxy_session->client_port);
		}

		sftp_server_session = sftp_server_new(session, chan);
		for (i = 0; i < 10; i++)
		{
			ret = sftp_server_init(sftp_server_session);
			if (ret && ret != -2)
			{
				ERROR(
						"SFTP session[%ld] workmain: sftp_server_init error.(workmain.c)(%s)\n",
						p_proxy_session->id, ssh_get_error(session));
				//			ssh_free(session);
				goto END;
			}
			if (ret == 0)
			{
				break;
			}
		}

		if (i == 10)
		{
			ERROR(
					"SFTP session[%ld] workmain: sftp_server_init error.(workmain.c)(%s)\n",
					p_proxy_session->id, ssh_get_error(session));
			//			ssh_free(session);
			goto END;
		}
		

		ret = connect_sftp_server(&sftp_client_session, p_proxy_session,
				deviceauth_info);
		if (ret != SSH_OK)
		{
			ERROR(
					"SFTP session[%ld] workmain: connect_sftp_server error.(workmain.c)\n",
					p_proxy_session->id);
			goto END;
		}

		

		sftp_proxy_loop(sftp_server_session, sftp_client_session,
				p_proxy_session);
//		sftp_proxy_loop_new(sftp_server_session, sftp_client_session);
//		sftp_free(sftp_server_session);
//		sftp_free(sftp_client_session);
	}
	else
	{
		

		ret = connect_ssh_server(&client_session, &channel, p_proxy_session,
				deviceauth_info);
		if (ret != SSHPROXY_OK)
		{
			ERROR(
					"SSH session[%ld] workmain: connect_ssh_server error.(workmain.c)\n",
					p_proxy_session->id);
			goto END;
		}

		
		DEBUG(
				"SSH session[%ld]: device IP(%d), device port(%d).\n",
				p_proxy_session->id, p_proxy_session->device_ip, p_proxy_session->device_port);

		INFO("SSH session[%ld] connects the remote server OK.\n",
				p_proxy_session->id);
		//session state:64 connect the device OK.
		proxy_session_set_state(p_proxy_session, 64);
		ssh_proxy_loop(client_session, channel, session, chan, p_proxy_session);
	}

	END:
	//session state: 240 start to close the session and clean the resources
	if (p_proxy_session != NULL)
	{
		proxy_session_set_state(p_proxy_session, 240);

		if (sftp_flag == 1)
		{
			INFO("SFTP session[%ld] starts to finalize...\n",
					p_proxy_session->id);

			if (sftp_client_session != NULL)
			{
				client_session = sftp_client_session->session;
				sftp_free(sftp_client_session);
				if (client_session != NULL)
				{
					ssh_disconnect(client_session);
					ssh_free(client_session);
				}
			}

			sftp_free(sftp_server_session);
			ssh_disconnect(session);
			ssh_free(session);
			INFO("SFTP session[%ld] finalizes OK.\n", p_proxy_session->id);
		}
		else
		{
			INFO("SSH session[%ld] starts to finalize...\n",
					p_proxy_session->id);
			if (client_session != NULL)
			{
				ssh_disconnect(client_session);
				ssh_free(client_session);
			}
			ssh_disconnect(session);
			ssh_free(session);
			INFO("SSH session[%ld] starts to finalize...\n",
					p_proxy_session->id);
		}

		if (sftp_flag == 1)
		{
			unsigned long id_tmp = p_proxy_session->id;
			INFO("SFTP session[%ld] is deleting from the session list.\n",
					p_proxy_session->id);
			proxy_session_delete(g_proxy_mod_sftp, p_proxy_session);
			INFO("SFTP session[%ld] deleted OK.\n", id_tmp);
			INFO("######### SFTP SESSION EXIT #########\n");
		}
		else
		{
			unsigned long id_tmp = p_proxy_session->id;
			INFO("SSH session[%ld] is deleting from the session list.\n",
					p_proxy_session->id);
			proxy_session_delete(g_proxy_mod_ssh, p_proxy_session);
			INFO("SSH session[%ld] deleted OK.\n", id_tmp);
			INFO("######### SSH SESSION EXIT #########\n");
		}
	}
	proxy_auth_proxyinfo_destroy(proxyauth_info);
	proxy_auth_deviceinfo_destroy(deviceauth_info);

	return NULL;
}






Archive administrator: postmaster@lists.cynapses.org