File: PgpDecryptExpect

package info (click to toggle)
exmh 1%3A2.9.0-8
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,932 kB
  • sloc: tcl: 38,143; perl: 1,647; makefile: 130; sh: 101; exp: 75; csh: 9; sed: 2
file content (183 lines) | stat: -rw-r--r-- 4,914 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# -*-Mode: tcl;-*-
#
# To be interpreted by expectk
# 
#
# This is run by exmh, currenly only when decrypting certain PGP messages.
# See Preferences->Pgp->Help or the source code for more information.
#
# Arguments: v, infile, outfile, exmh-bg name

wm withdraw .

if {[llength $argv] < 4} {
    puts "PgpDecryptExpect should be invoked by exmh"
    exit 1
}

set v [lindex $argv 0]
set infile [lindex $argv 1]
set outfile [lindex $argv 2]
set exmhbg [lindex [lrange $argv 3 [expr [llength $argv] - 1]] 0]
set badpass 0
set encrypted 0

# GetPassword tries (if necessary) to get the the pass phrase using
# Exmh's Misc_GetPass command.  It sets pgpPass if it gets a
# legitamite password.

proc GetPassword { key } {
    global spawn_id expect_out badpass v

    if {[string match conventional $key]} {
	set password [Exmh [list Pgp_Misc_GetPass $v \
                        "Enter [Exmh [list set pgp($v,fullName)]] Password" \
			"symmetric encryption - enter pass phrase"] ]
    } else {
	Match_PrivateExact $key keyid keydesc
	
	if $badpass {
	    Exmh [list unset pgp($v,pass,$keyid)]
	}
	
	if {$keyid!={} && [Exmh [list info exists pgp($v,pass,$keyid)]]} {
	    set password [Exmh [list set pgp($v,pass,$keyid)]]
	} else {
	    set password [Exmh [list Pgp_Misc_GetPass $v \
                        "Enter [Exmh [list set pgp($v,fullName)]] Password" \
                        "password for $keydesc"] ]
            Exmh [list set pgp($v,pass,$keyid) $password]
	}
	set badpass 1
    }

    exp_send "${password}\r"
    InterpretResponse
}

# search privatekeys for the keyid exactly matching keydesc
# returns keyid or {}
proc Match_PrivateExact { key keyidVar keydescVar } {
    global v
    upvar $keyidVar keyid
    upvar $keydescVar keydesc

    foreach elem [Exmh [list set pgp($v,privatekeys)]] {
        # One key keys (main only)
        set hexid [lindex $elem 0]
        if {[regexp $key $hexid]} {
            Debug "<Match_PrivateExact> $hexid"
            set keyid $hexid
            set keydesc [lindex $elem 4]
            return
        }
        # Double key keys (main and sub)
        set hexid [lindex $elem 2]
        if {[regexp $key $hexid]} {
            Debug "<Match_PrivateExact> $hexid"
            set keyid $hexid
            set keydesc [lindex $elem 4]
            return
        }
    }
    set keyid {}
    set keydesc $key
}

# Saves typing - this calls the given Exmh command.
proc Exmh {cmd} {
    global exmhbg
    send $exmhbg $cmd
}

proc Debug {text} {
#    send exmh [concat Exmh_Debug [list $text]]
    if {![catch {open /home/markus/***exmh***/dlog {APPEND WRONLY}} fd]} {
        puts $fd $text
        close $fd
    }
}

proc InterpretResponse { } {
    global spawn_id timeout expect_out badpass encrypted v

    expect {
	[Exmh [list set pgp($v,expectpat,passprompt)]] {
            if {[info exists expect_out(1,string)]} {
	        GetPassword $expect_out(1,string)
            } else {
                # There was no keyid and the program is prompting for a password?
                # It must be conventional encryption then. I hope this hasn't
                # unforeseen effects
                set encrypted 1
                GetPassword conventional
            }
	}
	-re [Exmh [list set pgp($v,expectpat,conventional)]] {
	    set encrypted 1
	    set expect_out(1,string) conventional
	    InterpretResponse
	}
        -re [Exmh [list set pgp($v,expectpat,publickey)]] {
            # I hope 40 is enough on slow computers
            set timeout 40
            set badpass 0
            set encrypted 1
            InterpretResponse
        }
	-re [Exmh [list set pgp($v,expectpat,secretmissing)]] {
	    set encrypted 1
	    catch {regsub -all \r $expect_out(1,string)$expect_out(2,string) {} msg}
	    Done $msg 1
	}
	-re [Exmh [list set pgp($v,expectpat,nopgpfile)]] {
	    Done $expect_out(1,string) 2
	}
	eof {
            Debug Eof
	    regsub -all \r $expect_out(buffer) {} msg
	    Done [string trim $msg]
	}
    }
    Debug Error
    Done "Unknown Error" 2
}

# Done is the procedure that calls the Exmh continuation command
# before this process exits.
proc Done {msg {error 0} } {
    global outfile infile encrypted

    if !$encrypted {
	set msg "Note: File may not have been encrypted.\n\n$msg"
    }

    if {$error==2} {
	set msg "Error processing with PGP\n$msg"
    }

    if {[string trim $msg]==""} {
	set msg "Message encrypted with PGP"
    }
    Exmh [list set pgpmsg $msg]
    puts $msg
    exit $error
}

expect_after timeout {
    Done "Unknown Error" 2
}
set timeout 4

# Now execute the whole thing
eval [concat spawn -nottycopy -noecho [Exmh [list set pgp($v,cmd_DecryptExpect)]]]

# Don't ask me why, but when I comment out the following line my
# program ceases to work under some conditions.  Mail me
# <bescoto@usa.net> if you figure it out.
expect -re . {}

catch {InterpretResponse} error
Debug $error

exit 3