Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   MAIL.ru авторизация на perl (https://forum.antichat.xyz/showthread.php?t=116399)

rdrule 17.04.2009 19:20

MAIL.ru авторизация на perl
 
Здравствуйте, подскажите в чем проблема.
Недавно начал изучать перл, и задался целью написать скрипт авторизации на MAIL.ru
вот код

Код:

#!/usr/bin/perl
use IO::Socket;
use strict;

my $login = "Логин";
my $domain = "mail.ru";
my $password = "пароль";


#STEP 1
my $hostname = "win.mail.ru"; 
my $path = "/cgi-bin/login";

my $sock = new IO::Socket::INET(PeerAddr  =>$hostname,PeerPort  => 80,PeerProto => 'tcp',TimeOut  => 5);

my $headers = "GET $path HTTP/1.0\r\n";
$headers .= "Host: $hostname\r\n"; 
$headers .= "Connection: keep-alive\r\n\r\n"; 

my $answ;
print $sock $headers;
sysread( $sock, $answ, 4096);

my $mrcu = '';
$answ=~ s/\w{28}/$mrcu=$&/gime;
close $sock;


#STEP 2
$path = "/cgi-bin/auth";
$sock = new IO::Socket::INET(PeerAddr  =>$hostname,PeerPort  => 80,PeerProto => 'tcp',TimeOut  => 5);
my $data = "page=&post=&login_from=&Login=$login&Domain=$domain&Password=$password&\r\n\r\n"; 

$headers = "POST $path HTTP/1.0\r\n"; 
$headers .= "Host: $hostname\r\n"; 
$headers .= "Content-type: application/x-www-form-urlencoded\r\n"; 
$headers .= "Content-Length: ".length($data)."\r\n"; 
$headers .= "Cookie: mrcu=$mrcu\r\n";
$headers .= "Connection: Close\r\n\r\n";

print $sock ($headers.$data);
sysread( $sock, my $answ, 4096);

my ($mpop, $t, $location) = '';
$answ=~ s/\w{10}\:\S*/$mpop=$&/gime;chop $mpop;$answ=~ s/\w{10}\:\S*//gim;
$answ=~ s/(\w{88})/$t=$&/gime;
$mpop=~ s/\:\S{98}/$location=$&/gime;
$location=~ s/\://gim;$location="http://win.mail.ru/cgi-bin/checkcookie?id=".$location;
close $sock;

#STEP 3
$sock = new IO::Socket::INET(PeerAddr  =>$hostname,PeerPort  => 80,PeerProto => 'tcp',TimeOut  => 5);

$headers = "GET $location HTTP/1.1\r\n";
$headers .= "Host: $hostname\r\n"; 
$headers .= "Content-type: application/x-www-form-urlencoded\r\n"; 
$headers .= "Cookie: mrcu=$mrcu; Mpop=$mpop; t=$t]\r\n";
$headers .= "Connection: keep-alive\r\n\r\n"; 

print $sock ($headers.$data);
sysread( $sock, my $answ, 4096);
close $sock;

#STEP 4
$hostname = "win.mail.ru"; 
$path = "http://win.mail.ru/cgi-bin/start?back=1";

$sock = new IO::Socket::INET(PeerAddr  =>$hostname,PeerPort  => 80,PeerProto => 'tcp',TimeOut  => 20);

$headers = "GET $path HTTP/1.1\r\n";
$headers .= "Host: $hostname\r\n"; 
$headers .= "Content-type: application/x-www-form-urlencoded\r\n"; 
$headers .= "Accept-Language: ru-RU,ru;q=0.9,en;q=0.8\r\n";
$headers .= "Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n";
$headers .= "Cookie: mrcu=$mrcu; Mpop=$mpop; t=$t\r\n";
$headers .= "Connection: keep-alive\r\n\r\n";

print $sock ($headers.$data);
sysread( $sock, my $main, 80000);

print $main;

Авторизация, как я понял, проходит в 4 этапа:
1)при входе на сайт нам дают "печеньку" $mrcu
2)потом идет авторизация, и нам дают еще $mpop и $t
3)идет редирект на проверку кукисов
4)сам вход на мейл

проблема заключаеться в том, что после 4го шага скрипт не грузит полность страничку, а только заголовки+1 ява скрипт

подскажите что не так и поправьте код пожалуйста

Sharky 17.04.2009 19:39

может в там в заголовках редирект?

rdrule 17.04.2009 19:51

сервер выдает

Код:

HTTP/1.1 200 OK                                                                                                                     
Server: nginx/0.7.41                                                                                                               
Date: Fri, 17 Apr 2009 15:50:28 GMT                                                                                                 
Content-Type: text/html; charset=windows-1251                                                                                       
Connection: keep-alive                                                                                                             
Cache-Control: no-cache,no-store,must-revalidate                                                                                    Pragma: no-cache                                                                                                                   
Expires: Thu, 17 Apr 2008 15:50:28 GMT                                                                                              Last-
Modified: Fri, 17 Apr 2009 19:50:28 GMT                                                                                        Content-
Length: 75712


Gar|k 17.04.2009 20:10

могу предположить следующее.... recv не обязательно получает указаное количество байт... тоесть вся страница приходит в разных покетах

вот пример реализации "правильной" функции получения и отправки данных на Си

Код:

int sendall(SOCKET s, char *buf, int len, int flags)
{
    int total = 0;
    int n;

    while(total < len)
    {
        n = send(s, buf+total, len-total, flags);
        if(n == -1) { break; }
        total += n;
    }

    return (n==-1 ? -1 : total);
}

// принять ВСЕ ... - правильная функция
int recvall(SOCKET s, char *buf, int len, int flags)
{
    int total = 0;
    int n;

    while(total < len)
    {
        n = recv(s, buf+total, len-total, flags);
        if(n == -1) { break; }
        total += n;
    }

    return (n==-1 ? -1 : total);
}

на PERL давно не писал, но если сам не сможешь помогу перевести код

Kaimi 17.04.2009 20:13

Код:

use warnings;
use IO::Socket;
$|=1;

my $login = "login";
my $domain = "mail.ru";
my $password = "pass";

my $answ1 = req('win.mail.ru', '/cgi-bin/auth', 'POST', "Login=$login&Domain=$domain&Password=$password", 0);
my $ck1 = collect($answ1);
$answ1 =~ /<HTML>http:\/\/win.mail.ru(.+?)<\/HTML>/;
req('win.mail.ru', $1, 'GET', 0, $ck1);
my $answ2 = req('win.mail.ru', '/cgi-bin/start?back=1', 'GET', 0, $ck1);
print $answ2;

sub collect
{
 my $data = $_[0];
 my $cookie = undef;
 while($data =~ /Set-Cookie: (.+?)(;|\r)/igs)
 {
  $cookie .= $1."; ";
 }
 return $cookie;
}
sub req
{
 my($host, $path, $type, $data, $cookies) = @_;
 
 my $sock = new IO::Socket::INET(
                        PeerAddr  => $host,
                        PeerPort  => 80,
                        PeerProto => 'tcp',
                        TimeOut  => 5);

 my $request = "$type $path HTTP/1.0\n".
 "Host: $host\n".
 "Cookie: $cookies\n";
 
 if($type eq "POST")
 {
  $request .= "Content-type: application/x-www-form-urlencoded\n".
  "Content-Length: ".length($data)."\n\n".$data;
 }
 else
 {
  $request .= "\n";
 }
 
 print $sock $request;
 
 my $answ = undef;
 while(my $buf = <$sock>)
 {
  $answ .= $buf;
 }

 return $answ;
}


rdrule 17.04.2009 20:31

спасибо за ответы.
Теперь всё работает, по видимому всё дело было в recv

p.s: а до Kaimi мне еще жить и жить)))


Время: 14:11