/[pdpsoft]/nl.nikhef.pdp.fetchcrl/tags/fetch-crl-3.0.4-1/OSSL.pm
ViewVC logotype

Contents of /nl.nikhef.pdp.fetchcrl/tags/fetch-crl-3.0.4-1/OSSL.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1777 - (show annotations) (download) (as text)
Sat Jun 12 15:04:48 2010 UTC (11 years, 5 months ago) by davidg
Original Path: trunk/fetchcrl/OSSL.pm
File MIME type: application/x-perl
File size: 7747 byte(s)
Removed auto-unlink from tempfiles, since it leads to race conditions

1 #
2 # @(#)$Id$
3 #
4 #
5 package OSSL;
6 use strict;
7 use POSIX;
8 use File::Temp qw/ tempfile /;
9 use IPC::Open3;
10 use IO::Select;
11 use Time::Local;
12 use vars qw/ $log $cnf $opensslversion /;
13
14 # Syntax:
15 # OSSL->new( [path] );
16 # OSSL->setName( name);
17
18 #
19 sub new {
20 my $obref = {}; bless $obref;
21 my $self = shift;
22 $self = $obref;
23 my $openssl = shift;
24 $self->{"openssl"} = "openssl";
25 $self->{"openssl"} = $::cnf->{_}->{"openssl"} if $::cnf->{_}->{"openssl"};
26 $self->setOpenSSL($openssl) if $openssl;
27 $self->{"version"} = undef;
28 return $self;
29 }
30
31 sub setOpenSSL($$) {
32 my $self = shift or die "Invalid invocation of CRL::setOpenSSL\n";
33 my $openssl = shift;
34 return 0 unless $openssl;
35
36 $openssl =~ /\// and ! -x "$openssl" or
37 $::log->err("OpenSSL binary $openssl is not executable or does not exist")
38 and return 0;
39
40 $::log->verb(4,"Using OpenSSL at $openssl");
41 $self->{"openssl"} = $openssl;
42 $self->{"version"} = undef;
43
44 return 1;
45 }
46
47 sub getVersion($) {
48 my $self = shift or die "Invalid invocation of CRL::getVersion\n";
49 #$self->{"version"} and return $self->{"version"};
50 $opensslversion and return $opensslversion;
51
52 my ($data,$errors) = $self->Exec3(undef,qw/version/);
53 if ( defined $data ) {
54 $data =~ /^OpenSSL\s+([\d\.]+\w)/ or
55 $::log->err("Cannot get OpenSSL version from command: invalid format in $data".($errors?" ($errors)":"")) and
56 return undef;
57
58 $self->{"version"} = $1;
59 $opensslversion = $self->{"version"};
60 return $1;
61 } else {
62 $::log->err("Cannot get OpenSSL version from command: $errors");
63 return undef;
64 }
65 }
66
67 sub Exec3select($$@) {
68 my $self = shift or die "Invalid invocation of CRL::OpenSSL\n";
69 my $datain = shift;
70 my ($dataout, $dataerr) = ("",undef);
71 my $rc = 0;
72 local(*CMD_IN, *CMD_OUT, *CMD_ERR);
73
74 $::log->verb(6,"Executing openssl",@_);
75 my $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $self->{"openssl"}, @_ );
76
77 $SIG{CHLD} = sub {
78 $rc = $? >> 8 if waitpid($pid, 0) > 0
79 };
80 $datain and print CMD_IN $datain;
81 close(CMD_IN);
82 print STDERR "Printed " . length($datain). " bytes of data\n";
83
84 my $selector = IO::Select->new();
85 $selector->add(*CMD_ERR);
86 $selector->add(*CMD_OUT);
87
88 my ($char,$cnt);
89 while ($selector->count) {
90 my @ready = $selector->can_read(1);
91 #my @ready = IO::Select->select($selector,undef,undef,1);
92 foreach my $fh (@ready) {
93 if (fileno($fh) == fileno(CMD_ERR)) {
94 $cnt = sysread CMD_ERR, $char, 1;
95 if ( $cnt ) { $dataerr .= $char; }
96 else { $selector->remove($fh); $dataerr and print STDERR "$dataerr\n";}
97 } else {
98 $cnt = sysread CMD_OUT, $char, 1;
99 if ( $cnt ) { $dataout .= $char; }
100 else { $selector->remove($fh); $dataout and print STDERR "$dataout\n"; }
101 }
102 $selector->remove($fh) if eof($fh);
103 }
104 }
105 close(CMD_OUT);
106 close(CMD_ERR);
107
108 if ( $rc >> 8 ) {
109 $::log->warn("Execute openssl " . $ARGV[0] . " failed: $rc");
110 (my $errmsg = $dataerr) =~ s/\n.*//sgm;
111 $::log->verb(6,"STDERR:",$errmsg);
112 return undef unless wantarray;
113 return (undef,$dataerr);
114 }
115 return $dataout unless wantarray;
116 return ($dataout,$dataerr);
117 }
118
119 sub Exec3pipe($$@) {
120 my $self = shift or die "Invalid invocation of CRL::OpenSSL\n";
121 my $datain = shift;
122 my ($dataout, $dataerr) = ("",undef);
123 my $rc = 0;
124 local(*CMD_IN, *CMD_OUT, *CMD_ERR);
125
126 $::log->verb(6,"Executing openssl",@_);
127
128 my ($tmpfh,$tmpname);
129 $datain and do {
130 ($tmpfh,$tmpname) = tempfile("fetchcrl3.XXXXXX", DIR=>'/tmp');
131 $|=1;
132 print $tmpfh $datain;
133 close $tmpfh;
134 push @_, "-in", $tmpname;
135 select undef,undef,undef,0.01;
136 };
137
138 $|=1;
139
140 my $pid = open3( *CMD_IN, *CMD_OUT, *CMD_ERR, $self->{"openssl"}, @_ );
141
142 # allow delay for child to startup - but will hang on many older platforms
143 select undef,undef,undef,0.15;
144
145 $SIG{CHLD} = sub {
146 $rc = $? >> 8 if waitpid($pid, 0) > 0
147 };
148
149 #close(CMD_IN);
150 CMD_OUT->autoflush;
151 CMD_ERR->autoflush;
152
153 my $selector = IO::Select->new();
154 $selector->add(*CMD_ERR, *CMD_OUT);
155
156 while (my @ready = $selector->can_read(0.01)) {
157 foreach my $fh (@ready) {
158 if (fileno($fh) == fileno(CMD_ERR)) {$dataerr .= scalar <CMD_ERR>}
159 else {$dataout .= scalar <CMD_OUT>}
160 $selector->remove($fh) if eof($fh);
161 }
162 }
163 close(CMD_OUT);
164 close(CMD_ERR);
165 $tmpname and unlink $tmpname;
166
167 if ( $rc >> 8 ) {
168 $::log->warn("Execute openssl " . $ARGV[0] . " failed: $rc");
169 (my $errmsg = $dataerr) =~ s/\n.*//sgm;
170 $::log->verb(6,"STDERR:",$errmsg);
171 return undef unless wantarray;
172 return (undef,$dataerr);
173 }
174 return $dataout unless wantarray;
175 return ($dataout,$dataerr);
176 }
177
178
179 sub Exec3file($$@) {
180 my $self = shift or die "Invalid invocation of CRL::OpenSSL\n";
181 my $datain = shift;
182 my ($dataout, $dataerr) = ("",undef);
183 my $rc = 0;
184 local(*CMD_IN, *CMD_OUT, *CMD_ERR);
185
186 $::log->verb(6,"Executing openssl",@_);
187
188 my ($tmpin,$tmpinname);
189 my ($tmpout,$tmpoutname);
190 my ($tmperr,$tmperrname);
191
192 my $tmpdir = $::cnf->{_}->{exec3tmpdir} || $ENV{"TMPDIR"} || '/tmp';
193
194 $|=1;
195 $datain and do {
196 ($tmpin,$tmpinname) = tempfile("fetchcrl3in.XXXXXX",
197 DIR=>$tmpdir);
198 print $tmpin $datain;
199 close $tmpin;
200 };
201 ($tmpout,$tmpoutname) = tempfile("fetchcrl3out.XXXXXX",
202 DIR=>$tmpdir);
203 ($tmperr,$tmperrname) = tempfile("fetchcrl3out.XXXXXX",
204 DIR=>$tmpdir);
205
206 my $pid = fork();
207
208 defined $pid or
209 $::log->warn("Internal error, fork for openssl failed: $!") and
210 return undef;
211
212 if ( $pid == 0 ) { # I'm a kid
213 close STDIN;
214 if ( $tmpinname ) {
215 open STDIN, "<", $tmpinname or
216 die "Cannot open tempfile $tmpinname again $!\n";
217 } else {
218 open STDIN, "<", "/dev/null" or
219 die "Cannot open /dev/null ??? $!\n";
220 }
221 close STDOUT;
222 if ( $tmpoutname ) {
223 open STDOUT, ">", $tmpoutname or
224 die "Cannot open tempfile $tmpoutname again $!\n";
225 } else {
226 open STDOUT, ">", "/dev/null" or
227 die "Cannot open /dev/null ??? $!\n";
228 }
229 close STDERR;
230 if ( $tmpoutname ) {
231 open STDERR, ">", $tmperrname or
232 die "Cannot open tempfile $tmperrname again $!\n";
233 } else {
234 open STDERR, ">", "/dev/null" or
235 die "Cannot open /dev/null ??? $!\n";
236 }
237 exec $self->{"openssl"}, @_;
238 }
239 $rc = $? >> 8 if waitpid($pid, 0) > 0;
240
241 { local $/; $dataout = <$tmpout>; };
242 { local $/; $dataerr = <$tmperr>; };
243
244 $tmpinname and unlink $tmpinname;
245 $tmpoutname and unlink $tmpoutname;
246 $tmperrname and unlink $tmperrname;
247
248 if ( $rc >> 8 ) {
249 $::log->warn("Execute openssl " . $ARGV[0] . " failed: $rc");
250 (my $errmsg = $dataerr) =~ s/\n.*//sgm;
251 $::log->verb(6,"STDERR:",$errmsg);
252 return undef unless wantarray;
253 return (undef,$dataerr);
254 }
255 return $dataout unless wantarray;
256 return ($dataout,$dataerr);
257 }
258
259 sub Exec3($@) {
260 my $self = shift;
261
262 grep /^pipe$/, $::cnf->{_}->{exec3mode}||"" and return $self->Exec3pipe(@_);
263 grep /^select$/, $::cnf->{_}->{exec3mode}||"" and return $self->Exec3select(@_);
264 return $self->Exec3file(@_); # default
265 }
266
267 sub gms2t($$) {
268 my $self = shift;
269 my ( $month, $mday, $htm, $year, $tz ) = split(/\s+/,$_[0]);
270 die "OSSL::gms2t: cannot hangle non GMT output from OpenSSL\n"
271 unless $tz eq "GMT";
272
273 my %mon=("Jan"=>0,"Feb"=>1,"Mar"=>2,"Apr"=>3,"May"=>4,"Jun"=>5,
274 "Jul"=>6,"Aug"=>7,"Sep"=>8,"Oct"=>9,"Nov"=>10,"Dec"=>11);
275
276 my ( $hrs,$min,$sec ) = split(/:/,$htm);
277 my $gmt = timegm($sec,$min,$hrs,$mday,$mon{$month},$year);
278
279 #print STDERR ">>> converted $_[0] to $gmt\n";
280 return $gmt;
281 }
282
283
284 1;

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28