Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

can't open file for writing that doesn't exist

by navalned (Beadle)
on Mar 22, 2020 at 19:14 UTC ( #11114547=perlquestion: print w/replies, xml ) Need Help??

navalned has asked for the wisdom of the Perl Monks concerning the following question:

I've written a dkim-signing filter for opensmtpd that works well. I decided to add the ability to create key pairs and print out the dns entries, etc, etc. Anyway the following code works. Albeit needs some cleaning up. However, it only works if the files already exist.

sub create_keys { my @selectors; my @towrite; eval { require Crypt::OpenSSL::RSA; require Crypt::OpenSSL::Random; foreach my $domain (keys %keys) { my $keyfile = $keys{$domain}->{key}; my $pubfile = $keyfile =~ s/key/pub/g; my $selector = $keys{$domain}->{selector}; Crypt::OpenSSL::RSA->import_random_seed(); my $rsa = Crypt::OpenSSL::RSA->generate_key(1024); my $pub_string = $rsa->get_public_key_string(); my $key_string = $rsa->get_private_key_string(); my $select_string = "-----BEGIN DNS ENTRIES FOR $domain--- +--\n"; $select_string .= "_domainkey IN TXT \"o=~;\"\n\n"; $pub_string =~ s/-----BEGIN\ RSA\ PUBLIC\ KEY-----//g; $pub_string =~ s/-----END\ RSA\ PUBLIC\ KEY-----//g; $pub_string =~ s/\s//g; $select_string .= "$selector\._domainkey IN TXT \"k=rsa\\; +\n"; $select_string .= "p=$pub_string\\;\"\n"; $select_string .= "-----END DNS ENTRIES FOR $domain-----\n +"; push @selectors, $select_string; push @towrite, { key => $keyfile, pub => $pubfile, keystring => $key_string, pubstring => $pub_string }; } }; die "Failed to create keypair: $@" if $@; # moved this out of the eval just to see if that would change anything foreach my $write (@towrite) { { open (my $key, ">", $write->{key}) or die "$!"; print $key $write->{keystring}; open (my $pub, ">", $write->{pub}) or die "$!"; print $pub $write->{pubstring}; } } foreach my $s (@selectors) { print $s . "\n"; } exit 0; }

Here is some sample output:

-----BEGIN DNS ENTRIES FOR domain.tld----- _domainkey IN TXT "o=~;" dkim._domainkey IN TXT "k=rsa\; p=MIGJAoGBAKghtMMxSlhU973zhV29hc0xeppV76jQmdLoIV/Zz9wJw6OenVU4dFWaT5gz +ENe3ufSxkbSOOmGKl5ukurpvPXtoymoD7DcVkU02HDApzmVgwHpT4E/A22SoGxuNwqFrh +VTmwb4gdSVGOKnkUIgeXelDsoG2F22FgnxWjjH03u/FAgMBAAE=\;" -----END DNS ENTRIES FOR domain.tld----- -----BEGIN DNS ENTRIES FOR domain.stuff.tld----- _domainkey IN TXT "o=~;" dkim._domainkey IN TXT "k=rsa\; p=MIGJAoGBAMAxZ3sixzpuON9XQu+zVzJknyJ6sQcJGZxpHKDTz2QG7V5Hpno3jXHYrHqf +nJ+pDtw7IloAT6zYe4DAsFyTbj1/96r1eRubL8DnU59mtxQAQmyoOVa0hiyJss6RTq49Z +dXuVhF0bqqvgrBS51ErkddACBz5F2TxfkO/qli6boL3AgMBAAE=\;" -----END DNS ENTRIES FOR domain.stuff.tld-----

This is what I get if the files don't already exist:
Error: cannot read /home/edgar/domain.stuff.tld.key: No such file or directory

This of course works:
perl -e 'open (my $fh, ">", "/home/edgar/domain.test.key") or die "$!";'
And creates a 0 length file.

Replies are listed 'Best First'.
Re: can't open file for writing that doesn't exist
by Corion (Patriarch) on Mar 22, 2020 at 19:19 UTC

    You're looking at (or showing us) the wrong part of the code. Your code as shown does not contain the string Error: cannot read, so the error message is produced elsewhere.

    Where exactly are you getting that error message?

    Also, what are the filenames that you construct? Do they contain the absolute filenames, without any whitespace?

      Thanks! I need to make some changes to the config_parse().

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11114547]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2022-05-19 19:32 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (72 votes). Check out past polls.