📄 gdipc.pl
字号:
close(CONFIG); chmod 0600, $configfile; # initialise cache file open(CACHE, ">$cachefile") or die "Could not create cache file $cachefile: $!\n"; print CACHE "0.0.0.0;0\n"; close(CACHE); chmod 0600, $cachefile;}# check address and connect to server to send updatesub sendlogin { my $username = shift; my $password = shift; my $domain = shift; my $serverip = shift; my $serveraction = shift; my $cachefile = shift; my $mintime = shift; my $maxtime = shift; # trust $serverip if ($serverip =~ /(.*)/) { $serverip = $1; } # last three arguments passed? my $cacheip = '0.0.0.0'; my $cachetime = '0'; if (! $cachefile) { $mintime = 0; $maxtime = 0; } else { # trust $cachefile if ($cachefile =~ /(.*)/) { $cachefile = $1; } print "Cache file name: $cachefile\n"; # read cache if (open(CACHE, "$cachefile")) { my $line = <CACHE>; if ($line) { chomp($line); ($cacheip, $cachetime) = split(/;/,$line); } close(CACHE); } } # requesting offline, but already offline? if (!$opt_i and $serveraction eq '1' and $cacheip eq '0.0.0.0') { print "No update done for $username.$domain - already offline\n"; return; } # use query command to get address? callquery() if $serveraction eq '0' and $opt_q and !$queryaddress; # current time my $timenow = time; # update wanted but not needed? if (($serveraction eq '0' or $serveraction eq '2') and $cacheip ne '0.0.0.0') { # maximum time not exceeded? if ($timenow < ($cachetime + $maxtime)) { # address still valid? if (checkaddress($cacheip)) { print "No update done for $username.$domain - $cacheip still valid\n"; return; } # not enough time gone by? if ($timenow < ($cachetime + $mintime)) { print "No update from $cacheip done for $username.$domain - too soon\n"; return; } } } # get server type, address, port and URL my $srvtype = 'd'; my ($serverhost, $serverport, $url); if ($serverip =~ /^http:\/\/(.*?)(\/.*)$/) { # web server $srvtype = 'w'; $serverip = $1; $url = $2; ($serverhost, $serverport) = split(/:/, $serverip . ':80'); } else { # direct TCP connection ($serverhost, $serverport) = split(/:/, $serverip . ':3495'); } # start the update print "Attempting update at $serverhost ...\n"; my $inet_addr = gethostbyname($serverhost); if (!$inet_addr) { print "Could not do DNS lookup for $serverhost\n"; return; } my $paddr = sockaddr_in($serverport, $inet_addr); # connect to server socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')); if (!connect(SERVER, $paddr)) { print "Could not connect to $serverhost:$serverport\n"; return; } # set autoflush on select(SERVER); $| = 1; select(STDOUT); # retrieve the salt (et al) my $salt; my $gentime; my $checkval; # HTTP headers my $httphdrs = "HTTP/1.0\rUser-Agent: GnuDIP/2.3.5\rPragma: no-cache\rHost: $serverhost:$serverport\r\r"; # direct TCP connection if ($srvtype eq 'd') { $salt = <SERVER>; $salt = '' if ! defined $salt; chomp($salt); # web server } else { #print "GET $url $httphdrs"; print SERVER "GET $url $httphdrs"; my %resp = (); while (my $line = <SERVER>) { $line = '' if ! defined $line; chomp($line); #print "$line\n"; if ($line =~ /^<meta name=\"(.*)\" content=\"(.*)\">$/) { $resp{$1} = $2; } } close SERVER; $salt = $resp{'salt'}; $gentime = $resp{'time'}; $checkval = $resp{'sign'}; # reconnect socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')); if (!connect(SERVER, $paddr)) { print "Could not reconnect to $serverhost:$serverport\n"; return; } select(SERVER); $| = 1; select(STDOUT); } # got a salt? if (!$salt) { print "Server did not send salt for $username.$domain\n"; close SERVER; return; } # get our IP address my $ip; # have address from query? if ($queryaddress) { $ip = $queryaddress; # get IP address of our end of connection } else { my $client_addr = getsockname(SERVER); if (!$client_addr) { print "Could not get our IP address for $username.$domain\n"; close(SERVER); return; } my ($port, $packed_ip) = sockaddr_in($client_addr); $ip = inet_ntoa($packed_ip); } # salt and digest password $password = md5_hex("$password.$salt"); # send update to server and retrieve response my $response = ''; my $receivedip = ''; # direct TCP connection if ($srvtype eq 'd') { my $updmsg = "$username:$password:$domain:$serveraction"; $updmsg .= ":$ip" if $serveraction eq '0'; print SERVER "$updmsg\n"; $response = <SERVER>; close SERVER; $response = '' if ! defined $response; chomp($response); if ($response =~ /^(.*):(.*)$/) { $response = $1; $ip = $2; $receivedip = 1; } # web server } else { my $updmsg = "salt=$salt&time=$gentime&sign=$checkval&user=$username&" . "pass=$password&domn=$domain&reqc=$serveraction"; $updmsg .= "&addr=$ip" if $serveraction eq '0'; #print "GET $url?$updmsg $httphdrs"; print SERVER "GET $url?$updmsg $httphdrs"; my %resp = (); while (my $line = <SERVER>) { $line = '' if ! defined $line; chomp($line); #print "$line\n"; if ($line =~ /^<meta name=\"(.*)\" content=\"(.*)\">$/) { $resp{$1} = $2; } } close SERVER; $response = $resp{'retc'} if defined $resp{'retc'}; if (defined $resp{'addr'}) { $ip = $resp{'addr'}; $receivedip = 1; } } # got a response? if ($response eq '') { print "Server did not respond to login attempt for $username.$domain\n"; return; } # check response if ($response eq '0') { if ($serveraction eq '2' and !$receivedip) { print "Server did not send IP address for $username.$domain\n"; } else { if ($cachefile) { if (!open(CACHE, ">$cachefile")) { print "Could not write cache file $cachefile: $!\n"; } else { print CACHE "$ip;$timenow\n"; close(CACHE); # address changed? $addrchange = 1 if $cacheip ne $ip; # good address (was not tested if past max time)) $chkaddr{$ip} = 1; } print "Update to address $ip from $cacheip successful for $username.$domain\n"; } else { print "Update to address $ip successful for $username.$domain\n"; } } } elsif ($response eq '1') { print "Invalid login attempt for $username.$domain\n"; } elsif ($response eq '2') { if ($cachefile) { if (!open(CACHE, ">$cachefile")) { print "Could not write cache file $cachefile: $!\n"; } else { print CACHE "0.0.0.0;$timenow\n"; close(CACHE); # address changed? $addrchange = 1 if $cacheip ne '0.0.0.0'; } } print "Offline request successful for $username.$domain\n"; } else { print "Server sent invalid response to login attempt for $username.$domain\n"; }}# check whether an address is valid# - uses address from query command if available and compares it# to the cached address, otherwise:# - sends random data to the cached address# - if it receives it back the address is goodsub checkaddress { # get parameter my $testip = shift; return '' if ! defined $testip; # trust $testip if ($testip =~ /(.*)/) { $testip = $1; } # already checked this address? return $chkaddr{$testip} if defined $chkaddr{$testip}; # assume bad address $chkaddr{$testip} = ''; # have address from query? if ($queryaddress) { # address the same? if ($testip ne $queryaddress) { print "Address returned by \"-q\" does not match cached address\n"; return ''; } # good address $chkaddr{$testip} = 1; return 1; } # generate a test value my $testdata = randomsalt(); # print a trace to STDERR? my $trace = ''; #$trace = 1; # bind socket for receive socket(RECEIVE, PF_INET, SOCK_DGRAM, getprotobyname('udp')) || die "socket for RECEIVE failed in checkaddress: $!\n"; setsockopt(RECEIVE, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt failed in checkaddress: $!\n"; bind(RECEIVE, sockaddr_in($recvport, INADDR_ANY)) || die "bind failed in checkaddress: $!\n"; # random port being used to receive? (no gateway?) ($sendport) = sockaddr_in(getsockname(RECEIVE)) if $recvport eq 0; # send packet socket(SEND, PF_INET, SOCK_DGRAM, getprotobyname('udp')) || die "socket for SEND failed in checkaddress: $!\n"; if (! send(SEND, $testdata, 0, sockaddr_in($sendport, inet_aton($testip)))) { close SEND; close RECEIVE; # not a good address print "Address validation failed for $testip - send failed: $!\n"; return ''; } print STDERR "sent data: $testdata\n" if $trace; close SEND; # wait for packet, with a timeout my $sin = ''; vec($sin, fileno(RECEIVE), 1) = 1; if (! select($sin, undef, undef, $opt_w)) { print STDERR "select failed\n" if $trace; close RECEIVE; # not a good address print "Address validation failed for $testip - UDP packet timed out\n"; return ''; } # receive it print STDERR "select succeeded\n" if $trace; recv(RECEIVE, my $check, 20, 0) || die "receive failed in checkaddress: $!\n"; close RECEIVE; print STDERR "received data: $check\n" if $trace; # data matches? if ($check ne $testdata) { print "Address validation failed for $testip - data not matched\n"; return ''; } # good address $chkaddr{$testip} = 1; return 1;}# call query command to get addresssub callquery { # flush before command select(STDERR); $| = 1; select(STDOUT); $| = 1; # call the command $queryaddress = `$opt_q`; my $retcode = $?; $retcode = $retcode >> 8; # command succeeded? if (! defined $queryaddress) { print "Query command failed - no ouput retrieved\n"; exit 1; } elsif ($retcode != 0) { print "Query command returned non-zero status: $retcode\n"; exit 1; } chomp($queryaddress); if (!$queryaddress) { print "Query command returned empty address\n"; exit 1; } print "Query command returned address $queryaddress\n";}# make 10 character random stringsub randomsalt { my @chars = ( 'A' .. 'Z', 'a' .. 'z', 0 .. 9); my $str = ''; for (my $charcount = 0; $charcount < 10; $charcount++) { $str .= $chars[ rand @chars ]; } return $str;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -