Chainmail Applescript
Chainmail Applescript
- Subject: Chainmail Applescript
- From: Jeanne <email@hidden>
- Date: Sun, 30 Sep 2001 13:30:20 -0400
-----BEGIN PGP SIGNED MESSAGE-----
Below is the entire script called "Chainmail" This is the original
source. NOT the copy I have been tinkering with.
+++++++++Begin Chain mail 1.0b2++++++++++++++++
- --various preferences are stored as properties
property textwrap : true
property DefChain : ""
property DefSignFromUser : ""
property DefEncryptTo : false
property DefSign : false
property remailerFile : ""
property TurnOffSig : true
set RemailerInfoList to ""
- --NOTE: if you wish to run this script from the Script Editor (if you
are reading this comment, you probably do)
- --you need to set dialogfile to the proper path to this script
manually. eg:
- --set dialogfile to alias "Hard Disk:Some Folder:Remail/Eudora"
set dialogfile to alias "Silverthorn:ChainMail Dev:Chres 1.0b2"
- --location of dialog resources for DialogRunner
- --set dialogfile to "Internal Disk:ChainMail Developement:ChainMail
0.5:ChainMail working"
- -- Copy the initial fields we need from Eudora
try
tell application "Eudora 5.1" --Change this if you call Eudora
something else
set setting 84 to "y" --stop Eudora from checking for new mail,
until we're done.
set theMessage to a reference to message named ""
copy field named "" of theMessage to theText
copy field "To:" of theMessage to tempF
if length of tempF > 5 then
set theRecipient to items 5 through (number
of items in tempF) of
tempF -- get rid of the "To: "
else
set theRecipient to ""
end if
copy field "Cc:" of theMessage to tempF
if length of tempF > 5 then
set theCc to items 5 through (number of items
in tempF) of tempF
set theRecipient to theRecipient & "," & theCc
else
set theCc to ""
end if
copy field "Bcc:" of theMessage to tempF
if length of tempF > 6 then
set theBcc to items 6 through (number of
items in tempF) of tempF
else
set theBcc to ""
end if
copy field "Subject:" of theMessage to tempF
if length of tempF > 10 then
set theSubject to items 10 through (number of
items in tempF) of
tempF
else
set theSubject to ""
end if
end tell
on error
display dialog ,
"Please make sure the Eudora window you want to
encrypt from is the
top window." & return & return & ,
"But you can still set preferences if you like." buttons
{"Preferences", "Cancel"} default button ,
"Cancel" with icon 0
if button returned of result is "Preferences" then dopreferences()
return
end try
- --display dialog box interface, and set variables from returned
values, J. Rochkind
set {chainList, EncryptToUser, SignFromUser, theRecipient,
EncryptToRecipient, sign} to RemailDialog(theRecipient)
- -- strips Eurora Sig if user checks box
if TurnOffSig then
tell application "Eudora 5.1"
set signature of theMessage to none
end tell
end if
- --change chainlist from ";" delimited to applescript list
set chainList to string2list(chainList, ";")
- --set up some files and variables we need
set pathToDesktop to path to desktop
set tempOutFilePath to (pathToDesktop as string) & "TempFile"
set tempInFilePath to (pathToDesktop as string) & "TempFile.asc"
OverWrite(theText, tempOutFilePath)
- --word wrap, if neccesary
if textwrap then
WrapFile(tempOutFilePath)
end if
set theText to (read tempOutFilePath)
- --encrypt to recipient, and/or sign, if the user chose to do so
- -rochkind, from hodges code.
if EncryptToRecipient or sign then
OverWrite(theText, tempOutFilePath)
--encrypt, sign, or both, then wipe.
if EncryptToRecipient and sign then
DoEncryptandSign(tempOutFilePath, EncryptToUser, SignFromUser)
else if EncryptToRecipient then
DoEncrypt(tempOutFilePath, EncryptToUser as string)
else
doSign(tempOutFilePath, SignFromUser)
end if
--remember, we've got an unwiped tempOutFile on the loose here.
--got to leave it until we see if the next try works.
try
open for access tempInFilePath -- read from the
ciphertext tempfile
and get rid of it
on error --trying to open the file is the only way to detect MacPGP
errors
if sign and MacPGPRecycling() then --hmmm, recycling
bad passwords?
stopRecycle() --turn off recycle passwords,
and do it again
if EncryptToRecipient then
DoEncryptandSign(tempOutFilePath,
EncryptToUser, SignFromUser)
else
doSign(tempOutFilePath, SignFromUser)
end if
try
open for access tempInFilePath
on error --well, at least we tried. Now give up.
display dialog "Error in using
MacPGP." buttons {"Cancel"}
default button "Cancel" with icon 0
error -128
end try
else
WipeFile(tempOutFilePath)
display dialog "Error in using MacPGP."
buttons {"Cancel"} default
button "Cancel" with icon 0
error -128
end if
end try
WipeFile(tempOutFilePath)
set theText to (read tempInFilePath)
close access tempInFilePath
WipeFile(tempInFilePath)
end if
- --set RemailerInfoList to GetListFromFile(remailerFile)
if remailerFile is "" then
set remailerFile to (choose file with prompt ,
"Where is the file containing Remailer Info List")
try
set RemailerInfoList to GetListFromFile(remailerFile)
on error errStr number errNum
if errNum = -1700 then --means that remailerFile didn't exist.
Let's give the user a chance to find it
set remailerFile to (choose file with prompt ,
"Where is the file containing
Remailer Info List")
set RemailerInfoList to GetListFromFile(remailerFile)
else --some other error, just pass it on.
error errStr number errNum
end if
end try
else
set RemailerInfoList to GetListFromFile(remailerFile)
end if
(*
RecurseEncryptLink does the actual work. recurses on chainList (list
of remailers to chain through)
terminating when chainList is empty.
the original code is Richard Hodges, but I changed it from a loop, to
accomodate the MakeChain
code which doesn't actually exist yet. And changed lots of other
stuff too. -J.A.R.
*)
RecurseEncryptLink(chainList)
tell application "Eudora 5.1"
activate
copy theText to field named "" of theMessage
copy theRecipient to field named "To:" of theMessage
copy theCc to field named "Cc:" of theMessage
copy theSubject to field named "Subject:" of theMessage
set setting 84 to "n" --Eudora can start checking new mail again.
end tell
- --end of main program; functions follow
on DoEncrypt(theFile, Recipient)
set Recipient to commasplit(Recipient)
if length of Recipient = 0 then
return
end if
with timeout of 300 seconds
try
tell application "PGP7.03"
activate
encrypt (theFile) ,
to Recipient ,
signature omitted ,
reading plaintext ,
writing asciified
end tell
on error
tell application "PGP7.03"
open {} -- This is a
workaround to a bug in MacPGP
end tell
return
end try
end timeout
end DoEncrypt
on DoEncryptandSign(theFile, Recipient, theUser)
set Recipient to commasplit(Recipient)
if length of Recipient = 0 then
return
end if
-- code added by Richard Hodges
<email@hidden>
with timeout of 300 seconds
try
tell application "PGP7.03"
activate
encrypt (theFile) ,
to Recipient ,
user id theUser ,
signature included ,
reading plaintext ,
writing asciified
end tell
on error
tell application "PGP7.03"
open {} -- This is a workaround to a
bug in MacPGP
end tell
return
end try
end timeout
end DoEncryptandSign
on doSign(theFile, theUser)
with timeout of 300 seconds
try
tell application "PGP7.03"
activate
sign (theFile) ,
signature clear ,
user id theUser
end tell
on error
tell application "PGP7.03"
open {} -- This is a workaround to a
bug in MacPGP
end tell
return
end try
end timeout
end doSign
- -- Richard Hodges
- --turns off PGPs "recycle passwords", then turns it back on again, to
flush bad password.
on stopRecycle()
tell application "PGP7.03"
try
with timeout of 30 seconds -- some
applications won't respond to
Menu events
set menuListInfo to Query Menu List
end timeout
on error errorString number errorNumber
if errorNumber is -126 then -- dsMBarNFnd
error "Sorry, that program does not have a
menu bar. It may be background-only." number -126
else
error errorString number errorNumber
end if
end try
repeat with menuID from 1 to count of menuListInfo
if menu title of item menuID of menuListInfo
= "Options" then
set menuInfo to Query Menu menu ID menuID
repeat with menuItemID from 1 to
count of menuInfo
set menuItemInfo to item
menuItemID of menuInfo
if menu item enabled of
menuItemInfo then
if menu item text of
menuItemInfo = "Recycle Passwords" then
set
menuItemID to menu item ID of menuItemInfo
if menu item
mark of menuItemInfo is 18 then
Select Menu Item menu ID menuID menu item ID menuItemID
Select Menu Item menu ID menuID menu item ID menuItemID
end if
end if
end if
end repeat
end if
end repeat
end tell
end stopRecycle
- --modification of Richard Hodges' StopRecycle
- --returns true if MacPGPs "recycle passwords" option is on.
on MacPGPRecycling()
tell application "PGP7.03"
try
with timeout of 30 seconds -- some
applications won't respond to
Menu events
set menuListInfo to Query Menu List
end timeout
on error errorString number errorNumber
if errorNumber is -126 then -- dsMBarNFnd
error "Sorry, that program does not have a
menu bar. It may be background-only." number -126
else
error errorString number errorNumber
end if
end try
repeat with menuID from 1 to count of menuListInfo
if menu title of item menuID of menuListInfo
= "Options" then
set menuInfo to Query Menu menu ID menuID
repeat with menuItemID from 1 to
count of menuInfo
set menuItemInfo to item
menuItemID of menuInfo
if menu item enabled of
menuItemInfo then
if menu item text of
menuItemInfo = "Recycle Passwords" then
set
menuItemID to menu item ID of menuItemInfo
if menu item
mark of menuItemInfo is 18 then
return true
else
return false
end if
end if
end if
end repeat
end if
end repeat
end tell
end MacPGPRecycling
- -- Richard Hodges, modified by R.Lytle so that remailer addresses
with "_" do not cause errors
- -- Also, modified so that Remailer List file can use "?" in the
remailer feature description list
- -- the statement "compile regular expression" uses the Regular
Expression OSAXen. It is very
- -- similar to the UNIX "grep" command in its use of syntax, and is
used along with "match regular
- -- expression" to find character patterns within a text file
- -- regular expression establishes a pattern of: 1. (any character
except letters and numbers)
- -- over and over again up to (the word set by the variable
"remailer") 2. after that, (any
- --character except letters and numbers) over and over again up to (a
word containing letters,
- --numbers, "_", "@", and "-") i.e. the remailer address
- -- this is followed by any number of (words containing letters, ".",
and "?"), each of which can
- --be tested later to see if it is either "cpunk" or "pgp"
on getRemailerData(remailer)
global RemailerInfoList
set reRexp to compile regular expression "remailer[^a-zA-Z0-9]*" &
remailer & "[^a-zA-Z0-9]*([a-zA-Z0-9_.@-]*)..([a-z.? ]*)"
set matchResult to match regular expression reRexp to
RemailerInfoList
if matched of matchResult then
set remailerAddr to match 1 of matchResult
set remailerType to match 2 of matchResult
else
error "not a known remailer"
end if
return {remailerAddr, string2list(remailerType, " ")}
end getRemailerData
- --gets remailer info from file
on GetListFromFile(fileLocation)
set remailerList to (read (open for access fileLocation))
close access fileLocation
set l1 to offset of "$" in remailerList
set l2 to offset of "---" in remailerList
if l1 0 and l2 0 then
set remailerList to (characters l1 through (l2 - 1) of
remailerList) as text
else --the file doesn't look quite right. tell the user, and make
him choose a new file
set x to remailerFile
set remailerFile to "" --null remailerFile, cause it's invalid
display dialog ("The file" & return & "\"" & x as
string) & "\"" &
return & ,
"does not contain valid remailer info that I
recognize."
error -128
end if
return remailerList
end GetListFromFile
on WrapFile(theFile)
tell application "Drop*TextBreak"
open (theFile as string)
quit
end tell
end WrapFile
on WipeFile(theFile)
tell application "PGP7.03"
execute (("pgp -w \"" & theFile as string) & "\"")
open {} -- This is a workaround to a bug in MacPGP
end tell
end WipeFile
on commasplit(Recipient)
set rList to {}
repeat while (length of Recipient > 0)
set rLen to (length of Recipient)
set cLoc to (offset of "," in Recipient)
set qLoc to (offset of "\"" in Recipient)
if cLoc > 1 and (qLoc = 0 or qLoc > cLoc) then
-- comma comes before any quote: at least the
next name is
unquoted
copy rList & ,
((text of characters 1 thru (cLoc - 1) ,
of Recipient) as string) ,
to rList
else if qLoc > 1 and (cLoc = 0 or cLoc > qLoc) then
-- quote comes before comma: the next name
contains quotes
copy (characters 1 through qLoc of Recipient)
as text to nextId
copy (characters (qLoc + 1) through (length
of Recipient) of
Recipient) as text to Recipient
set qLoc to offset of "\"" in Recipient --
consume to closing
quote
copy nextId & (characters 1 through qLoc of
Recipient) to nextId
copy (characters (qLoc + 1) through (length
of Recipient) of
Recipient) as text to Recipient
set cLoc to offset of "," in Recipient -- and
consume out to comma
or end
if cLoc = 0 then
copy rList & (nextId & Recipient) to rList
set cLoc to (length of Recipient) + 1
else if cLoc = 1 then
copy rList & nextId to rList
else
copy rList & (nextId & (characters 1
through (cLoc - 1) of
Recipient)) to rList
end if
else
copy rList & Recipient to rList
set cLoc to (length of Recipient) + 1
end if
-- Now, advance cLoc through Recipient
set rLen to length of Recipient
repeat while ,
(cLoc > rLen and ,
(", " contains ,
(character cLoc of Recipient)))
set cLoc to cLoc + 1
end repeat
if (cLoc > rLen) then
copy ,
(text of characters cLoc ,
thru rLen ,
of Recipient) as string ,
to Recipient
else
set Recipient to ""
end if
end repeat
return rList
end commasplit
- --rochkind.-- made recursive function out of Richard Hodges loop
- -- chainList is the list of Remailers left to chain
on RecurseEncryptLink(chainList)
global theText, tempOutFilePath, tempInFilePath
global RemailerInfoList
global theCc, theSubject, theRecipient
global pathToDesktop
--chop off last item of chainlist, and store it in theRemailer
set theRemailer to item (length of chainList) of chainList
set chainList to (items 1 through ((length of chainList) - 1) of
chainList)
try
set {remailerAddr, remailerType} to
getRemailerData(theRemailer)
on error
display dialog ,
theRemailer & ,
" is not a known remailer." buttons
{"Cancel"} default button
"Cancel" with icon 0
error number -128
end try
--deal with subject and Cc headers.
if theCc "" or theSubject "" then
set theText to return & theText
if theCc "" then
set theText to "Cc: " & theCc & return & theText
set theCc to ""
end if
if theSubject "" then
set theText to "Subject: " & theSubject &
return & theText
end if
set theText to "##" & return & theText
set theCc to ""
set theSubject to ""
end if
if remailerType contains "cpunk" then
set thePreamble to "::" & return & "Request-Remailing-To: " &
theRecipient & return & return
else
display dialog theRemailer & " is not identified as
being cpunk." &
return & ,
,
"I only know how to deal with those
types of remailers." buttons
{"Cancel"} default button "Cancel" with icon 0
error number -128
end if
set theText to thePreamble & theText
OverWrite(theText, tempOutFilePath)
--figure out what to use as the keyID for pgp encryption
if remailerType contains "pgp" then
set keyID to remailerAddr
else if remailerType contains "pgp." then
set keyID to theRemailer
else
display dialog ,
"Sorry, " & theRemailer & ,
" doesn't support pgp, according to the info
I have. I can only
use remailers that support pgp encryption." buttons {"Cancel"}
default button "Cancel" with icon 0
error number -128
end if
DoEncrypt(tempOutFilePath, keyID)
-- Now wipe files and give the result back to
Eudora
WipeFile(tempOutFilePath) -- get rid of the plaintext temp file
try
open for access tempInFilePath -- read from the
ciphertext tempfile
and get rid of it
on error -- Bad passphrase most likely.
--tell application "MacPGP2.6ui1.2" to quit
activate
display dialog "PGP failed." buttons {"Cancel"} default button
"Cancel" with icon 0
error -128
end try
set theText to "::" & return & "Encrypted: PGP" & return & return &
(read tempInFilePath)
close access tempInFilePath
WipeFile(tempInFilePath)
set theRecipient to remailerAddr
if chainList is not {} then RecurseEncryptLink(chainList)
end RecurseEncryptLink
- --checks to see if theString is contains only numeric charectors.
rochkind
- --eventually, the script will generate a chain for you of length n,
but this not implemented yet
on isnumber(theString)
set answer to true
repeat with i from 1 to count of theString
set a to (ASCII number item i of theString)
if a < 48 or a > 57 then set answer to false
end repeat
return answer
end isnumber
- --put up a preferences dialog and save results in properties
- -rochkind
on dopreferences()
global dialogfile
set myresult to run dialog "Preferences" from dialogfile ,
edit texts {DefChain, DefSignFromUser} ,
checkboxes {BooleanToCheck(textwrap),
BooleanToCheck(TurnOffSig),
BooleanToCheck(DefEncryptTo), BooleanToCheck(DefSign)} ,
until {"OK", "Cancel"}
if item hit of myresult is "OK" then
set DefChain to item 1 of edit texts of myresult
set DefSignFromUser to item 2 of edit texts of myresult
set textwrap to (item 1 of checkboxes of myresult is checked)
set TurnOffSig to (item 2 of checkboxes of myresult is checked)
set DefEncryptTo to (item 3 of checkboxes of myresult
is checked)
set DefSign to (item 4 of checkboxes of myresult is checked)
end if
end dopreferences
- --changes true or false to checked or "" (should be to unchecked
instead of "", but there appears to be a bug in DialogRunner)
- --rochkind
on BooleanToCheck(x)
if x then
return checked
else
return ""
end if
end BooleanToCheck
- --displays remail dialog, returns list of results
on RemailDialog(theInitialRecipient)
global dialogfile
set myresult to run dialog "Remail" from dialogfile ,
edit texts {DefChain, theInitialRecipient as string,
DefSignFromUser, theInitialRecipient as string} ,
checkboxes {BooleanToCheck(DefEncryptTo),
BooleanToCheck(DefSign)}
,
until {"OK", "Cancel", "Preferences"}
if item hit of myresult is "Cancel" then
error number -128 --this is the "cancel" system error
code, it will
cleanly stop execution
else if item hit of myresult is "Preferences" then
dopreferences()
return RemailDialog(theInitialRecipient)
else
set chainList to item 1 of edit texts of myresult
set EncryptToUser to item 2 of edit texts of myresult
set SignFromUser to item 3 of edit texts of myresult
set theRecipient to item 4 of edit texts of myresult
set EncryptToRecipient to (item 1 of checkboxes of myresult is
checked)
set sign to (item 2 of checkboxes of myresult is checked)
if chainList is "" or theRecipient is "" then
display dialog ,
"You must specify a recipient and a
chain" buttons {"OK"} default
button "OK" with icon 0
return RemailDialog(theInitialRecipient)
end if
end if
return {chainList, EncryptToUser, SignFromUser, theRecipient,
EncryptToRecipient, sign}
end RemailDialog
- --input a string. Seperate the string along specified delimiters,
and return as applescript list
- --(delimiter charectors not included)
on string2list(theString, delimiter)
set newlist to {}
repeat until theString is ""
set x to offset of delimiter in theString
if x = 0 then
set newlist to newlist & theString
set theString to ""
else
set newlist to newlist & ((characters 1
through (x - 1) of
theString) as string)
set theString to ((characters (x + 1) through
(length of
theString) of theString) as string)
end if
end repeat
return newlist
end string2list
- --OverWrite will write theText to theFile. If theFile already
existed, the old one is trashed.
on OverWrite(theText, theFile)
try -- The create function is in the file i/o
scripting addition.
create file theFile
on error errMsg number errNum
if errNum = -48 then --file by that name already existed
WipeFile(theFile) --so delete it, and make a new one
create file theFile
else
error errMsg number errNum --if it wasn't a
"duplicate file name"
error, better pass it on
end if
end try
open for access theFile with write permission --now we know it
exists, and it's empty.
write theText to theFile --so, write theText to it
close access theFile
end OverWrite
- --return true if file exists, false if it doesn't
on FileExists(theFile)
try
open for access theFile
on error errStr number errNum
if errNum = -1700 then --the file doesn't exist
return false
else
error errStr number errNum --pass it on
end if
end try
close access theFile
return true
end FileExists
+++++++++++End Chainmail 1.0b2++++++++++++++++
This is the entire source. Yes the read me does indicate Mac PGP and
legacy keys. If I need to step down to MacPGP 2.6.x to use (which I
would rather not) - I will give it a shot...
-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <
http://www.pgp.com>
iQEVAwUBO7dWqBvtLiDCTH5jAQHqzgf7BNT0d5mU9915aMHOSlTmYkYIo+d9onqe
F5SM9UBSxGZPaX/8394bhwDzlKdfuSa8vmdGvRUG6/8Z110kSA2ndpMJoIjsoc9U
I0R9jxMznzx4ySBkb52w+uL3h1FKSmijcaWJVR7nMbR/i6XqHFWZisjrxqw6/1Hu
l7ymwwfoIrFZIcbWrnZae0M0EbK/DsLx5479llmAJ9CmpzmuYwMVcrQ1497hSTNl
rczLANWlYZatZdBeU//ToEJu/q4tschnxlvs6gj+TPuJvWTiaiJb+rnWd52jvBKV
TU+GHp3ENK+uzpbfey/herfsA2sEkENwQHEIN/SbQkcek3j/5byqTw==
=zQnc
-----END PGP SIGNATURE-----
--
Jeanne