root/10kz/shell/perl.jm3

Revision 49, 3.9 kB (checked in by jm3, 2 years ago)

decryption + verification working!

  • Property svn:executable set to *
  • Property svn:keywords set to Id
Line 
1 #!/usr/bin/perl
2
3 use CGI qw/:standard/;
4
5 # for gpg stderr mangling:
6 use IPC::Open3;
7 use Symbol qw(gensym);
8 use IO::File;
9
10 $debug = 1;
11 if( $debug ) {
12         open LOG, ">/tmp/10kz.log" or print "\n\nCouldn't open logfile for writing: $!\n";
13         print LOG "*** starting new crypto session: ***\n";
14         my $pwd = `pwd`;
15         print LOG "pwd: $pwd\n";
16 }
17
18 # FIXME: ugh, unless we perl-ify the other shell scripts, we need a way to share the configure.sh info between perl + shell
19 my $bin = "/usr/local/bin";
20 my $KEY_HOME = "/Users/jmanoogi/.gnupg";
21
22 print header('text/plain');
23        
24 if (param()) {
25         my $mode  = param('mode');
26
27         my $key_id     = param('key_id');
28         my $passphrase = param('passphrase');
29         my $recipients = param('recipients');
30         # FIXME: refactor: this is mis-named; since decrypt() expects the ciphertext to come in here, should be renamed as input text
31         my $plaintext  = param('plaintext');
32
33         $key_id =~      s/([\&;\`'\\\|"*?~<>^\(\)\[\]\{\}\$\n\r])/\\$1/g;
34         $passphrase =~  s/([\&;\`'\\\|"*?~<>^\(\)\[\]\{\}\$\n\r])/\\$1/g;
35
36         # don't shell-encode the plaintext (it will be stored in a file)
37         $recipients = parse_recips( $recipients );
38         $recipients =~  s/([\&;\`'\\\|"*?~<>^\(\)\[\]\{\}\$\n\r])/\\$1/g;
39         $plaintext  =~ s/__PLUS__/+/g;
40         my $pt = "/tmp/plaintext";
41
42         my $default_ops = "--no-tty "
43                 . " --no-permission-warning --load-extension idea --homedir $KEY_HOME";
44         my $recips = "$recipients" . ($key_id ? " -r $key_id --default-key $key_id " : "");
45
46         my $sign_cmd    = "echo '$passphrase' | $bin/gpg $default_ops --command-fd 0 --passphrase-fd 0 --armor --clearsign $pt";
47         my $verify_cmd    = "$bin/gpg $default_ops --verify $pt";
48         my $decrypt_cmd = "echo '$passphrase' | $bin/gpg $default_ops --command-fd 0 --passphrase-fd 0 --ignore-crc-error --output $pt.asc --decrypt $pt";
49         my $cmd =                              "$bin/gpg $default_ops $recips --armor --encrypt $pt";
50
51         if( $mode eq "verify" ) {
52                 $cmd = $verify_cmd;
53                 # replace gmail-rewritten links
54                 print LOG "rewriting gmail-munged links\n";
55                 $plaintext =~ s/<a onclick="return top\.js\.[^>]*>(http[^<]*)<\/a>/$1/g;
56
57         }
58         if( $mode eq "sign" ) { $cmd = $sign_cmd; }
59         if( $mode eq "decrypt" ) { $cmd = $decrypt_cmd; }
60         if( $debug == 1 ) { print LOG "\$cmd: $cmd\n"; }
61         if( $debug == 1 ) { print LOG "\$plaintext: $plaintext\n"; }
62
63         open PLAINTEXT, ">$pt" or print "\n\nCouldn't open '$pt' to write: $!\n";
64         print PLAINTEXT $plaintext;
65         close PLAINTEXT;
66
67         # FIXME: need to tee off stderr here so we can capture and optionally grovel through GPG's egregiously bad error messages
68         # for now, we're just suppressing them
69         my $out; # = `$cmd &> /dev/null`;
70         my $err;
71
72         local *CATCHOUT = IO::File->new_tmpfile;
73         local *CATCHERR = IO::File->new_tmpfile;
74         my $pid = open3(gensym, ">&CATCHOUT", ">&CATCHERR", "$cmd");
75         waitpid($pid, 0);
76         seek $_, 0, 0 for \*CATCHOUT, \*CATCHERR;
77         $out = $err = "";
78         while( <CATCHOUT> ) {
79                 $out .= $_;
80         }
81         while( <CATCHERR> ) {
82                 $err .= $_;
83         }
84
85         if( $debug == 1 ) {
86                 print LOG "err: $err\n";
87                 print LOG "out: $out\n";
88         }
89        
90         if( -f "$pt.asc" && $mode ne "verify" ) {
91                 $data = `cat $pt.asc`;
92                 print "<?xml version='1.0'?>\n<data>$data</data>";
93         } elsif( $mode eq "verify" ) {
94                 print "<?xml version='1.0'?>\n<data>$err\n\n$plaintext</data>";
95         } else {
96                 print "<?xml version='1.0'?>\n<data><error>mode: $mode\n Source: $plaintext\n$err\nCommand:\n$cmd</error></data>";
97         }
98
99         # cache these for post-hoc analysis
100         if( $debug == 1 ) {
101                 if( -f $pt ) {
102                         `cp $pt /tmp/plaintext.bak`;
103                 }
104                 if( -f "$pt.asc" ) {
105                         `cp $pt.asc /tmp/plaintext.asc.bak`;
106                 }
107         }
108         unlink $pt;
109         unlink "$pt.asc";
110
111         if( $debug ) {
112                 #print LOG "Your passphrase is: $passphrase, key_id is: $key_id, the recipients are: $recipients, The plaintext is: $plaintext\n";
113         }
114
115 } else {
116
117         print "<error>No Input: Make sure you are passing a minimum of: key_id, recipients, plaintext (and passphrase, if you're signing)</error>";
118
119 }
120
121 sub parse_recips {
122         my $r = $_[-1];
123         $r =~ s:^.*?<:-r :g;
124         $r =~ s:>,.+?<: -r :g;
125         $r =~ s:[<>]::g;
126         $r =~ s:,::g;
127         return "$r";
128 }
Note: See TracBrowser for help on using the browser.