From owner-freebsd-ports-bugs@FreeBSD.ORG Tue May 13 11:50:00 2014 Return-Path: Delivered-To: freebsd-ports-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id BA5655E9 for ; Tue, 13 May 2014 11:50:00 +0000 (UTC) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 971112D62 for ; Tue, 13 May 2014 11:50:00 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.8/8.14.8) with ESMTP id s4DBo02m071720 for ; Tue, 13 May 2014 11:50:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.8/8.14.8/Submit) id s4DBo0ZU071719; Tue, 13 May 2014 11:50:00 GMT (envelope-from gnats) Resent-Date: Tue, 13 May 2014 11:50:00 GMT Resent-Message-Id: <201405131150.s4DBo0ZU071719@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Pavel Timofeev Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 546855CE for ; Tue, 13 May 2014 11:49:09 +0000 (UTC) Received: from cgiserv.freebsd.org (cgiserv.freebsd.org [IPv6:2001:1900:2254:206a::50:4]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 41F222D55 for ; Tue, 13 May 2014 11:49:09 +0000 (UTC) Received: from cgiserv.freebsd.org ([127.0.1.6]) by cgiserv.freebsd.org (8.14.8/8.14.8) with ESMTP id s4DBn9WA039719 for ; Tue, 13 May 2014 11:49:09 GMT (envelope-from nobody@cgiserv.freebsd.org) Received: (from nobody@localhost) by cgiserv.freebsd.org (8.14.8/8.14.8/Submit) id s4DBn9sr039716; Tue, 13 May 2014 11:49:09 GMT (envelope-from nobody) Message-Id: <201405131149.s4DBn9sr039716@cgiserv.freebsd.org> Date: Tue, 13 May 2014 11:49:09 GMT From: Pavel Timofeev To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Subject: ports/189762: security/tinyca can't open saved CA X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 May 2014 11:50:00 -0000 >Number: 189762 >Category: ports >Synopsis: security/tinyca can't open saved CA >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue May 13 11:50:00 UTC 2014 >Closed-Date: >Last-Modified: >Originator: Pavel Timofeev >Release: FreeBSD 10.0-RELEASE amd64 >Organization: OCS >Environment: >Description: After new CA creation security/tinyca can't open saved CA. It says *** Day '' out of range 1..31 at /usr/share/tinyca/OpenSSL.pm line 1050 >How-To-Repeat: >Fix: I googled and found that debian folks had same problem and fixed it. I took it. Here it is. Patch attached with submission follows: --- lib/OpenSSL.pm.orig +++ lib/OpenSSL.pm @@ -22,6 +22,7 @@ use POSIX; use IPC::Open3; +use IO::Select; use Time::Local; sub new { @@ -41,7 +42,7 @@ close(TEST); # set version (format: e.g. 0.9.7 or 0.9.7a) - if($v =~ /\b(0\.9\.[678][a-z]?)\b/) { + if($v =~ /\b(0\.9\.[6-9][a-z]?)\b/ || $v =~ /\b(1\.0\.[01][a-z]?)\b/) { $self->{'version'} = $1; } @@ -817,7 +818,7 @@ my $self = shift; my $opts = { @_ }; - my ($tmp, $ext, $ret, $file, $pid, $cmd); + my ($tmp, $ext, $ret, $file, $pid, $cmd, $cmdout, $cmderr); $file = HELPERS::mktmp($self->{'tmp'}."/data"); $cmd = "$self->{'bin'} $opts->{'cmd'}"; @@ -830,16 +831,7 @@ $cmd .= " -outform $opts->{'outform'}"; } - my($rdfh, $wtfh); - $ext = "$cmd\n\n"; - $pid = open3($wtfh, $rdfh, $rdfh, $cmd); - print $wtfh "$opts->{'data'}\n"; - while(<$rdfh>){ - $ext .= $_; - # print STDERR "DEBUG: cmd ret: $_"; - }; - waitpid($pid, 0); - $ret = $?>>8; + ($ret, $tmp, $ext) = _run_with_fixed_input($cmd, $opts->{'data'}); if($self->{'broken'}) { if(($ret != 0 && $opts->{'cmd'} ne 'crl') || @@ -859,14 +851,15 @@ } } - open(IN, $file) || do { - my $t = sprintf(_("Can't open file %s: %s"), $file, $!); - GUI::HELPERS::print_warning($t); - return; - }; - $tmp .= $_ while(); - close(IN); - + if (-s $file) { # If the file is empty, the payload is in $tmp (via STDOUT of the called process). + open(IN, $file) || do { + my $t = sprintf(_("Can't open file %s: %s"), $file, $!); + GUI::HELPERS::print_warning($t); + return; + }; + $tmp .= $_ while(); + close(IN); + } unlink($file); return($ret, $tmp, $ext); @@ -1076,4 +1069,72 @@ } } + +=over + +=item _run_with_fixed_input($cmd, $input) + +This function runs C<$cmd> and writes the C<$input> to STDIN of the +new process (all at once). + +While the command runs, all of its output to STDOUT and STDERR is +collected. + +After the command terminates (closes both STDOUT and STDIN) the +function returns the command's return value as well as everything it +wrote to its STDOUT and STDERR in a list. + +=back + +=cut + +sub _run_with_fixed_input { + my $cmd = shift; + my $input = shift; + + my ($wtfh, $rdfh, $erfh, $pid, $sel, $ret, $stdout, $stderr); + $erfh = Symbol::gensym; # Must not be false, otherwise it is lumped together with rdfh + + # Run the command + $pid = open3($wtfh, $rdfh, $erfh, $cmd); + print $wtfh $input, "\n"; + + $stdout = ''; + $stderr = ''; + $sel = new IO::Select($rdfh, $erfh); + while (my @fhs = $sel->can_read()) { + foreach my $fh (@fhs) { + if ($fh == $rdfh) { # STDOUT + my $bytes_read = sysread($fh, my $buf='', 1024); + if ($bytes_read == -1) { + warn("Error reading from child's STDOUT: $!\n"); + $sel->remove($fh); + } elsif ($bytes_read == 0) { + # print("Child's STDOUT closed.\n"); + $sel->remove($fh); + } else { + $stdout .= $buf; + } + } + elsif ($fh == $erfh) { # STDERR + my $bytes_read = sysread($fh, my $buf='', 1024); + if ($bytes_read == -1) { + warn("Error reading from child's STDERR: $!\n"); + $sel->remove($fh); + } elsif ($bytes_read == 0) { + # print("Child's STDERR closed.\n"); + $sel->remove($fh); + } else { + $stderr .= $buf; + } + } + } + } + + waitpid($pid, 0); + $ret = $?>>8; + + return ($ret, $stdout, $stderr) + } + 1 >Release-Note: >Audit-Trail: >Unformatted: