13 Replies Latest reply: Jan 13, 2011 10:04 AM by baltwo
lucapost Level 1 Level 1 (0 points)
I'm trying to run the script to export keychain items described in:

http://discussions.apple.com/thread.jspa?messageID=12224599&#12224599

it seems to run fine but aborts with a '+Keychain Scripting got an error: There is not enough memory available to use the specified item. number -25301+' error about half-way through my 183 keychain entries.

I tried to modify the script (see below) and have it open the output file first and append single entries to it on each iteration but this returns
+Can’t get application \"Macintosh HD:System:Library:ScriptingAdditions:Keychain Scripting.app:\"." number -1728 from application "Macintosh HD:System:Library:ScriptingAdditions:Keychain Scripting.app:+



set osXKeychainScriptingPath to ¬
"Macintosh HD:System:Library:ScriptingAdditions:Keychain Scripting.app:" -- one line
set theSecuridPIN to {}



tell application "Keychain Scripting" to launch
tell application "Keychain Access" to launch

tell application "Finder"
open for access file (((path to desktop folder) as text) & "Passwords") with write permission
set theFile to result


using terms from application "Keychain Scripting"
tell application osXKeychainScriptingPath

set KeyList to every key of current keychain
repeat with aKey in KeyList
set theSecuridPIN to ((name of aKey) & tab & ¬
(account of aKey) & tab & (password of aKey) & tab & (comment of aKey) & tab & (description of aKey) & return) as text

write theSecuridPIN to theFile starting at eof
log (name of aKey) as text

end repeat
end tell
end using terms from

close access theFile
end tell

tell application "Keychain Scripting" to quit
tell application "Keychain Access" to quit

macbook pro, Mac OS X (10.6.5)
  • baltwo Level 9 Level 9 (61,900 points)
    Since it's my script and it works w/Snow Leopard, post the details WRT to your computer's disk space: capacity (under the colored circle), utilized, and free. Launch Activity Monitor in Utilities folder and select Disk Usage.
  • red_menace Level 6 Level 6 (14,760 points)
    Note that you should really put the keychain access statements in a handler, since +global variables+ (which include those in a run handler) +are saved with the script+ when run outside of the *Script Editor* and can be easily viewed with a hex dump of the file (and don't forget to secure delete all those test files!).

    You can also just use *Keychain Scripting* directly instead of that using terms from stuff.
  • baltwo Level 9 Level 9 (61,900 points)
    I think I originally tried it w/o the using terms from stuff, but ran into issues. Too long ago for my waning memory to remember exactly. There's really no sense changing things, since the manual clicking of allow buttons on each keychain called requires patience. FWIW, once I get the text file, I edit it extensively and pop it into an encrypted disk image for security purposes. Allows me to mount the image, open the file, and have it readily at hand for username & password access. It's a backup incase the keychain or memory goes south.
  • red_menace Level 6 Level 6 (14,760 points)
    I use something similar, although it uses local handler variables that don't get saved with the script. Kind of defeats the purpose of a keychain if someone can just look at the script file to get the passwords (unless you lock up the script, too).

    <pre style="
    font-family: Monaco, 'Courier New', Courier, monospace;
    font-size: 10px;
    font-weight: normal;
    margin: 0px;
    padding: 5px;
    border: 1px solid #000000;
    width: 720px; height: 340px;
    color: #000000;
    background-color: #FFCE75;
    overflow: auto;"
    title="this text can be pasted into the AppleScript Editor">
    -- write keychain information to a text file


    property spacer : tab & tab -- some dividing text
    property theKeychain : "login.keychain" -- the name of the keychain


    on run
    -- set theKeychain to text returned of (display dialog "Keychain to use?" default answer theKeychain)
    getKeyInfo for theKeychain -- use handler(s) to avoid persistant global variables!
    end run


    to getKeyInfo for theKeychain
    (*
    get a list of names, accounts, and passwords for keys in the specified keychain
    parameters - theKeychain [text]: the name of the keychain to use
    returns nothing
    *)
    tell (current date) as «class isot» as string to set theDate to text 1 thru 10 & space & text 12 thru -1
    set keyInfo to {return & "Keychain information from " & (quoted form of theKeychain) & space & theDate & " - " & return}

    tell application id "com.apple.KeychainScripting" -- get key info (same as application "Keychain Scripting")
    try
    set current keychain to first item of (get keychains whose name is theKeychain)
    unlock current keychain

    set the end of keyInfo to return & "generic keys: " & return
    repeat with aKey in (get every generic key of current keychain)
    tell aKey to set the end of keyInfo to (name & spacer & account & spacer & password & return)
    end repeat

    set the end of keyInfo to return & "Internet keys: " & return
    repeat with aKey in (get every Internet key of current keychain)
    tell aKey to set the end of keyInfo to (name & spacer & account & spacer & password & return)
    end repeat

    set the end of keyInfo to return & "AppleShare keys: " & return
    repeat with aKey in (get every AppleShare key of current keychain)
    tell aKey to set the end of keyInfo to (name & spacer & account & spacer & password & return)
    end repeat

    on error errmess
    log errmess
    end try
    quit
    end tell

    writeResults for (return & (keyInfo as text)) into ¬
    (choose file name with prompt "Save passwords to:" default name "Passwords.text" default location (path to desktop))

    end getKeyInfo


    to writeResults for whatever into aTextFile
    (*
    write some results to a text file
    parameters - whatever [text]: something to write
    aTextFile [various]: the text file to write to (POSIX or Finder)
    returns[boolean]: true if successful, false if not
    *)
    set aTextFile to aTextFile as text
    if aTextFile begins with "/" then set aTextFile to aTextFile as POSIX file as text -- POSIX
    try
    set theOpenFile to (open for access file aTextFile with write permission)
    write (whatever as text) to theOpenFile starting at eof -- append
    close access theOpenFile
    return true -- success
    on error errmess
    log errmess
    try
    close access theOpenFile
    end try
    end try
    return false
    end writeResults
    </pre>
  • baltwo Level 9 Level 9 (61,900 points)
    Thanks. I'll give it a look-see.
  • lucapost Level 1 Level 1 (0 points)
    still not getting it; how can the disk space be the issue?
    I have over 380 GBs free anyhow.. and over 2 GB of free System Memory

    The script by red_menace aborts with a "«script» doesn’t understand the writeResults message." but commenting out the writeResults statement the same memory issue as before actually surfaces.

    I do keep these into a secure disk image!

    -ciao
  • baltwo Level 9 Level 9 (61,900 points)
    A google search for *error 25301* indicates that it's a loader issue if you're running mySql. That's all I can offer, since it works here and I haven't tested red_menace's script.
  • red_menace Level 6 Level 6 (14,760 points)
    It isn't a disk space issue, but something *Keychain Scripting* is having a problem with. Have you run first aid from the *Keychain Access* application?

    The writeResults line (make sure it is one single line) is a call to a handler that writes the results to a text file. If you are getting to that point in the script, the keychain keys have all been read, although if there was an error some may have been skipped - check the AppleScript Editor log results for any errors. If this is a result of some particular key that has gone amok, I can modify the script so that just individual errors are skipped (hmmm, I might do that anyway).
  • baltwo Level 9 Level 9 (61,900 points)
    If you do, post the updated script.
  • lucapost Level 1 Level 1 (0 points)
    I did run First Aid.

    Commenting out the 3 iterations one-by-one and watching the Events-log I find that:

    the generic keys loop exits with the 'There is not enough memory ...' error
    the internet keys and the Appleshare ones don't.

    in all cases execution ends with the '«script» doesn’t understand the writeResults message'.
    The 'save as' dialog window appears, the error is generated when the 'save' in it gets clicked, changing the name and location of the output file in the dialog does not have any effect.

    where is the 'writeresults' handler actually defined ? I don't see it mentioned in the code anywhere before the line where it gets called!
  • red_menace Level 6 Level 6 (14,760 points)
    I have the different key types separated so that a particular type can be removed - I guess that came in handy. The writeResults handler is at the end of the script, immediately after the getKeyInfo handler (don't forget to scroll down to the end of the script).

    The following updated script traps errors for every key read (for you too, baltwo), - if there is an error, that particular key will be skipped (hopefully there isn't an error in just getting the key):

    <pre style="
    font-family: Monaco, 'Courier New', Courier, monospace;
    font-size: 10px;
    font-weight: normal;
    margin: 0px;
    padding: 5px;
    border: 1px solid #000000;
    width: 720px; height: 340px;
    color: #000000;
    background-color: #FFCE75;
    overflow: auto;"
    title="this text can be pasted into the AppleScript Editor">
    -- write keychain information to a text file


    property spacer : tab & tab -- some dividing text
    property theKeychain : "login.keychain" -- the name of the keychain


    on run
    -- set theKeychain to text returned of (display dialog "Keychain to use?" default answer theKeychain)
    getKeyInfo for theKeychain -- use handler(s) to avoid persistant global variables!
    end run


    to getKeyInfo for theKeychain
    (*
    get a list of names, accounts, and passwords for keys in the specified keychain
    parameters - theKeychain [text]: the name of the keychain to use
    returns nothing
    *)
    try
    tell application id "com.apple.KeychainScripting" -- get key info (same as application "Keychain Scripting")
    set current keychain to first item of (get keychains whose name is theKeychain)
    unlock current keychain
    end tell
    on error errorMessage number errorNumber -- error getting the keychain
    tell application id "com.apple.KeychainScripting" to quit
    tell me to activate
    display alert "There was an error in getting keychain " & quoted form of theKeychain message "(" & errorNumber & ") - " & errorMessage
    error number -128 -- cancel
    end try

    tell (current date) as «class isot» as string to set theDate to text 1 thru 10 & space & text 12 thru -1
    set keyInfo to {return & "Keychain information from " & (quoted form of theKeychain) & space & theDate & " - " & return}
    set {errorCount, thePrompt} to {0, ""}

    tell application id "com.apple.KeychainScripting"
    set the end of keyInfo to return & "generic keys: " & return
    repeat with aKey in (get every generic key of current keychain)
    try
    tell aKey to set the end of keyInfo to (name & spacer & account & spacer & password & return)
    on error errmess
    log errmess
    set errorCount to errorCount + 1
    end try
    end repeat

    set the end of keyInfo to return & "Internet keys: " & return
    repeat with aKey in (get every Internet key of current keychain)
    try
    tell aKey to set the end of keyInfo to (name & spacer & account & spacer & password & return)
    on error errmess
    log errmess
    set errorCount to errorCount + 1
    end try
    end repeat

    set the end of keyInfo to return & "AppleShare keys: " & return
    repeat with aKey in (get every AppleShare key of current keychain)
    try
    tell aKey to set the end of keyInfo to (name & spacer & account & spacer & password & return)
    on error errmess
    log errmess
    set errorCount to errorCount + 1
    end try
    end repeat
    quit
    end tell

    if errorCount is not 0 then
    if errorCount is 1 then
    set thePrompt to "One key was skipped."
    else
    set thePrompt to "There were " & errorCount & " keys skipped."
    end if
    tell me to activate
    display alert "There was an error while getting passwords from " & quoted form of theKeychain message thePrompt buttons {"Cancel", "OK"} cancel button "Cancel"
    end if
    set thePrompt to thePrompt & "  Save read keychain passwords to:"

    set theLocation to (choose file name with prompt thePrompt default name "Passwords.text" default location (path to desktop))
    writeResults for (return & (keyInfo as text)) into theLocation
    end getKeyInfo


    to writeResults for whatever into aTextFile
    (*
    write some results to a text file
    parameters - whatever [text]: something to write
    aTextFile [various]: the text file to write to (POSIX or Finder)
    returns [boolean]: true if successful, false if not
    *)
    set aTextFile to aTextFile as text
    if aTextFile begins with "/" then set aTextFile to aTextFile as POSIX file as text -- POSIX
    try
    set theOpenFile to (open for access file aTextFile with write permission)
    write (whatever as text) to theOpenFile starting at eof -- append
    close access theOpenFile
    return true -- success
    on error errmess
    log errmess
    try
    close access theOpenFile
    end try
    end try
    return false
    end writeResults</pre>

    It would be nice if the new discussions allow the use of a Script Editor URL link...
  • lucapost Level 1 Level 1 (0 points)
    wow OK, I just did not see nor copy the below-the-fold code (ehmm..)

    It just works now (fine) !

    Ciao Thanks**3
  • baltwo Level 9 Level 9 (61,900 points)
    Thanks. I'll check it out; too busy doing other stuff.