Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian....@packages.debian.org
Usertags: pu

Paul Wise found out that duck rund untrusted code from the current directory as
well as the ./lib and ./lib/checks directory. The attached patch fixes this
issue.



-- System Information:
Debian Release: 8.4
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.3.0-0.bpo.1-amd64 (SMP w/4 CPU cores)
Locale: LANG=de_AT.utf8, LC_CTYPE=de_AT.utf8 (charmap=UTF-8)
diff -Nru duck-0.7/DUCK.pm duck-0.7+deb8u1/DUCK.pm
--- duck-0.7/DUCK.pm	1970-01-01 01:00:00.000000000 +0100
+++ duck-0.7+deb8u1/DUCK.pm	2016-07-04 17:38:18.000000000 +0200
@@ -0,0 +1,597 @@
+
+# Copyright (C) 2014 Simon Kainz <si...@familiekainz.at>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# he Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# On Debian GNU/Linux systems, the complete text of the GNU General
+# Public License can be found in `/usr/share/common-licenses/GPL-2'.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, you can find it on the World Wide
+# Web at https://www.gnu.org/copyleft/gpl.html, or write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+
+
+use strict;
+use warnings;
+
+
+package DUCK;
+my $VERSION ='0.7';
+my $COPYRIGHT_YEAR ='2014';
+
+
+use String::Similarity;
+use File::Which;
+use WWW::Curl::Easy;
+use strict;
+use IPC::Open3;
+use IO::Select;
+use Net::DNS;
+use Mail::Address;
+use Data::Dumper;
+
+my $callbacks;
+
+my $self;
+my $helpers={
+    svn =>0,
+    bzr =>0,
+    git =>0,
+    darcs =>1, # This works always as it uses WWW::Curl::Easy
+    hg => 0,
+    browser =>1 # This works always as we use WWW::Curl::Easy;
+};
+
+
+my $cli_options;
+
+my $tools=
+{
+    git => {
+	cmd => 'git',
+	args => ['ls-remote','%URL%']
+    },
+	    
+    hg =>{
+		cmd => 'hg',
+		args => ['id','%URL%']
+	},
+
+    bzr => {
+		cmd => 'bzr',
+		args => ['-Ossl.cert_reqs=none','log','%URL%']
+    },
+
+    svn => {
+	cmd => 'svn',
+	args => ['--non-interactive','--trust-server-cert','info','%URL%']
+}
+	    
+	     
+};
+
+sub version
+{
+    return $VERSION;
+}
+
+sub copyright_year
+{
+    return $COPYRIGHT_YEAR;
+}
+
+sub new {
+    my $class = shift;
+     $self = {};
+     bless $self, $class;
+    $self->__find_helpers();
+
+
+    foreach (keys %$tools)
+    {
+	$tools->{$_}->{'args_count'}=scalar @{$tools->{$_}->{'args'}};
+    }
+    return $self;
+}
+
+sub cb()
+{
+    $callbacks=
+    {
+	
+	"Vcs-Browser" =>\&browser,
+	"Vcs-Darcs" =>\&darcs,
+	"Vcs-Git" =>\&git,
+	"Vcs-Hg" =>\&hg,
+	"Vcs-Svn" =>\&svn,
+        "Vcs-Bzr" =>\&bzr,
+	"Homepage" => \&browser,
+	"URL" => \&browser,
+	"Email" => \&email,
+	"Maintainer" => \&maintainer,
+	"Uploaders" => \&uploaders,
+	"Try-HTTPS" => \&try_https,
+        "SVN" => \&svn
+	    
+    };
+    
+    return $callbacks;
+}
+
+sub setOptions()
+{
+    shift;
+    my ($ke,$va)=@_;
+    $cli_options->{$ke}=$va;
+}
+
+sub __find_helpers()
+{
+
+    $helpers->{git}=1 unless !defined (which('git'));
+    $helpers->{svn}=1 unless !defined (which('svn'));
+    $helpers->{hg}=1 unless !defined (which('hg'));
+    $helpers->{bzr}=1 unless !defined (which('bzr'));
+}
+
+sub getHelpers()
+{ return $helpers; }
+
+sub git()
+{
+    my ($url)=@_;
+
+    my @urlparts=split(/\s+/,$url);
+    
+    if ($tools->{'git'}->{'args_count'})
+    {
+    splice(@{$tools->{'git'}->{'args'}},$tools->{'git'}->{'args_count'});
+    }
+
+
+    if ($urlparts[1])
+    {
+	if ($urlparts[1] eq "-b" && $urlparts[2])
+	{
+	    push(@{$tools->{'git'}->{'args'}},'-b '.$urlparts[2]);
+	}
+    }
+    return __run_helper('git',$urlparts[0]);
+}
+
+sub bzr()
+{
+    my ($url)=@_;
+    return __run_helper('bzr',$url);
+}
+
+
+sub hg()
+{
+    my ($url)=@_;
+    return __run_helper('hg',$url);
+}
+
+sub svn()
+{
+    my ($url)=@_;
+	$ENV{SVN_SSH}='ssh -o BatchMode=yes';
+    return __run_helper('svn',$url);
+}
+
+sub browser()
+{
+
+    my $enforce=1;
+
+   my ($url)=@_;
+    
+    $url =~ s/\.*$//g;
+
+    if (! ( $cli_options->{'no-https'}))
+	{
+	    $cli_options->{'no-https'}=1;
+	}
+
+    if ( ($cli_options->{'no-https'}==0) && (!($url =~ m/https:\/\//i )) )
+    {
+	return try_https($url);
+    }
+    else
+    {
+	
+	
+    return __run_browser($url);
+    }
+}
+
+
+
+
+sub try_https()
+{
+    my $similarity_th=0.9;
+    my ($url)=@_;
+    $url =~ s/\.*$//g;
+
+    my $res;
+
+    my $erghttp= __run_browser($url);
+
+    if ($erghttp->{'retval'} >0 ) {return $erghttp;}
+    my $secure_url= $url; 
+    $secure_url=~ s/http:/https:/g;
+
+
+    my $erghttps= __run_browser($secure_url);
+    
+    if ($erghttps->{'retval'} >0 )
+    {
+	# error with https, so do not suggest switching to https, report only http check results
+	return $erghttp;
+    }
+
+    # otherwise check similarity, and report if pages are (quite) the same 
+
+    if ($erghttps->{'retval'} == 0)
+    {
+	# https worked, now try to find out if pages match
+
+	my $similarity= similarity $erghttp->{'body'}, $erghttps->{'body'};
+
+
+	if ($similarity > $similarity_th)
+	{
+	    $res->{'retval'}=2;
+	    $res->{'response'}="The web page at $url works, but is also available via $secure_url, please consider switching to HTTPS urls.";
+	    return $res;
+	
+	}
+	
+    } else
+    {
+	# report nothing
+	$res->{'retval'}=0;
+	return $res;
+       
+    }
+	
+
+
+
+
+    $res->{'retval'}=0;
+    $res->{'response'}="lolz";
+    $res->{'url'}=$url;
+    return $res;
+
+}
+
+sub darcs()
+{
+    my ($url)=@_;
+    my $darcsurltemp=$url;
+    $darcsurltemp =~ s/\/$//;
+    $darcsurltemp.='/_darcs/hashed_inventory';
+    return __run_browser($darcsurltemp);
+}
+
+
+
+
+sub uploaders()
+{
+    my ($line_uploaders)=@_;
+    $line_uploaders =~ s/\n/ /g;
+    my @emails;
+
+    if ($line_uploaders =~ /@/)
+    {
+	@emails=Mail::Address->parse($line_uploaders);
+    }
+    my $res;
+#    print Dumper @emails;
+    foreach my $email(@emails)
+    {
+	my $es=$email->address();
+	my $r=check_domain($es);
+    
+	if ($r->{retval}>0)
+	{
+	    if (!$res->{retval})
+	    {
+		$res=$r;
+	    } else
+	    {
+		$res->{retval}=$r->{retval};
+		$res->{response}.="\n".$r->{response};
+		$res->{url}="foo";
+	    }
+	    
+	}
+	
+    }
+    
+    if (!$res->{retval})
+    {
+	$res->{'retval'}=0;
+	$res->{'response'}="";
+	$res->{'url'}=$line_uploaders;
+    }
+    return $res;
+
+}
+
+sub maintainer()
+{
+    my ($email)=@_;
+     return check_domain($email);
+}
+
+
+
+sub email()
+{
+    my ($email) =@_;
+    return check_domain($email);
+}
+
+
+sub __run_browser {
+
+
+    my $certainty;
+    my @SSLs=(CURL_SSLVERSION_DEFAULT,
+      CURL_SSLVERSION_TLSv1,
+      CURL_SSLVERSION_SSLv2,
+      CURL_SSLVERSION_SSLv3,
+      CURL_SSLVERSION_TLSv1_0,
+      CURL_SSLVERSION_TLSv1_1,
+      CURL_SSLVERSION_TLSv1_2);
+
+    my ($url,$return_ref)=@_;
+    
+    #check if URL is mailto: link
+    
+    if ($url =~/mailto:\s*.+@.+/)
+    {
+    return check_domain($url);
+    }
+    
+    my $curl = WWW::Curl::Easy->new;
+    
+    my @website_moved_regexs=('new homepage','update your links','we have moved','buy this domain','domain .* for sale', 'order this domain');
+  
+
+    my @website_moved_whitelist=('anonscm.debian.org.*duck.git');
+    
+    $curl->setopt(CURLOPT_HEADER,0);
+    $curl->setopt(CURLOPT_SSL_VERIFYPEER,0);
+    $curl->setopt(CURLOPT_SSL_VERIFYHOST,0);
+    $curl->setopt(CURLOPT_CERTINFO,0);
+    $curl->setopt(CURLOPT_FOLLOWLOCATION,1);
+    $curl->setopt(CURLOPT_SSL_CIPHER_LIST,'ALL');
+    $curl->setopt(CURLOPT_MAXREDIRS,10);     
+    $curl->setopt(CURLOPT_TIMEOUT,60);
+    $curl->setopt(CURLOPT_USERAGENT,'Mozilla/5.0 (X11; Linux x86_64; rv:10.0.4) Gecko/20100101 Firefox/10.0.4 Iceweasel/10.0.4');
+    $curl->setopt(CURLOPT_URL, $url);
+
+    my $response_body;
+    my $response_code;
+    my $retcode;
+    my $response;
+
+    foreach my $s (@SSLs)
+    {
+    $curl->setopt(CURLOPT_WRITEDATA,\$response_body);
+    $curl->setopt(CURLOPT_SSLVERSION,$s);
+    # Starts the actual request
+    $retcode = $curl->perform;
+    $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
+    $response=$curl->strerror($retcode)." ".$curl->errbuf."\n";
+
+    if ($retcode == 35) { next;}
+    if ($retcode == 56) {next;}
+    last;
+    }
+
+    # Looking at the results...
+    my $status=0;
+    my $disp=0;
+
+ 
+    if ($retcode == 0) # no curl error, but maybe a http error
+    {
+	#default to error
+	$status=1;
+	$disp=1;
+
+	#handle ok cases, 200 is ok for sure
+	if ($response_code ==200 )
+	{
+	    $status=0;
+	    $disp=0;
+	}
+
+
+	if ($response_code ==226 )
+	{
+	    $status=0;
+	    $disp=0;
+	}
+
+	if ($response_code ==227 )
+	{
+	    $status=0;
+	    $disp=0;
+	}
+
+	if ($response_code ==302 ) #temporary redirect is ok
+	{
+	    $status=0;
+	    $disp=0;
+	}
+
+	if ($response_code ==403)
+	{
+	    ## special case for sourceforge.net sites
+	    ## sourceforge seems to always return correct pages wit http code 40.
+	    
+	    if ( $url =~ m/(sourceforge|sf).net/i)
+	    {
+		# print "Sourceforge site, so hande special!!";
+		$status=0;
+		$disp=0;
+	    }
+
+
+	}
+	my $whitelisted=0;
+
+	foreach my $whitelist_url (@website_moved_whitelist)
+	{
+	    if ( $url =~ m/$whitelist_url/i)
+	
+	    {$whitelisted=1;}
+
+	}
+	if ($whitelisted == 0)
+	  {  
+	      foreach my $regex (@website_moved_regexs)
+	      {
+		  #   print "$regex\n";
+		  if ($response_body =~ m/$regex/i )
+		  {
+		      $disp=2;
+		      $response.="Website seems to be outdated, is probably a parked domain or for sale. Please update your links!\nMatching regular expression: m/".$regex."/i";
+		      $certainty="wild-guess";
+		      last;
+		  }
+	      }
+	  }
+	
+    }
+    else {  # we have a curl error, so we show this entry for sure
+	$status=1;
+	$disp=1;
+    }
+
+
+    my $ret;
+    $ret->{'retval'}=$disp;
+    $ret->{'response'}="Curl:$retcode HTTP:$response_code $response";
+    $ret->{'url'}=$url;
+    $ret->{'body'}=$response_body;
+    $ret->{'certainty'}=$certainty;
+    return $ret; 
+}
+
+
+
+sub __run_helper {
+    
+    my ($tool,$url)=@_;
+   return undef unless $helpers->{$tool} == 1;
+   return undef unless defined $tools->{$tool};
+
+   my @args=@{$tools->{$tool}->{'args'}};
+
+   for(@args){s/\%URL\%/$url/g}
+
+    my $pid;
+    my $command;
+    my $timeout;
+
+
+    if ($cli_options->{'timeout'})
+    {
+
+	my $timeout_value=60;
+	if ( ( $cli_options->{'timeout_seconds'} ))
+	    {
+		$timeout_value=$cli_options->{'timeout_seconds'};
+		$timeout_value =~ s/[^0-9]//;
+	    }
+	unshift @args,$tools->{$tool}->{'cmd'};
+	unshift @args,$timeout_value."s";
+	$command="/usr/bin/timeout";
+	$pid=open3(\*WRITE,\*READ,0,$command,@args);
+    
+    }
+    else
+    {
+    $pid=open3(\*WRITE,\*READ,0,$tools->{$tool}->{'cmd'},@args);
+
+    }
+
+   my @results = <READ>;
+   waitpid ($pid,0);
+   close READ;
+
+   my $retval=$?;
+   my $ret;
+   $ret->{'retval'}=$retval;
+   $ret->{'response'}=join("",@results);
+   $ret->{'url'}=$url;
+   return $ret;
+}
+
+sub check_domain($)
+		 {
+
+
+    
+		     my $res = Net::DNS::Resolver->new;
+		     my ($email) = @_;
+		     my @emails=Mail::Address->parse($email);
+		     $email=$emails[0]->address();
+#		     $email=$email->address();
+		     my @domain = ( $email =~ m/^[^@]*@([^?^&^>]*).*/);
+
+		     my @queries=('MX','A','AAAA');
+		     my @results;
+		     my $iserror=1;
+		     foreach my $query (@queries)
+		     {
+			 my $q=$res->query($domain[0],$query);
+			 
+			 if ($q)
+			 {
+			     my @answers=$q->answer;
+			     my $mxcount=scalar @answers;
+			     push (@results,$mxcount." ".$query." entries found.");
+			     $iserror=0;
+			     last;
+			 } else
+			 {
+			     push (@results,"$email: No ".$query." entry found.");
+			 }
+			 
+		     }
+		     
+		     
+		     my $ret;
+		     $ret->{'retval'}=$iserror;
+		     $ret->{'response'}=join("\n",@results);
+		     $ret->{'url'}=$email;
+		     return $ret;
+		     
+		     
+		 }
+
+
+
+
+
+1;
diff -Nru duck-0.7/debian/changelog duck-0.7+deb8u1/debian/changelog
--- duck-0.7/debian/changelog	2014-10-23 08:38:01.000000000 +0200
+++ duck-0.7+deb8u1/debian/changelog	2016-07-04 17:51:16.000000000 +0200
@@ -1,3 +1,11 @@
+duck (0.7+deb8u1) jessie-security; urgency=high
+
+  * Fix CVE-2016-1239: Load code from untrusted local dir
+
+  * Update Maintainer email to my Debian email address.
+
+ -- Simon Kainz <ska...@debian.org>  Mon, 04 Jul 2016 17:50:54 +0200
+
 duck (0.7) unstable; urgency=medium
 
   * Change certainty level (certain -> wild-guess) and
diff -Nru duck-0.7/debian/control duck-0.7+deb8u1/debian/control
--- duck-0.7/debian/control	2014-10-23 08:44:59.000000000 +0200
+++ duck-0.7+deb8u1/debian/control	2016-07-04 17:48:49.000000000 +0200
@@ -1,7 +1,7 @@
 Source: duck
 Section: devel
 Priority: optional
-Maintainer: Simon Kainz <si...@familiekainz.at>
+Maintainer: Simon Kainz <ska...@debian.org>
 Build-Depends: debhelper (>= 9),
                libfile-which-perl,
                libmailtools-perl,
diff -Nru duck-0.7/debian/duck.install duck-0.7+deb8u1/debian/duck.install
--- duck-0.7/debian/duck.install	2014-03-25 22:12:49.000000000 +0100
+++ duck-0.7+deb8u1/debian/duck.install	2016-07-04 17:30:23.000000000 +0200
@@ -1,2 +1,3 @@
 duck	usr/bin
-lib	usr/share/duck
\ No newline at end of file
+lib	usr/share/duck
+DUCK.pm /usr/share/duck
diff -Nru duck-0.7/debian/rules duck-0.7+deb8u1/debian/rules
--- duck-0.7/debian/rules	2014-03-25 22:12:49.000000000 +0100
+++ duck-0.7+deb8u1/debian/rules	2016-07-04 17:31:02.000000000 +0200
@@ -7,4 +7,4 @@
 	dh $@
 
 override_dh_auto_test:
-	$(PERL) -Mlib=$(LIBDIR) -wc duck
\ No newline at end of file
+	$(PERL) -wc duck
\ No newline at end of file
diff -Nru duck-0.7/duck duck-0.7+deb8u1/duck
--- duck-0.7/duck	2014-10-23 08:17:58.000000000 +0200
+++ duck-0.7+deb8u1/duck	2016-07-04 17:32:29.000000000 +0200
@@ -24,15 +24,15 @@
 
 use strict;
 
+use lib '/usr/share/duck';
 use lib '/usr/share/duck/lib';
-use lib './lib';
 
 use DUCK;
 use Getopt::Std;
 use Getopt::Long qw(:config pass_through );
 use Data::Dumper;
 use File::Basename;
-require lib;
+#require lib;
 
 sub HELP_MESSAGE();
 sub display_result($;$;$);
@@ -40,10 +40,10 @@
 
 my $checksdir='/usr/share/duck/lib/checks';
 
- if ( -d "./lib/checks" )
-{
-    $checksdir='./lib/checks';
-}
+# if ( -d "./lib/checks" )
+#{
+#    $checksdir='./lib/checks';
+#}
 
 
 my $try_https=0;
diff -Nru duck-0.7/duck.1 duck-0.7+deb8u1/duck.1
--- duck-0.7/duck.1	2014-10-23 09:18:59.000000000 +0200
+++ duck-0.7+deb8u1/duck.1	2016-07-04 17:33:11.000000000 +0200
@@ -62,7 +62,8 @@
 dry run. Don't run any checks, just show entries to be checked.
 .TP
 \fB\--modules-dir=\fRDIRECTORY
-specify modules directory. Mostly useful for developing new checks.
+specify modules directory. Mostly useful for developing new checks. If this parameter is specified, only modules defined in this
+directory are used. You have to copy all \fI*.pm\fR files from \fI/usr/share/duck/lib/checks\fR to the directory specified.
 .TP
 \fB\--no-color\fR
 do not colorize output. See also the \fIDUCK_NOCOLOR\fR environment variable.
diff -Nru duck-0.7/lib/DUCK.pm duck-0.7+deb8u1/lib/DUCK.pm
--- duck-0.7/lib/DUCK.pm	2014-10-23 08:50:08.000000000 +0200
+++ duck-0.7+deb8u1/lib/DUCK.pm	1970-01-01 01:00:00.000000000 +0100
@@ -1,598 +0,0 @@
-
-# Copyright (C) 2014 Simon Kainz <si...@familiekainz.at>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# he Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# On Debian GNU/Linux systems, the complete text of the GNU General
-# Public License can be found in `/usr/share/common-licenses/GPL-2'.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, you can find it on the World Wide
-# Web at https://www.gnu.org/copyleft/gpl.html, or write to the Free
-# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
-# MA 02110-1301, USA.
-
-
-
-use strict;
-use warnings;
-use lib '.';
-
-
-package DUCK;
-my $VERSION ='0.7';
-my $COPYRIGHT_YEAR ='2014';
-
-
-use String::Similarity;
-use File::Which;
-use WWW::Curl::Easy;
-use strict;
-use IPC::Open3;
-use IO::Select;
-use Net::DNS;
-use Mail::Address;
-use Data::Dumper;
-
-my $callbacks;
-
-my $self;
-my $helpers={
-    svn =>0,
-    bzr =>0,
-    git =>0,
-    darcs =>1, # This works always as it uses WWW::Curl::Easy
-    hg => 0,
-    browser =>1 # This works always as we use WWW::Curl::Easy;
-};
-
-
-my $cli_options;
-
-my $tools=
-{
-    git => {
-	cmd => 'git',
-	args => ['ls-remote','%URL%']
-    },
-	    
-    hg =>{
-		cmd => 'hg',
-		args => ['id','%URL%']
-	},
-
-    bzr => {
-		cmd => 'bzr',
-		args => ['-Ossl.cert_reqs=none','log','%URL%']
-    },
-
-    svn => {
-	cmd => 'svn',
-	args => ['--non-interactive','--trust-server-cert','info','%URL%']
-}
-	    
-	     
-};
-
-sub version
-{
-    return $VERSION;
-}
-
-sub copyright_year
-{
-    return $COPYRIGHT_YEAR;
-}
-
-sub new {
-    my $class = shift;
-     $self = {};
-     bless $self, $class;
-    $self->__find_helpers();
-
-
-    foreach (keys %$tools)
-    {
-	$tools->{$_}->{'args_count'}=scalar @{$tools->{$_}->{'args'}};
-    }
-    return $self;
-}
-
-sub cb()
-{
-    $callbacks=
-    {
-	
-	"Vcs-Browser" =>\&browser,
-	"Vcs-Darcs" =>\&darcs,
-	"Vcs-Git" =>\&git,
-	"Vcs-Hg" =>\&hg,
-	"Vcs-Svn" =>\&svn,
-        "Vcs-Bzr" =>\&bzr,
-	"Homepage" => \&browser,
-	"URL" => \&browser,
-	"Email" => \&email,
-	"Maintainer" => \&maintainer,
-	"Uploaders" => \&uploaders,
-	"Try-HTTPS" => \&try_https,
-        "SVN" => \&svn
-	    
-    };
-    
-    return $callbacks;
-}
-
-sub setOptions()
-{
-    shift;
-    my ($ke,$va)=@_;
-    $cli_options->{$ke}=$va;
-}
-
-sub __find_helpers()
-{
-
-    $helpers->{git}=1 unless !defined (which('git'));
-    $helpers->{svn}=1 unless !defined (which('svn'));
-    $helpers->{hg}=1 unless !defined (which('hg'));
-    $helpers->{bzr}=1 unless !defined (which('bzr'));
-}
-
-sub getHelpers()
-{ return $helpers; }
-
-sub git()
-{
-    my ($url)=@_;
-
-    my @urlparts=split(/\s+/,$url);
-    
-    if ($tools->{'git'}->{'args_count'})
-    {
-    splice(@{$tools->{'git'}->{'args'}},$tools->{'git'}->{'args_count'});
-    }
-
-
-    if ($urlparts[1])
-    {
-	if ($urlparts[1] eq "-b" && $urlparts[2])
-	{
-	    push(@{$tools->{'git'}->{'args'}},'-b '.$urlparts[2]);
-	}
-    }
-    return __run_helper('git',$urlparts[0]);
-}
-
-sub bzr()
-{
-    my ($url)=@_;
-    return __run_helper('bzr',$url);
-}
-
-
-sub hg()
-{
-    my ($url)=@_;
-    return __run_helper('hg',$url);
-}
-
-sub svn()
-{
-    my ($url)=@_;
-	$ENV{SVN_SSH}='ssh -o BatchMode=yes';
-    return __run_helper('svn',$url);
-}
-
-sub browser()
-{
-
-    my $enforce=1;
-
-   my ($url)=@_;
-    
-    $url =~ s/\.*$//g;
-
-    if (! ( $cli_options->{'no-https'}))
-	{
-	    $cli_options->{'no-https'}=1;
-	}
-
-    if ( ($cli_options->{'no-https'}==0) && (!($url =~ m/https:\/\//i )) )
-    {
-	return try_https($url);
-    }
-    else
-    {
-	
-	
-    return __run_browser($url);
-    }
-}
-
-
-
-
-sub try_https()
-{
-    my $similarity_th=0.9;
-    my ($url)=@_;
-    $url =~ s/\.*$//g;
-
-    my $res;
-
-    my $erghttp= __run_browser($url);
-
-    if ($erghttp->{'retval'} >0 ) {return $erghttp;}
-    my $secure_url= $url; 
-    $secure_url=~ s/http:/https:/g;
-
-
-    my $erghttps= __run_browser($secure_url);
-    
-    if ($erghttps->{'retval'} >0 )
-    {
-	# error with https, so do not suggest switching to https, report only http check results
-	return $erghttp;
-    }
-
-    # otherwise check similarity, and report if pages are (quite) the same 
-
-    if ($erghttps->{'retval'} == 0)
-    {
-	# https worked, now try to find out if pages match
-
-	my $similarity= similarity $erghttp->{'body'}, $erghttps->{'body'};
-
-
-	if ($similarity > $similarity_th)
-	{
-	    $res->{'retval'}=2;
-	    $res->{'response'}="The web page at $url works, but is also available via $secure_url, please consider switching to HTTPS urls.";
-	    return $res;
-	
-	}
-	
-    } else
-    {
-	# report nothing
-	$res->{'retval'}=0;
-	return $res;
-       
-    }
-	
-
-
-
-
-    $res->{'retval'}=0;
-    $res->{'response'}="lolz";
-    $res->{'url'}=$url;
-    return $res;
-
-}
-
-sub darcs()
-{
-    my ($url)=@_;
-    my $darcsurltemp=$url;
-    $darcsurltemp =~ s/\/$//;
-    $darcsurltemp.='/_darcs/hashed_inventory';
-    return __run_browser($darcsurltemp);
-}
-
-
-
-
-sub uploaders()
-{
-    my ($line_uploaders)=@_;
-    $line_uploaders =~ s/\n/ /g;
-    my @emails;
-
-    if ($line_uploaders =~ /@/)
-    {
-	@emails=Mail::Address->parse($line_uploaders);
-    }
-    my $res;
-#    print Dumper @emails;
-    foreach my $email(@emails)
-    {
-	my $es=$email->address();
-	my $r=check_domain($es);
-    
-	if ($r->{retval}>0)
-	{
-	    if (!$res->{retval})
-	    {
-		$res=$r;
-	    } else
-	    {
-		$res->{retval}=$r->{retval};
-		$res->{response}.="\n".$r->{response};
-		$res->{url}="foo";
-	    }
-	    
-	}
-	
-    }
-    
-    if (!$res->{retval})
-    {
-	$res->{'retval'}=0;
-	$res->{'response'}="";
-	$res->{'url'}=$line_uploaders;
-    }
-    return $res;
-
-}
-
-sub maintainer()
-{
-    my ($email)=@_;
-     return check_domain($email);
-}
-
-
-
-sub email()
-{
-    my ($email) =@_;
-    return check_domain($email);
-}
-
-
-sub __run_browser {
-
-
-    my $certainty;
-    my @SSLs=(CURL_SSLVERSION_DEFAULT,
-      CURL_SSLVERSION_TLSv1,
-      CURL_SSLVERSION_SSLv2,
-      CURL_SSLVERSION_SSLv3,
-      CURL_SSLVERSION_TLSv1_0,
-      CURL_SSLVERSION_TLSv1_1,
-      CURL_SSLVERSION_TLSv1_2);
-
-    my ($url,$return_ref)=@_;
-    
-    #check if URL is mailto: link
-    
-    if ($url =~/mailto:\s*.+@.+/)
-    {
-    return check_domain($url);
-    }
-    
-    my $curl = WWW::Curl::Easy->new;
-    
-    my @website_moved_regexs=('new homepage','update your links','we have moved','buy this domain','domain .* for sale', 'order this domain');
-  
-
-    my @website_moved_whitelist=('anonscm.debian.org.*duck.git');
-    
-    $curl->setopt(CURLOPT_HEADER,0);
-    $curl->setopt(CURLOPT_SSL_VERIFYPEER,0);
-    $curl->setopt(CURLOPT_SSL_VERIFYHOST,0);
-    $curl->setopt(CURLOPT_CERTINFO,0);
-    $curl->setopt(CURLOPT_FOLLOWLOCATION,1);
-    $curl->setopt(CURLOPT_SSL_CIPHER_LIST,'ALL');
-    $curl->setopt(CURLOPT_MAXREDIRS,10);     
-    $curl->setopt(CURLOPT_TIMEOUT,60);
-    $curl->setopt(CURLOPT_USERAGENT,'Mozilla/5.0 (X11; Linux x86_64; rv:10.0.4) Gecko/20100101 Firefox/10.0.4 Iceweasel/10.0.4');
-    $curl->setopt(CURLOPT_URL, $url);
-
-    my $response_body;
-    my $response_code;
-    my $retcode;
-    my $response;
-
-    foreach my $s (@SSLs)
-    {
-    $curl->setopt(CURLOPT_WRITEDATA,\$response_body);
-    $curl->setopt(CURLOPT_SSLVERSION,$s);
-    # Starts the actual request
-    $retcode = $curl->perform;
-    $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
-    $response=$curl->strerror($retcode)." ".$curl->errbuf."\n";
-
-    if ($retcode == 35) { next;}
-    if ($retcode == 56) {next;}
-    last;
-    }
-
-    # Looking at the results...
-    my $status=0;
-    my $disp=0;
-
- 
-    if ($retcode == 0) # no curl error, but maybe a http error
-    {
-	#default to error
-	$status=1;
-	$disp=1;
-
-	#handle ok cases, 200 is ok for sure
-	if ($response_code ==200 )
-	{
-	    $status=0;
-	    $disp=0;
-	}
-
-
-	if ($response_code ==226 )
-	{
-	    $status=0;
-	    $disp=0;
-	}
-
-	if ($response_code ==227 )
-	{
-	    $status=0;
-	    $disp=0;
-	}
-
-	if ($response_code ==302 ) #temporary redirect is ok
-	{
-	    $status=0;
-	    $disp=0;
-	}
-
-	if ($response_code ==403)
-	{
-	    ## special case for sourceforge.net sites
-	    ## sourceforge seems to always return correct pages wit http code 40.
-	    
-	    if ( $url =~ m/(sourceforge|sf).net/i)
-	    {
-		# print "Sourceforge site, so hande special!!";
-		$status=0;
-		$disp=0;
-	    }
-
-
-	}
-	my $whitelisted=0;
-
-	foreach my $whitelist_url (@website_moved_whitelist)
-	{
-	    if ( $url =~ m/$whitelist_url/i)
-	
-	    {$whitelisted=1;}
-
-	}
-	if ($whitelisted == 0)
-	  {  
-	      foreach my $regex (@website_moved_regexs)
-	      {
-		  #   print "$regex\n";
-		  if ($response_body =~ m/$regex/i )
-		  {
-		      $disp=2;
-		      $response.="Website seems to be outdated, is probably a parked domain or for sale. Please update your links!\nMatching regular expression: m/".$regex."/i";
-		      $certainty="wild-guess";
-		      last;
-		  }
-	      }
-	  }
-	
-    }
-    else {  # we have a curl error, so we show this entry for sure
-	$status=1;
-	$disp=1;
-    }
-
-
-    my $ret;
-    $ret->{'retval'}=$disp;
-    $ret->{'response'}="Curl:$retcode HTTP:$response_code $response";
-    $ret->{'url'}=$url;
-    $ret->{'body'}=$response_body;
-    $ret->{'certainty'}=$certainty;
-    return $ret; 
-}
-
-
-
-sub __run_helper {
-    
-    my ($tool,$url)=@_;
-   return undef unless $helpers->{$tool} == 1;
-   return undef unless defined $tools->{$tool};
-
-   my @args=@{$tools->{$tool}->{'args'}};
-
-   for(@args){s/\%URL\%/$url/g}
-
-    my $pid;
-    my $command;
-    my $timeout;
-
-
-    if ($cli_options->{'timeout'})
-    {
-
-	my $timeout_value=60;
-	if ( ( $cli_options->{'timeout_seconds'} ))
-	    {
-		$timeout_value=$cli_options->{'timeout_seconds'};
-		$timeout_value =~ s/[^0-9]//;
-	    }
-	unshift @args,$tools->{$tool}->{'cmd'};
-	unshift @args,$timeout_value."s";
-	$command="/usr/bin/timeout";
-	$pid=open3(\*WRITE,\*READ,0,$command,@args);
-    
-    }
-    else
-    {
-    $pid=open3(\*WRITE,\*READ,0,$tools->{$tool}->{'cmd'},@args);
-
-    }
-
-   my @results = <READ>;
-   waitpid ($pid,0);
-   close READ;
-
-   my $retval=$?;
-   my $ret;
-   $ret->{'retval'}=$retval;
-   $ret->{'response'}=join("",@results);
-   $ret->{'url'}=$url;
-   return $ret;
-}
-
-sub check_domain($)
-		 {
-
-
-    
-		     my $res = Net::DNS::Resolver->new;
-		     my ($email) = @_;
-		     my @emails=Mail::Address->parse($email);
-		     $email=$emails[0]->address();
-#		     $email=$email->address();
-		     my @domain = ( $email =~ m/^[^@]*@([^?^&^>]*).*/);
-
-		     my @queries=('MX','A','AAAA');
-		     my @results;
-		     my $iserror=1;
-		     foreach my $query (@queries)
-		     {
-			 my $q=$res->query($domain[0],$query);
-			 
-			 if ($q)
-			 {
-			     my @answers=$q->answer;
-			     my $mxcount=scalar @answers;
-			     push (@results,$mxcount." ".$query." entries found.");
-			     $iserror=0;
-			     last;
-			 } else
-			 {
-			     push (@results,"$email: No ".$query." entry found.");
-			 }
-			 
-		     }
-		     
-		     
-		     my $ret;
-		     $ret->{'retval'}=$iserror;
-		     $ret->{'response'}=join("\n",@results);
-		     $ret->{'url'}=$email;
-		     return $ret;
-		     
-		     
-		 }
-
-
-
-
-
-1;

Reply via email to