]>
Commit | Line | Data |
---|---|---|
e1613d9f | 1 | #! /usr/bin/env perl |
7622baf8 | 2 | # Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. |
e1613d9f RL |
3 | # |
4 | # Licensed under the OpenSSL license (the "License"). You may not use | |
5 | # this file except in compliance with the License. You can obtain a copy | |
6 | # in the file LICENSE in the source distribution or at | |
7 | # https://www.openssl.org/source/license.html | |
8 | ||
a75831f9 | 9 | use File::Spec::Functions; |
4c0669dc | 10 | use File::Copy; |
e1613d9f | 11 | use MIME::Base64; |
d32e10d6 | 12 | use OpenSSL::Test qw(:DEFAULT srctop_file srctop_dir bldtop_file data_file); |
45fd6a59 | 13 | use OpenSSL::Test::Utils; |
e1613d9f RL |
14 | |
15 | my $test_name = "test_store"; | |
16 | setup($test_name); | |
17 | ||
18 | my @noexist_files = | |
19 | ( "test/blahdiblah.pem", | |
20 | "test/blahdibleh.der" ); | |
21 | my @src_files = | |
22 | ( "test/testx509.pem", | |
23 | "test/testrsa.pem", | |
24 | "test/testrsapub.pem", | |
25 | "test/testcrl.pem", | |
26 | "apps/server.pem" ); | |
27 | my @generated_files = | |
28 | ( | |
29 | ### generated from the source files | |
30 | ||
31 | "testx509.der", | |
32 | "testrsa.der", | |
33 | "testrsapub.der", | |
34 | "testcrl.der", | |
35 | ||
36 | ### generated locally | |
e1613d9f RL |
37 | |
38 | "rsa-key-pkcs1.pem", "rsa-key-pkcs1.der", | |
39 | "rsa-key-pkcs1-aes128.pem", | |
40 | "rsa-key-pkcs8.pem", "rsa-key-pkcs8.der", | |
41 | "rsa-key-pkcs8-pbes1-sha1-3des.pem", "rsa-key-pkcs8-pbes1-sha1-3des.der", | |
42 | "rsa-key-pkcs8-pbes2-sha1.pem", "rsa-key-pkcs8-pbes2-sha1.der", | |
43 | "rsa-key-sha1-3des-sha1.p12", "rsa-key-sha1-3des-sha256.p12", | |
44 | "rsa-key-aes256-cbc-sha256.p12", | |
45 | "rsa-key-md5-des-sha1.p12", | |
46 | "rsa-key-aes256-cbc-md5-des-sha256.p12", | |
47 | "rsa-key-pkcs8-pbes2-sha256.pem", "rsa-key-pkcs8-pbes2-sha256.der", | |
48 | "rsa-key-pkcs8-pbes1-md5-des.pem", "rsa-key-pkcs8-pbes1-md5-des.der", | |
49 | "dsa-key-pkcs1.pem", "dsa-key-pkcs1.der", | |
50 | "dsa-key-pkcs1-aes128.pem", | |
51 | "dsa-key-pkcs8.pem", "dsa-key-pkcs8.der", | |
52 | "dsa-key-pkcs8-pbes2-sha1.pem", "dsa-key-pkcs8-pbes2-sha1.der", | |
53 | "dsa-key-aes256-cbc-sha256.p12", | |
54 | "ec-key-pkcs1.pem", "ec-key-pkcs1.der", | |
55 | "ec-key-pkcs1-aes128.pem", | |
56 | "ec-key-pkcs8.pem", "ec-key-pkcs8.der", | |
57 | "ec-key-pkcs8-pbes2-sha1.pem", "ec-key-pkcs8-pbes2-sha1.der", | |
58 | "ec-key-aes256-cbc-sha256.p12", | |
59 | ); | |
4c0669dc RL |
60 | my %generated_file_files = |
61 | $^O eq 'linux' | |
62 | ? ( "test/testx509.pem" => "file:testx509.pem", | |
63 | "test/testrsa.pem" => "file:testrsa.pem", | |
64 | "test/testrsapub.pem" => "file:testrsapub.pem", | |
65 | "test/testcrl.pem" => "file:testcrl.pem", | |
66 | "apps/server.pem" => "file:server.pem" ) | |
67 | : (); | |
68 | my @noexist_file_files = | |
69 | ( "file:blahdiblah.pem", | |
70 | "file:test/blahdibleh.der" ); | |
71 | ||
346bf1a2 RL |
72 | my $n = (3 * scalar @noexist_files) |
73 | + (6 * scalar @src_files) | |
74 | + (4 * scalar @generated_files) | |
4c0669dc RL |
75 | + (scalar keys %generated_file_files) |
76 | + (scalar @noexist_file_files) | |
7622baf8 | 77 | + 3 |
a75831f9 | 78 | + 11; |
e1613d9f RL |
79 | |
80 | plan tests => $n; | |
81 | ||
82 | indir "store_$$" => sub { | |
83 | SKIP: | |
84 | { | |
85 | skip "failed initialisation", $n unless init(); | |
86 | ||
a75831f9 | 87 | my $rehash = init_rehash(); |
0443b117 | 88 | |
e1613d9f RL |
89 | foreach (@noexist_files) { |
90 | my $file = srctop_file($_); | |
79120f46 | 91 | |
f106f406 RL |
92 | ok(!run(app(["openssl", "storeutl", $file]))); |
93 | ok(!run(app(["openssl", "storeutl", to_abs_file($file)]))); | |
94 | { | |
95 | local $ENV{MSYS2_ARG_CONV_EXCL} = "file:"; | |
79120f46 RL |
96 | |
97 | ok(!run(app(["openssl", "storeutl", to_abs_file_uri($file)]))); | |
98 | } | |
e1613d9f RL |
99 | } |
100 | foreach (@src_files) { | |
101 | my $file = srctop_file($_); | |
79120f46 | 102 | |
f106f406 RL |
103 | ok(run(app(["openssl", "storeutl", $file]))); |
104 | ok(run(app(["openssl", "storeutl", to_abs_file($file)]))); | |
105 | { | |
106 | local $ENV{MSYS2_ARG_CONV_EXCL} = "file:"; | |
79120f46 RL |
107 | |
108 | ok(run(app(["openssl", "storeutl", to_abs_file_uri($file)]))); | |
109 | ok(run(app(["openssl", "storeutl", | |
110 | to_abs_file_uri($file, 0, "")]))); | |
111 | ok(run(app(["openssl", "storeutl", | |
112 | to_abs_file_uri($file, 0, "localhost")]))); | |
113 | ok(!run(app(["openssl", "storeutl", | |
114 | to_abs_file_uri($file, 0, "dummy")]))); | |
115 | } | |
e1613d9f RL |
116 | } |
117 | foreach (@generated_files) { | |
f106f406 RL |
118 | ok(run(app(["openssl", "storeutl", "-passin", "pass:password", |
119 | $_]))); | |
120 | ok(run(app(["openssl", "storeutl", "-passin", "pass:password", | |
121 | to_abs_file($_)]))); | |
79120f46 | 122 | |
f106f406 RL |
123 | { |
124 | local $ENV{MSYS2_ARG_CONV_EXCL} = "file:"; | |
79120f46 RL |
125 | |
126 | ok(run(app(["openssl", "storeutl", "-passin", "pass:password", | |
127 | to_abs_file_uri($_)]))); | |
128 | ok(!run(app(["openssl", "storeutl", "-passin", "pass:password", | |
129 | to_file_uri($_)]))); | |
130 | } | |
e1613d9f | 131 | } |
4c0669dc | 132 | foreach (values %generated_file_files) { |
f106f406 | 133 | local $ENV{MSYS2_ARG_CONV_EXCL} = "file:"; |
79120f46 | 134 | |
f106f406 | 135 | ok(run(app(["openssl", "storeutl", $_]))); |
4c0669dc RL |
136 | } |
137 | foreach (@noexist_file_files) { | |
f106f406 | 138 | local $ENV{MSYS2_ARG_CONV_EXCL} = "file:"; |
79120f46 | 139 | |
f106f406 | 140 | ok(!run(app(["openssl", "storeutl", $_]))); |
4c0669dc | 141 | } |
d32e10d6 RL |
142 | { |
143 | my $dir = srctop_dir("test", "certs"); | |
79120f46 | 144 | |
f106f406 RL |
145 | ok(run(app(["openssl", "storeutl", $dir]))); |
146 | ok(run(app(["openssl", "storeutl", to_abs_file($dir, 1)]))); | |
147 | { | |
148 | local $ENV{MSYS2_ARG_CONV_EXCL} = "file:"; | |
79120f46 RL |
149 | |
150 | ok(run(app(["openssl", "storeutl", to_abs_file_uri($dir, 1)]))); | |
151 | } | |
d32e10d6 | 152 | } |
7622baf8 | 153 | |
a75831f9 RL |
154 | ok(!run(app(['openssl', 'storeutl', |
155 | '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert', | |
156 | srctop_file('test', 'testx509.pem')])), | |
157 | "Checking that -subject can't be used with a single file"); | |
158 | ||
7622baf8 RL |
159 | ok(run(app(['openssl', 'storeutl', '-certs', |
160 | srctop_file('test', 'testx509.pem')])), | |
161 | "Checking that -certs returns 1 object on a certificate file"); | |
162 | ok(run(app(['openssl', 'storeutl', '-certs', | |
163 | srctop_file('test', 'testcrl.pem')])), | |
164 | "Checking that -certs returns 0 objects on a CRL file"); | |
165 | ||
166 | ok(run(app(['openssl', 'storeutl', '-crls', | |
167 | srctop_file('test', 'testx509.pem')])), | |
168 | "Checking that -crls returns 0 objects on a certificate file"); | |
169 | ok(run(app(['openssl', 'storeutl', '-crls', | |
170 | srctop_file('test', 'testcrl.pem')])), | |
171 | "Checking that -crls returns 1 object on a CRL file"); | |
a75831f9 RL |
172 | |
173 | SKIP: { | |
174 | skip "failed rehash initialisation", 6 unless $rehash; | |
175 | ||
176 | # subject from testx509.pem: | |
177 | # '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert' | |
178 | # issuer from testcrl.pem: | |
179 | # '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority' | |
180 | ok(run(app(['openssl', 'storeutl', | |
181 | '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert', | |
182 | catdir(curdir(), 'rehash')]))); | |
183 | ok(run(app(['openssl', 'storeutl', | |
184 | '-subject', | |
185 | '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority', | |
186 | catdir(curdir(), 'rehash')]))); | |
187 | ok(run(app(['openssl', 'storeutl', '-certs', | |
188 | '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert', | |
189 | catdir(curdir(), 'rehash')]))); | |
190 | ok(run(app(['openssl', 'storeutl', '-crls', | |
191 | '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert', | |
192 | catdir(curdir(), 'rehash')]))); | |
193 | ok(run(app(['openssl', 'storeutl', '-certs', | |
194 | '-subject', | |
195 | '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority', | |
196 | catdir(curdir(), 'rehash')]))); | |
197 | ok(run(app(['openssl', 'storeutl', '-crls', | |
198 | '-subject', | |
199 | '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority', | |
200 | catdir(curdir(), 'rehash')]))); | |
201 | } | |
e1613d9f RL |
202 | } |
203 | }, create => 1, cleanup => 1; | |
204 | ||
205 | sub init { | |
206 | return ( | |
207 | # rsa-key-pkcs1.pem | |
208 | run(app(["openssl", "genrsa", | |
209 | "-out", "rsa-key-pkcs1.pem", "2432"])) | |
210 | # dsa-key-pkcs1.pem | |
211 | && run(app(["openssl", "dsaparam", "-genkey", | |
212 | "-out", "dsa-key-pkcs1.pem", "1024"])) | |
213 | # ec-key-pkcs1.pem (one might think that 'genec' would be practical) | |
214 | && run(app(["openssl", "ecparam", "-genkey", "-name", "prime256v1", | |
215 | "-out", "ec-key-pkcs1.pem"])) | |
216 | # rsa-key-pkcs1-aes128.pem | |
217 | && run(app(["openssl", "rsa", "-passout", "pass:password", "-aes128", | |
218 | "-in", "rsa-key-pkcs1.pem", | |
219 | "-out", "rsa-key-pkcs1-aes128.pem"])) | |
220 | # dsa-key-pkcs1-aes128.pem | |
221 | && run(app(["openssl", "dsa", "-passout", "pass:password", "-aes128", | |
222 | "-in", "dsa-key-pkcs1.pem", | |
223 | "-out", "dsa-key-pkcs1-aes128.pem"])) | |
224 | # ec-key-pkcs1-aes128.pem | |
225 | && run(app(["openssl", "ec", "-passout", "pass:password", "-aes128", | |
226 | "-in", "ec-key-pkcs1.pem", | |
227 | "-out", "ec-key-pkcs1-aes128.pem"])) | |
228 | # *-key-pkcs8.pem | |
229 | && runall(sub { | |
230 | my $dstfile = shift; | |
231 | (my $srcfile = $dstfile) | |
232 | =~ s/-key-pkcs8\.pem$/-key-pkcs1.pem/i; | |
233 | run(app(["openssl", "pkcs8", "-topk8", "-nocrypt", | |
234 | "-in", $srcfile, "-out", $dstfile])); | |
235 | }, grep(/-key-pkcs8\.pem$/, @generated_files)) | |
236 | # *-key-pkcs8-pbes1-sha1-3des.pem | |
237 | && runall(sub { | |
238 | my $dstfile = shift; | |
239 | (my $srcfile = $dstfile) | |
240 | =~ s/-key-pkcs8-pbes1-sha1-3des\.pem$ | |
241 | /-key-pkcs8.pem/ix; | |
242 | run(app(["openssl", "pkcs8", "-topk8", | |
243 | "-passout", "pass:password", | |
244 | "-v1", "pbeWithSHA1And3-KeyTripleDES-CBC", | |
245 | "-in", $srcfile, "-out", $dstfile])); | |
246 | }, grep(/-key-pkcs8-pbes1-sha1-3des\.pem$/, @generated_files)) | |
247 | # *-key-pkcs8-pbes1-md5-des.pem | |
248 | && runall(sub { | |
249 | my $dstfile = shift; | |
250 | (my $srcfile = $dstfile) | |
251 | =~ s/-key-pkcs8-pbes1-md5-des\.pem$ | |
252 | /-key-pkcs8.pem/ix; | |
253 | run(app(["openssl", "pkcs8", "-topk8", | |
254 | "-passout", "pass:password", | |
255 | "-v1", "pbeWithSHA1And3-KeyTripleDES-CBC", | |
256 | "-in", $srcfile, "-out", $dstfile])); | |
257 | }, grep(/-key-pkcs8-pbes1-md5-des\.pem$/, @generated_files)) | |
258 | # *-key-pkcs8-pbes2-sha1.pem | |
259 | && runall(sub { | |
260 | my $dstfile = shift; | |
261 | (my $srcfile = $dstfile) | |
262 | =~ s/-key-pkcs8-pbes2-sha1\.pem$ | |
263 | /-key-pkcs8.pem/ix; | |
264 | run(app(["openssl", "pkcs8", "-topk8", | |
265 | "-passout", "pass:password", | |
266 | "-v2", "aes256", "-v2prf", "hmacWithSHA1", | |
267 | "-in", $srcfile, "-out", $dstfile])); | |
268 | }, grep(/-key-pkcs8-pbes2-sha1\.pem$/, @generated_files)) | |
269 | # *-key-pkcs8-pbes2-sha1.pem | |
270 | && runall(sub { | |
271 | my $dstfile = shift; | |
272 | (my $srcfile = $dstfile) | |
273 | =~ s/-key-pkcs8-pbes2-sha256\.pem$ | |
274 | /-key-pkcs8.pem/ix; | |
275 | run(app(["openssl", "pkcs8", "-topk8", | |
276 | "-passout", "pass:password", | |
277 | "-v2", "aes256", "-v2prf", "hmacWithSHA256", | |
278 | "-in", $srcfile, "-out", $dstfile])); | |
279 | }, grep(/-key-pkcs8-pbes2-sha256\.pem$/, @generated_files)) | |
6d737ea0 RL |
280 | # *-cert.pem (intermediary for the .p12 inits) |
281 | && run(app(["openssl", "req", "-x509", | |
282 | "-config", data_file("ca.cnf"), "-nodes", | |
283 | "-out", "cacert.pem", "-keyout", "cakey.pem"])) | |
284 | && runall(sub { | |
285 | my $srckey = shift; | |
286 | (my $dstfile = $srckey) =~ s|-key-pkcs8\.|-cert.|; | |
287 | (my $csr = $dstfile) =~ s|\.pem|.csr|; | |
288 | ||
289 | (run(app(["openssl", "req", "-new", | |
290 | "-config", data_file("user.cnf"), | |
291 | "-key", $srckey, "-out", $csr])) | |
292 | && | |
293 | run(app(["openssl", "x509", "-days", "3650", | |
294 | "-CA", "cacert.pem", | |
295 | "-CAkey", "cakey.pem", | |
296 | "-set_serial", time(), "-req", | |
297 | "-in", $csr, "-out", $dstfile]))); | |
298 | }, grep(/-key-pkcs8\.pem$/, @generated_files)) | |
299 | # *.p12 | |
300 | && runall(sub { | |
301 | my $dstfile = shift; | |
302 | my ($type, $certpbe_index, $keypbe_index, | |
303 | $macalg_index) = | |
304 | $dstfile =~ m{^(.*)-key-(?| | |
305 | # cert and key PBE are same | |
306 | () # | |
307 | ([^-]*-[^-]*)- # key & cert PBE | |
308 | ([^-]*) # MACalg | |
309 | | | |
310 | # cert and key PBE are not same | |
311 | ([^-]*-[^-]*)- # cert PBE | |
312 | ([^-]*-[^-]*)- # key PBE | |
313 | ([^-]*) # MACalg | |
314 | )\.}x; | |
315 | if (!$certpbe_index) { | |
316 | $certpbe_index = $keypbe_index; | |
317 | } | |
318 | my $srckey = "$type-key-pkcs8.pem"; | |
319 | my $srccert = "$type-cert.pem"; | |
320 | my %pbes = | |
321 | ( | |
322 | "sha1-3des" => "pbeWithSHA1And3-KeyTripleDES-CBC", | |
323 | "md5-des" => "pbeWithMD5AndDES-CBC", | |
324 | "aes256-cbc" => "AES-256-CBC", | |
325 | ); | |
326 | my %macalgs = | |
327 | ( | |
328 | "sha1" => "SHA1", | |
329 | "sha256" => "SHA256", | |
330 | ); | |
331 | my $certpbe = $pbes{$certpbe_index}; | |
332 | my $keypbe = $pbes{$keypbe_index}; | |
333 | my $macalg = $macalgs{$macalg_index}; | |
334 | if (!defined($certpbe) || !defined($keypbe) | |
335 | || !defined($macalg)) { | |
336 | print STDERR "Cert PBE for $pbe_index not defined\n" | |
337 | unless defined $certpbe; | |
338 | print STDERR "Key PBE for $pbe_index not defined\n" | |
339 | unless defined $keypbe; | |
340 | print STDERR "MACALG for $macalg_index not defined\n" | |
341 | unless defined $macalg; | |
342 | print STDERR "(destination file was $dstfile)\n"; | |
343 | return 0; | |
344 | } | |
345 | run(app(["openssl", "pkcs12", "-inkey", $srckey, | |
346 | "-in", $srccert, "-passout", "pass:password", | |
347 | "-export", "-macalg", $macalg, | |
348 | "-certpbe", $certpbe, "-keypbe", $keypbe, | |
349 | "-out", $dstfile])); | |
350 | }, grep(/\.p12/, @generated_files)) | |
e1613d9f RL |
351 | # *.der (the end all init) |
352 | && runall(sub { | |
353 | my $dstfile = shift; | |
354 | (my $srcfile = $dstfile) =~ s/\.der$/.pem/i; | |
355 | if (! -f $srcfile) { | |
356 | $srcfile = srctop_file("test", $srcfile); | |
357 | } | |
358 | my $infh; | |
359 | unless (open $infh, $srcfile) { | |
360 | return 0; | |
361 | } | |
362 | my $l; | |
363 | while (($l = <$infh>) !~ /^-----BEGIN\s/ | |
364 | || $l =~ /^-----BEGIN.*PARAMETERS-----/) { | |
365 | } | |
366 | my $b64 = ""; | |
367 | while (($l = <$infh>) !~ /^-----END\s/) { | |
368 | $l =~ s|\R$||; | |
369 | $b64 .= $l unless $l =~ /:/; | |
370 | } | |
371 | close $infh; | |
372 | my $der = decode_base64($b64); | |
373 | unless (length($b64) / 4 * 3 - length($der) < 3) { | |
374 | print STDERR "Length error, ",length($b64), | |
375 | " bytes of base64 became ",length($der), | |
376 | " bytes of der? ($srcfile => $dstfile)\n"; | |
377 | return 0; | |
378 | } | |
379 | my $outfh; | |
380 | unless (open $outfh, ">:raw", $dstfile) { | |
381 | return 0; | |
382 | } | |
383 | print $outfh $der; | |
384 | close $outfh; | |
385 | return 1; | |
386 | }, grep(/\.der$/, @generated_files)) | |
4c0669dc RL |
387 | && runall(sub { |
388 | my $srcfile = shift; | |
389 | my $dstfile = $generated_file_files{$srcfile}; | |
390 | ||
391 | unless (copy srctop_file($srcfile), $dstfile) { | |
392 | warn "$!\n"; | |
393 | return 0; | |
394 | } | |
395 | return 1; | |
396 | }, keys %generated_file_files) | |
e1613d9f RL |
397 | ); |
398 | } | |
a75831f9 RL |
399 | |
400 | sub init_rehash { | |
401 | return ( | |
402 | mkdir(catdir(curdir(), 'rehash')) | |
403 | && copy(srctop_file('test', 'testx509.pem'), | |
404 | catdir(curdir(), 'rehash')) | |
405 | && copy(srctop_file('test', 'testcrl.pem'), | |
406 | catdir(curdir(), 'rehash')) | |
407 | && run(app(['openssl', 'rehash', catdir(curdir(), 'rehash')])) | |
408 | ); | |
409 | } | |
e1613d9f RL |
410 | |
411 | sub runall { | |
412 | my ($function, @items) = @_; | |
413 | ||
414 | foreach (@items) { | |
415 | return 0 unless $function->($_); | |
416 | } | |
417 | return 1; | |
418 | } | |
419 | ||
420 | # According to RFC8089, a relative file: path is invalid. We still produce | |
421 | # them for testing purposes. | |
94437ceb | 422 | sub to_file_uri { |
e1613d9f RL |
423 | my ($file, $isdir, $authority) = @_; |
424 | my $vol; | |
425 | my $dir; | |
426 | ||
94437ceb | 427 | die "to_file_uri: No file given\n" if !defined($file) || $file eq ''; |
e1613d9f RL |
428 | |
429 | ($vol, $dir, $file) = File::Spec->splitpath($file, $isdir // 0); | |
430 | ||
431 | # Make sure we have a Unix style directory. | |
432 | $dir = join('/', File::Spec->splitdir($dir)); | |
433 | # Canonicalise it (note: it seems to be only needed on Unix) | |
434 | while (1) { | |
435 | my $newdir = $dir; | |
436 | $newdir =~ s|/[^/]*[^/\.]+[^/]*/\.\./|/|g; | |
437 | last if $newdir eq $dir; | |
438 | $dir = $newdir; | |
439 | } | |
440 | # Take care of the corner cases the loop can't handle, and that $dir | |
441 | # ends with a / unless it's empty | |
442 | $dir =~ s|/[^/]*[^/\.]+[^/]*/\.\.$|/|; | |
443 | $dir =~ s|^[^/]*[^/\.]+[^/]*/\.\./|/|; | |
444 | $dir =~ s|^[^/]*[^/\.]+[^/]*/\.\.$||; | |
445 | if ($isdir // 0) { | |
446 | $dir =~ s|/$|| if $dir ne '/'; | |
447 | } else { | |
448 | $dir .= '/' if $dir ne '' && $dir !~ m|/$|; | |
449 | } | |
450 | ||
451 | # If the file system has separate volumes (at present, Windows and VMS) | |
452 | # we need to handle them. In URIs, they are invariably the first | |
453 | # component of the path, which is always absolute. | |
454 | # On VMS, user:[foo.bar] translates to /user/foo/bar | |
455 | # On Windows, c:\Users\Foo translates to /c:/Users/Foo | |
456 | if ($vol ne '') { | |
457 | $vol =~ s|:||g if ($^O eq "VMS"); | |
458 | $dir = '/' . $dir if $dir ne '' && $dir !~ m|^/|; | |
459 | $dir = '/' . $vol . $dir; | |
460 | } | |
461 | $file = $dir . $file; | |
462 | ||
463 | return "file://$authority$file" if defined $authority; | |
464 | return "file:$file"; | |
465 | } | |
466 | ||
346bf1a2 RL |
467 | sub to_abs_file { |
468 | my ($file) = @_; | |
469 | ||
470 | return File::Spec->rel2abs($file); | |
471 | } | |
472 | ||
94437ceb | 473 | sub to_abs_file_uri { |
e1613d9f RL |
474 | my ($file, $isdir, $authority) = @_; |
475 | ||
94437ceb RL |
476 | die "to_abs_file_uri: No file given\n" if !defined($file) || $file eq ''; |
477 | return to_file_uri(to_abs_file($file), $isdir, $authority); | |
e1613d9f | 478 | } |