Server IP : 103.119.228.120 / Your IP : 3.138.125.86 Web Server : Apache System : Linux v8.techscape8.com 3.10.0-1160.119.1.el7.tuxcare.els2.x86_64 #1 SMP Mon Jul 15 12:09:18 UTC 2024 x86_64 User : nobody ( 99) PHP Version : 5.6.40 Disable Function : shell_exec,symlink,system,exec,proc_get_status,proc_nice,proc_terminate,define_syslog_variables,syslog,openlog,closelog,escapeshellcmd,passthru,ocinum cols,ini_alter,leak,listen,chgrp,apache_note,apache_setenv,debugger_on,debugger_off,ftp_exec,dl,dll,myshellexec,proc_open,socket_bind,proc_close,escapeshellarg,parse_ini_filepopen,fpassthru,exec,passthru,escapeshellarg,escapeshellcmd,proc_close,proc_open,ini_alter,popen,show_source,proc_nice,proc_terminate,proc_get_status,proc_close,pfsockopen,leak,apache_child_terminate,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,dl,symlink,shell_exec,system,dl,passthru,escapeshellarg,escapeshellcmd,myshellexec,c99_buff_prepare,c99_sess_put,fpassthru,getdisfunc,fx29exec,fx29exec2,is_windows,disp_freespace,fx29sh_getupdate,fx29_buff_prepare,fx29_sess_put,fx29shexit,fx29fsearch,fx29ftpbrutecheck,fx29sh_tools,fx29sh_about,milw0rm,imagez,sh_name,myshellexec,checkproxyhost,dosyayicek,c99_buff_prepare,c99_sess_put,c99getsource,c99sh_getupdate,c99fsearch,c99shexit,view_perms,posix_getpwuid,posix_getgrgid,posix_kill,parse_perms,parsesort,view_perms_color,set_encoder_input,ls_setcheckboxall,ls_reverse_all,rsg_read,rsg_glob,selfURL,dispsecinfo,unix2DosTime,addFile,system,get_users,view_size,DirFiles,DirFilesWide,DirPrintHTMLHeaders,GetFilesTotal,GetTitles,GetTimeTotal,GetMatchesCount,GetFileMatchesCount,GetResultFiles,fs_copy_dir,fs_copy_obj,fs_move_dir,fs_move_obj,fs_rmdir,SearchText,getmicrotime MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/local/share/perl5/Net/OSCAR/Connection/ |
Upload File : |
=pod Net::OSCAR::Connection::Direct -- OSCAR direct connections =cut package Net::OSCAR::Connection::Direct; BEGIN { $Net::OSCAR::Connection::Direct::VERSION = '1.928'; } $REVISION = '$Revision$'; use strict; use Carp; use vars qw(@ISA $REVISION); use Socket; use Symbol; use Net::OSCAR::Common qw(:all); use Net::OSCAR::Constants; use Net::OSCAR::Utility; use Net::OSCAR::XML; @ISA = qw(Net::OSCAR::Connection); sub process_one($;$$$) { my($self, $read, $write, $error) = @_; my $snac; if($error) { $self->{sockerr} = 1; $self->disconnect(); if($self->{rv}->{ft_state} eq "connecting" or $self->{rv}->{ft_state} eq "connected") { $self->log_print(OSCAR_DBG_INFO, "Couldn't connect to rendezvous peer; revising rendezvous."); $self->{session}->rendezvous_revise($self->{rv}->{cookie}); } return; } #$self->log_printf(OSCAR_DBG_DEBUG, # "Called process_one on direct connection: st=%s, fts=%s, dir=%s, acp=%s, r=$read, w=$write, e=$error", # $self->{state}, $self->{rv}->{ft_state}, $self->{rv}->{direction}, $self->{rv}->{accepted} #); if($read and $self->{rv}->{ft_state} eq "listening") { my $newsock = gensym(); if(accept($newsock, $self->{socket})) { $self->log_print(OSCAR_DBG_DEBUG, "Accepted incoming connection."); $self->{session}->callback_connection_changed($self, "deleted"); close($self->{socket}); $self->{socket} = $newsock; $self->set_blocking(0); if($self->{rv}->{direction} eq "send") { $self->{state} = "write"; } else { $self->{state} = "read"; } $self->{rv}->{ft_state} = "connected"; $self->{session}->callback_connection_changed($self, $self->{state}); return 1; } else { $self->log_print(OSCAR_DBG_WARN, "Failed to accept incoming connection: $!"); return 0; } } elsif($write and $self->{rv}->{ft_state} eq "proxy_connect") { $self->log_print(OSCAR_DBG_DEBUG, "Connected to proxy."); $self->{connected} = 1; my $ret; if($self->{sent_proxy_init}++) { my $packet = protoparse($self->{session}, "direct_connect_proxy_init")->pack( msg_type => 2, screenname => $self->{rv}->{peer}, cookie => $self->{rv}->{cookie}, capability => OSCAR_CAPS()->{filexfer}->{value} ); $ret = $self->write(pack("n", length($packet)) . $packet); } else { $ret = $self->write(); } return $ret unless $ret; delete $self->{sent_proxy_init}; $self->{rv}->{ft_state} = "proxy_ack"; $self->{state} = "read"; $self->{session}->callback_connection_changed($self, "read"); } elsif($read and $self->{rv}->{ft_state} eq "proxy_ack") { my $ret = $self->get_proxy_header("direct_connect_proxy_reply"); return $ret unless $ret; if($ret->{magic} != 1098 or $ret->{msg_type} != 3) { $self->{sockerr} = 1; $self->disconnect(); $self->log_print(OSCAR_DBG_INFO, "Bad response from proxy; revising rendezvous."); $self->{session}->rendezvous_revise($self->{rv}->{cookie}); return undef; } else { $self->{rv}->{ft_state} = "proxy_connected"; $self->{state} = "read"; $self->{session}->callback_connection_changed($self, "read"); my %protodata = ( status => "accept", cookie => $self->{rv}->{cookie}, capability => OSCAR_CAPS()->{$self->{rv}->{type}} ? OSCAR_CAPS()->{$self->{rv}->{type}}->{value} : $self->{rv}->{type}, client_1_ip => $ret->{ip}, port => $ret->{port} ); $self->{session}->send_message($self->{rv}->{sender}, 2, protoparse($self->{session}, "rendezvous_IM")->pack(%protodata)); } } elsif($read and $self->{rv}->{ft_state} eq "proxy_connect") { my $ret = $self->get_proxy_header(); return $ret unless $ret; if($ret->{magic} != 1098 or $ret->{msg_type} != 5) { $self->{sockerr} = 1; $self->disconnect(); $self->log_print(OSCAR_DBG_INFO, "Bad response from proxy; revising rendezvous."); $self->{session}->rendezvous_revise($self->{rv}->{cookie}); return undef; } else { $self->log_print(OSCAR_DBG_DEBUG, "Rendezvous peer connected to proxy."); $self->{rv}->{ft_state} = "connected"; if($self->{rv}->{direction} eq "send") { $self->{state} = "write"; } else { $self->{state} = "read"; } $self->{session}->callback_connection_changed($self, $self->{state}); } } elsif($write and $self->{rv}->{ft_state} eq "connecting") { $self->log_print(OSCAR_DBG_DEBUG, "Connected."); $self->{connected} = 1; my %protodata; $protodata{status} = "accept"; $protodata{cookie} = $self->{rv}->{cookie}; $protodata{capability} = OSCAR_CAPS()->{$self->{rv}->{type}} ? OSCAR_CAPS()->{$self->{rv}->{type}}->{value} : $self->{rv}->{type}; $self->{session}->send_message($self->{rv}->{sender}, 2, protoparse($self->{session}, "rendezvous_IM")->pack(%protodata)); $self->{rv}->{ft_state} = "connected"; $self->{rv}->{accepted} = 1; if($self->{rv}->{direction} eq "receive") { $self->{state} = "read"; $self->{session}->callback_connection_changed($self, $self->{state}); } } elsif($write and $self->{rv}->{ft_state} eq "connected") { if($self->{rv}->{direction} eq "send") { return 1 unless $self->{rv}->{accepted}; } $self->log_print(OSCAR_DBG_DEBUG, "Sending OFT header (SYN)."); my $ret; if($self->{sent_oft_header}) { $self->log_print(OSCAR_DBG_DEBUG, "Flushing buffer"); $ret = $self->write(); # Flush buffer } else { $self->log_print(OSCAR_DBG_DEBUG, "Sending initial header"); $self->{sent_oft_header} = 1; if($self->{rv}->{direction} eq "send" and !$self->{got_files}) { $self->{checksum} = $self->checksum($self->{rv}->{data}->[0]); $self->{byte_count} = $self->{rv}->{total_size}; $self->{bytes_left} = length($self->{rv}->{data}->[0]); $self->{filename} = $self->{rv}->{filenames}->[0]; } $ret = $self->send_oft_header(); } return $ret unless $ret; if($self->{rv}->{direction} eq "receive") { if($self->{rv}->{file_count} == 1 or ($self->{sent_oft_header} and $self->{sent_oft_header} >= 2)) { $self->{rv}->{ft_state} = "data"; } else { $self->log_print(OSCAR_DBG_DEBUG, "Sending second header."); $self->{sent_oft_header} = 2; $ret = $self->send_oft_header(); return $ret unless $ret; $self->{rv}->{ft_state} = "data"; } } delete $self->{sent_oft_header}; $self->{state} = "read"; $self->{session}->callback_connection_changed($self, "read"); } elsif($read and $self->{rv}->{ft_state} eq "connected") { $self->log_print(OSCAR_DBG_DEBUG, "Getting OFT header"); my $ret = $self->get_oft_header(); return $ret unless $ret; if($self->{rv}->{direction} eq "send") { $self->{rv}->{ft_state} = "data"; } elsif($self->{got_files}) { $self->{sent_oft_header} = 2; $self->log_print(OSCAR_DBG_DEBUG, "Sending second header."); $ret = $self->send_oft_header(); if($ret) { delete $self->{sent_oft_header}; $self->{rv}->{ft_date} = "data"; $self->{state} = "read"; $self->{session}->callback_connection_changed($self, "read"); return; } } $self->{state} = "write"; $self->{session}->callback_connection_changed($self, "write"); } elsif($self->{rv}->{ft_state} eq "data") { my $ret; if($write and $self->{rv}->{direction} eq "send") { $self->log_print(OSCAR_DBG_DEBUG, "Sending data"); if($self->{sent_data}++) { $ret = $self->write(); } else { $ret = $self->write($self->{rv}->{data}->[0]); } if($ret) { $self->log_print(OSCAR_DBG_DEBUG, "Done sending data"); shift @{$self->{rv}->{data}}; shift @{$self->{rv}->{filenames}}; $self->{sent_data} = 0; $self->{rv}->{ft_state} = "fin"; $self->{state} = "read"; $self->{session}->callback_connection_changed($self, "read"); } else { return $ret; } } elsif($read and $self->{rv}->{direction} eq "receive") { $self->log_printf(OSCAR_DBG_DEBUG, "Receiving %d bytes of data", $self->{read_size}); if($self->{got_data}++) { $self->log_print(OSCAR_DBG_DEBUG, "Getting more data"); $ret = $self->read(); } else { $self->log_print(OSCAR_DBG_DEBUG, "Doing initial read"); $ret = $self->read($self->{read_size}); } if($ret) { $self->log_printf(OSCAR_DBG_DEBUG, "Got complete file, %d bytes.", length($ret)); $self->{rv}->{data} ||= []; push @{$self->{rv}->{data}}, $ret; shift @{$self->{rv}->{filenames}}; $self->{bytes_recv} = length($ret); $self->{got_data} = 0; $self->{received_checksum} = $self->checksum($ret); if($self->{received_checksum} != $self->{checksum}) { $self->log_printf(OSCAR_DBG_WARN, "Checksum mismatch: %lu/%lu", $self->{checksum}, $self->{received_checksum}); $self->log_print(OSCAR_DBG_WARN, "Data: ", hexdump($ret)); $self->{sockerr} = 1; $self->disconnect(); return undef; } else { $self->log_print(OSCAR_DBG_WARN, "Data: ", hexdump($ret)); } $self->{rv}->{ft_state} = "fin"; $self->{state} = "write"; $self->{session}->callback_connection_changed($self, "write"); } else { return $ret; } } } elsif($self->{rv}->{ft_state} eq "fin") { if($read and $self->{rv}->{direction} eq "send") { $self->log_print(OSCAR_DBG_DEBUG, "Getting OFT fin header"); my $ret = $self->get_oft_header(); return $ret unless $ret; if(@{$self->{rv}->{data}}) { $self->{rv}->{ft_state} = "connected"; $self->{state} = "write"; $self->{session}->callback_connection_changed($self, "write"); } else { $self->disconnect(); } return 1; } elsif($write and $self->{rv}->{direction} eq "receive") { $self->log_print(OSCAR_DBG_DEBUG, "Sending OFT fin header"); my $ret = $self->send_oft_header(); return $ret unless $ret; if(++$self->{got_files} < $self->{rv}->{file_count}) { $self->{rv}->{ft_state} = "connected"; $self->{state} = "read"; $self->{session}->callback_connection_changed($self, "read"); } else { $self->disconnect(); } return 1; } } } sub send_oft_header($) { my $self = shift; my $total_size = 0; $total_size += length($_) foreach @{$self->{rv}->{data}}; my $type; my $cookie; if($self->{rv}->{ft_state} eq "connected" and ($self->{sent_oft_header} and $self->{sent_oft_header} != 2)) { if($self->{rv}->{direction} eq "send") { $type = 0x101; $cookie = chr(0) x 8; } else { $type = 0x202; $cookie = $self->{rv}->{cookie}; } } else { $type = 0x204; $cookie = $self->{rv}->{cookie}; } my %protodata = ( type => $type, cookie => $cookie, file_count => $self->{rv}->{file_count}, files_left => scalar(@{$self->{rv}->{data}}), byte_count => $self->{byte_count}, bytes_left => $self->{bytes_left}, mtime => time(), ctime => 0, bytes_received => $self->{bytes_recv}, checksum => $self->{checksum}, received_checksum => $self->{received_checksum}, filename => $self->{filename} ); $self->write(protoparse($self->{session}, "file_transfer_header")->pack(%protodata)); } sub get_oft_header($) { my $self = shift; my $header = $self->read(6); return $header unless $header; my($magic, $length) = unpack("a4 n", $header); if($magic ne "OFT2") { $self->log_print(OSCAR_DBG_WARN, "Got unexpected data while reading file transfer header!"); $self->{sockerr} = 1; $self->disconnect(); return undef; } my $data = $self->read($length - 6); return $data unless $data; my %protodata = protoparse($self->{session}, "file_transfer_header")->unpack($header . $data); if($self->{rv}->{direction} eq "receive") { if( $protodata{file_count} != $self->{rv}->{file_count} or $protodata{byte_count} != $self->{rv}->{total_size} ) { $self->log_print(OSCAR_DBG_WARN, "Rendezvous header data doesn't match initial proposal!"); $self->{sockerr} = 1; $self->disconnect(); return undef; } else { $self->{read_size} = $protodata{bytes_left}; $self->{checksum} = $protodata{checksum}; $self->{byte_count} = $protodata{byte_count}; $self->{bytes_left} = $protodata{bytes_left}; $self->{filename} = $protodata{filename}; } } else { if($protodata{cookie} ne $self->{rv}->{cookie}) { $self->log_print(OSCAR_DBG_WARN, "Rendezvous header cookie doesn't match initial proposal!"); $self->{sockerr} = 1; $self->disconnect(); return undef; } } $self->log_print(OSCAR_DBG_DEBUG, "Got OFT header."); return 1; } # Adopted from Gaim's implementation sub checksum($$) { my($self, $part) = @_; my $check = sprintf("%lu", (0xFFFF0000 >> 16) & 0xFFFF); for(my $i = 0; $i < length($part); $i++) { my $oldcheck = $check; my $byte = ord(substr($part, $i, 1)); my $val = ($i & 1) ? $byte : ($byte << 8); $check -= $val; $check = sprintf("%lu", $check); if($check > $oldcheck) { $check--; $check = sprintf("%lu", $check); } } $check = (($check & 0x0000FFFF) + ($check >> 16)); $check = (($check & 0x0000FFFF) + ($check >> 16)); $check = $check << 16; return sprintf("%lu", $check); } sub get_proxy_header($;$) { my ($self, $protobit) = @_; my $socket = $self->{socket}; my ($buffer, $len); my $nchars; $protobit ||= "direct_connect_proxy_hdr"; if(!$self->{buff_gotproxy}) { my $header = $self->read(2); if(!defined($header)) { return undef; } elsif($header eq "") { return ""; } $self->{buff_gotproxy} = 2; ($self->{proxy_size}) = unpack("n", $header); } if($self->{proxy_size} > 0) { my $data = $self->read($self->{proxy_size}, 2); if(!defined($data)) { return undef; } elsif($data eq "") { return ""; } $self->log_print_cond(OSCAR_DBG_PACKETS, sub { "Got ", hexdump($data) }); delete $self->{buff_gotproxy}; return {protoparse($self->{session}, $protobit)->unpack($data)}; } else { delete $self->{buff_gotproxy}; return ""; } } 1;