Задача: написать протопип FTP-прокси, который должен
1. Принимать подключения FTP-клиентов, в соответствии с именем пользователя выбирать из конфига параметры доступа к удалённому серверу, логиниться на нем и транлсировать команды FTP - протокола и ответы.
2. Вести логи.
Основная проблема - отделить "реальные" параметры доступа по FTP, от пользователей, которые их переодически проёживают, выдав им "игрушечные" параметры, в том числе и имя хоста этого прокси.
Средства отладки
1. Мой комп (127.0.0.1) и Perl-интерпретатор (типа прокси)
2. FTP-сервер в локальной сети (ftp://r-asian:111@150.150.150.254:21)
3. gftp как ftp-client, которым я и подключаюсь к 127.0.0.1:21
Исходный код:
#!/usr/bin/perl
use Socket;
$host = "127.0.0.1";
$port = 21;
$work = 1;
$buffer_size=65536;
$host = inet_aton($host);
$sock_name = sockaddr_in($port,$host)
or die "Couldn't convert $host into an Internet address: $!\n";
socket(SERVER,PF_INET,SOCK_STREAM,getprotobyname('tcp'))
or die "Couldn't create socket: $!\n";
setsockopt(SERVER,SOL_SOCKET,SO_REUSEADDR,1)
or die "setsockopt() failed: $!\n";
bind(SERVER,$sock_name)
or die "Couldn't bind to port $port: $!\n";
listen(SERVER,127);
while ($work){
my $rem_addr = accept(CLIENT,SERVER);
my $pid=fork();
if ($pid==0)
{
# Алло, FTP-прокси слушает
send(CLIENT,"220 FTP server ready.\r\n",0);
while(1)
{
# Получаем от клиента очередную команду
recv(CLIENT,$data,$buffer_size,0);
print "client=>: $data";
# Получаем имя пользователя и по нему проводим авторизацию
if ($data=~/^.*USER\s([\d\w\.\-\_]*).*$/)
{
socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
$iaddr = inet_aton(user2remote_ip($1));
$paddr = sockaddr_in(user2remote_port($1), $iaddr);
connect(SOCK, $paddr);
$data=<SOCK>;
send (SOCK, "USER ".user2remote_username($1)."\r\n", 0);
$data=<SOCK>;
print $data;
send (SOCK, "PASS ".user2remote_password($1)."\r\n", 0);
$data=<SOCK>;
print $data;
send(CLIENT,"$data.\r\n",0);
}
else
{
send(SOCK,$data,0);
recv(SOCK,$data,$buffer_size,0);
send(CLIENT,$data,0);
}
# Пропускаем пароль (нах..й он никому не нужен)
if ($data=~/^.*PASS\s.*$/)
{
}
}
close(SOCK);
close CLIENT;
}
close CLIENT;
}
close SERVER;
sub user2remote_ip
{
my ($username)=@_;
$remote_ip="150.150.150.254";
return $remote_ip;
}
sub user2remote_username
{
my ($username)=@_;
$remote_username="r-asian";
return $remote_username;
}
sub user2remote_password
{
my ($username)=@_;
$remote_password="111";
return $remote_password;
}
sub user2remote_port
{
my ($username)=@_;
$remote_port="21";
return $remote_port;
}
--------------------------------------------
Как он работает:
--------------------------------------------
Поиск 127.0.0.1
Попытка 127.0.0.1:21
Подключение к 127.0.0.1:21
220 FTP server ready.
USER intelhouse.ru
230 User r-asian logged in.
SYST
.
215 UNIX Type: L8 Version: BSD-199506
TYPE I
200 Type set to I.
PWD
257 "/home/r-asian" is current directory.
Loading directory listing /home/r-asian from server (LC_TIME=ru_RU)
PASV
227 Entering Passive Mode (150,150,150,254,209,39)
LIST -aL
150 Opening BINARY mode data connection for '/bin/ls'.
И ТУТ ОН ПОВИСАЕТ :-((
---------------------------------------------------------
Дополнительно скажу, что:
Если выполнение perl-скрипта оборвать, то клиент показывает список файлов(что от него и требовалось)
Чо не так, а? :-(
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум troubles with perl & tcp sockets (2006)
- Форум Perl: проблема совместимости «use Socket;» (2004)
- Форум [perl] почему так медленно читается сокет? (2009)
- Форум Perl & win32 (2005)
- Форум Работа с сокетами в C (2010)
- Форум Сканер портов (2000)
- Форум TCPSERVER (2019)
- Форум perl, IPC & socket - чего тут не так? (2006)
- Форум сваливается send (сокет) (2008)
- Форум socket error (2009)