Saturday, January 20, 2018

#1 2011-08-16 10:46:29 am

partron22
Member
Registered: 2011-03-18
Posts: 86

Scripting Keychain Access in Lion

Apple's "Keychain Scripting" application disappeared in the transition form Snow Leopard to Lion.
That left me without a viable method of fetching and setting passwords in my scripts.

Turns out Daniel Jalkut, of Red Sweater software has updated his keychain scripting App for Lion:
Usable Keychain Scripting For Lion
It's pretty nice stuff!

However, the shell-accessible 'security' command offers keychain access without relying on the installation of 3rd party software.
Security just needs a little Applescript interface, and my password requiring scripts will be securely back in action.

After playing around in Terminal and Keychain Access for a while, it became clear that Keychain Access and the security command use different vocabularies.
Specifically:
What Keychain Access calls a 'Name', the security utility calls a 'label' (-l is match label string)
What Keychain Access calls an 'Account', the security utility calls a 'name' (-a is "match account name string")
What Keychain Access calls 'Where', the security utility calls a 'service name' (-s is "match service name string")

Once that is sorted out, implementation of utility shell scripts is reasonably straightforward.
Here's a heavily commented Demo which can add a password item to the login keychain, find an item specified by its label, read its password etc., and delete an item specified by its label.
Additional functions list keychains, and allow for locking and unlocking of the default keychain.

The Demo is meant to be run repeatedly, while watching the contents of the login keychain in "Keychain Access".
The shell scripting functions may easily be pulled out of the script, modified and used as needed.
Consider them a starting point, not a finished product.

Included Functions:
AddPwrdItemToKeychain
GetPassword
GetAcctnameServicenameAndPwrdFromPwrdItem
DeletePwrdItemFromKeychain
LockDefaultKeychain
UnlockDefaultKeychain
ListKeychains


Applescript:

-- ShellScripting Keychains
-- BP Aug, 2011

-- Permits AppleScript access to keychain items through BSD's 'security' command.
-- Run this script to demonstrate its main functions.

-- If you'd rather use a separate App for scripting the keychain, try
-- [url]http://www.red-sweater.com/blog/2035/usable-keychain-scripting-for-lion[/url]

-----------------------------------------------------------------------------------------------------
(*
A little terminological clarification:
What Keychain Access calls a 'Name', the security utility calls a 'label' (-l is match label string)
What Keychain Access calls an 'Account', the security utility calls a 'name' (-a is "match account name string")
What Keychain Access calls 'Where', the security utility calls a 'service name' (-s is "match service name string")
*)

-----------------------------------------------------------------------------------------------------
set t to "" -- all purpose variable holds various types of data

tell application "Keychain Access" to activate -- Bring this up so as to see what's happening in the keychain.
tell application "AppleScript Editor" to activate

set label to "My New Keyitem" --e        -- if omitted, service name is used as default label
set KeyKind to "application password" --e unless new type is "Internet password", then --n
-- set KeyKind to "Internet password" --e -- here for testing internet password items
set AcctName to "Vladimir's Secret Cache" -- n
set ServiceName to "Boise Oblast dot com" --n
set Acctpassword to "tootyfruity232" --e
set AcctComments to "Chatty stuff of no import, except to the chatterer. Or someone could fill this space with a pointer to another keychain entry." --e
(*
Trying to add an item to the keychain twice usually results in an error (indicated by --e above).
Changing AcctName, ServiceName or KeyKind to "Internet password" produces a 2nd keychain item (indicated by --n above)..
The security add-XX-password command's -U (for update) option alters this behavior.
*)



set t to AddPwrdItemToKeychain(label, KeyKind, AcctName, ServiceName, Acctpassword, AcctComments) -- Add a new password item to the default keychain

-- set t to GetPassword(label, KeyKind) -- ********** If you just want a password, this line will do nicely **********

set t to GetAcctnameServicenameAndPwrdFromPwrdItem(label, KeyKind) -- Read and display data from that new password item

-- Show the results in a Dialog, and let user DELETE the keychain entry if desired.
set t2 to "Label: \t\t\t" & label & "\n" & "Account name: \t" & text item 1 of t & "\n" & "Password: \t\t" & text item 2 of t & "\n" & "Service name: \t" & text item 3 of t & "\n"
set dr to display dialog t2 buttons {"Delete Item", "OK"} default button 2 with title "Recovered Keychain Item Data"
if button returned of dr is equal to "Delete Item" then
   set t to DeletePwrdItemFromKeychain(label, KeyKind) -- Delete the newly added password item from the keychain.
end if

return t -- look to the result pane

-----
-----
on AddPwrdItemToKeychain(label, KeyKind, AcctName, ServiceName, Acctpassword, AcctComments)
   -- Make UNIX happy by quoting everything:
   set Qlabel to quoted form of label
   set QKeyKind to quoted form of KeyKind
   set QAcctName to quoted form of AcctName
   set QServiceName to quoted form of ServiceName -- or server if it's an internet password being created
   set QAcctpassword to quoted form of Acctpassword
   set QAcctComments to quoted form of AcctComments
   
   set retval to true
   
   -- Unless specified, new items are added to the default, usually login, keychain.
   -- add-generic-password [-h] [-a account] [-s service] [-w password] [options...] [keychain]
   -- add-internet-password [-h] [-a account] [-s server] [-w password] [options...] [keychain]
   try
       if KeyKind is equal to "Internet password" then
           set t to do shell script "security add-internet-password -a " & QAcctName & " -s " & QServiceName & " -w " & QAcctpassword & " -l " & Qlabel & " -j " & QAcctComments
       else
           set t to do shell script "security add-generic-password -a " & QAcctName & " -s " & QServiceName & " -w " & QAcctpassword & " -l " & Qlabel & " -j " & QAcctComments
       end if
   on error n --number n
       display dialog n buttons {"OK"} default button 1 with title "Key Creation Error" with icon caution -- error number 45 is keychain entry already exists.
       set retval to false
   end try
   return retval
end AddPwrdItemToKeychain

-----
-----
on GetAcctnameServicenameAndPwrdFromPwrdItem(label, KeyKind)
   set retarray to {"", "", ""}
   set Qlabel to quoted form of label
   set oldelim to text item delimiters
   
   try
       if KeyKind is equal to "Internet password" then
           set t to do shell script "security 2>&1 find-internet-password -gl " & Qlabel
       else
           set t to do shell script "security 2>&1 find-generic-password -gl " & Qlabel
       end if
       (*
        That odd 2>&1 redirects password output from stderr to stdout so we can get to it along with everything else.
        See Allan Odgaard's posting here:
        [url]http://blog.macromates.com/2006/keychain-access-from-shell/[/url]
        *)

       
       --display dialog t            -- Display raw data
       (*
           Output is messy, and needs to be parsed.
           grep and friends could work here.
           See [url]http://www.maclovin.de/2010/02/access-os-x-keychain-from-terminal/[/url]
           I'd rather use Applescript's text item delimiters here:
       *)

       set text item delimiters to "acct" -- Get Account name
       set tlst to every text item of t
       set acct to item 2 of tlst
       set text item delimiters to "\""
       set tlst to every text item of acct
       set acct to item 3 of tlst
       
       if KeyKind is equal to "Internet password" then -- Get Service name or Server
           set text item delimiters to "srvr" -- server
       else
           set text item delimiters to "svce" -- service
       end if
       set tlst to every text item of t
       set svcnam to item 2 of tlst
       set text item delimiters to "\""
       set tlst to every text item of svcnam
       set svcnam to item 3 of tlst
       
       set text item delimiters to "\"" -- Get Password
       set tlst to every text item of t
       set pw to item 2 of tlst
       --display dialog pw
       
       set retarray to {acct, pw, svcnam}
   on error
       display dialog "Sorry, can't find your keychain item." buttons "OK" default button 1 with icon caution
       set retarray to {"", "", ""}
   end try
   
   set text item delimiters to oldelim
   return retarray
end GetAcctnameServicenameAndPwrdFromPwrdItem
-----
-----
on DeletePwrdItemFromKeychain(label, KeyKind)
   set Qlabel to quoted form of label
   set retval to true
   
   try
       if KeyKind is equal to "Internet password" then
           set t to do shell script "security delete-internet-password -l " & Qlabel
       else
           set t to do shell script "security delete-generic-password -l " & Qlabel
       end if
   on error
       set retval to false
   end try
   
   return retval
end DeletePwrdItemFromKeychain
-----
-----
on LockDefaultKeychain()
   do shell script "security lock-keychain"
   
   -- This'll work too:
   -- do shell script "security lock-keychain login.keychain"    
end LockDefaultKeychain
-----
-----
on UnlockDefaultKeychain()
   -- KeychainAccess'll ask for password as needed, or I could hardcode it here.
   do shell script "security unlock-keychain"
end UnlockDefaultKeychain
-----
-----
on listKeychains()
   set t to do shell script "security list-keychains"
   display dialog t as text buttons "OK" default button 1 with title "Keychains List" -- Ugly but this is just a utility function
end listKeychains
-----
-----
on GetPassword(label, KeyKind)
   set Qlabel to quoted form of label
   (*
   I search keychains based on the desired item's label (ie what Keychain Access calls a name) here.
   An item's label appears to be its most unique identifier in a keychain. This is important because the find-XX-password
   command returns only the first matching instance.
   I could as easily search by other attributes, or combinations thereof:

-a account Match account string
-c creator Match creator (four-character code)
-C type Match type (four-character code)
-D kind Match kind string
-G value Match value string (generic attribute)
-j comment Match comment string
-l label Match label string
-s service Match service string
-g Display the password for the item found        -- from the man page
   
           For example: set pwrd to do shell script "security 2>&1 >/dev/null find-generic-password -gs " & 'Boise Oblast dot com'
   *)

   
   try
       if KeyKind is equal to "Internet password" then
           set pwrd to do shell script "security 2>&1 >/dev/null find-internet-password -gl " & Qlabel
       else
           set pwrd to do shell script "security 2>&1 >/dev/null find-generic-password -gl " & Qlabel
       end if
       (*
        That odd 2>&1 redirects password output from stderr to stdout so we can get to it.
        The >/dev/null redirects stdout, (everything except password) to nowhere.
        See Allan Odgaard's posting here:
        [url]http://blog.macromates.com/2006/keychain-access-from-shell/[/url]
        *)

   on error
       set pwrd to ""
   end try
   
   --display dialog pwrd -- Display raw data This'll be something like "password: tuttyfruity"    
   
   set oldelim to text item delimiters -- clean up the extra text.
   set text item delimiters to "\""
   set tlst to every text item of pwrd
   set pwrd to item 2 of tlst
   set text item delimiters to oldelim
   
   --display dialog pwrd -- Display cleaned up data This'll be something like "tuttyfruity"
   
   return pwrd
end GetPassword
-----
-----


Filed under: shell, Keychain, lion

Offline

 

#2 2011-08-17 01:42:58 pm

regulus6633
Member
From:: Taulov, Denmark
Registered: 2006-11-02
Posts: 1695
Website

Re: Scripting Keychain Access in Lion

Thanks for this. I posted a question about this recently here. I found that you could copy keychain scripting from 10.6 to 10.7 (also URL Access Scripting because that's missing too). However I like your solution better so I'll use this.

Offline

 

#3 2011-11-25 11:53:59 am

druido
Member
Registered: 2010-09-03
Posts: 96

Re: Scripting Keychain Access in Lion

I would like to add a few clarifications based on my experience (please correct me if something is wrong). I find that the security tool is not as well documented as it should be, so maybe my remarks can be helpful to others, too.

First of all, any password item in a keychain belongs essentially to one of two (completely distinct) types: a generic password or an internet password (there are other item types, of course, like certificates and keys, but here I am only interested in those items that allow you to store some sensitive information). In particular, a secure note is nothing more than a generic password (treated specially by Keychain.app, but not by the command-line tool).

Any generic password inside a keychain is uniquely determined by two values: the “account” and the “service” (this holds for secure notes, too, although typically—but not mandatorily—the account is the null value).

Any internet password inside a keychain is uniquely determined by three values: the “account”, the “server” and the “protocol”.

Note that the “label” needs not be unique inside a keychain. As far as I know, there is no direct way to let the security tool output all the items matching given criteria: security always reports at most one item. Hence, when there is more than one generic password or more than one internet password with the same label, security outputs only one of them.

I'll make an example. The following session assumes that an empty keychain called test.keychain has been created in the current directory.

First, let us create a generic password whose label coincides with the service (“My credit card number”):
[code]security add-generic-password -a john -s 'My credit card number' -p abc123def456 ./test.keychain[/code]
This is the same as choosing “New Password Item…” in Keychain.app, filling “Keychain Item Name” with the value of the -s option, “Account Name” with the value of the -a option and the password with the value of the -p option. Similarly, we may create a generic password for the same service and a different account:
[code]security add-generic-password -a bryan -s 'My credit card number' -p xyz789uvw345 ./test.keychain[/code]
Note that we have now two password items with the same label (“My credit card number”).

We may also assign a label which is different from the service:
[code]security add-generic-password -a john -s 'Shopping card' -l 'My credit card number' -p qwerty456 ./test.keychain[/code]
(Now we have three items with the same label). This cannot be done directly in Keychain.app: you must edit the item after creating it to change its name (as pointed out by the OP, -l corresponds to “Name”, -s to “Where” and -a to “Account”).

For internet passwords, things are a bit different, because you may have items that coincide on the account and the service, but differ on the protocol. For example,
[code]security add-internet-password -a john -s www.google.com ./test.keychain
security add-internet-password -a john -s www.google.com -r http ./test.keychain
security add-internet-password -a bryan -s www.google.com -r htps ./test.keychain
security add-internet-password -a bryan -s www.google.com -r 'ftp ' ./test.keychain[/code]
may all coexist. If John wants to retrieve his Google password, he may try one of:
[code]security find-internet-password -s www.google.com ./test.keychain
security find-internet-password -l www.google.com ./test.keychain[/code]
but he will get one (and only one) of the four items above. The correct way to retrieve a specific Internet password is by specifying all the three parameters:
[code]security find-internet-password -a john -s www.google.com -r https ./test.keychain[/code]
(note that this cannot be shortened by “-s https://www.google.com”).

I' have said that secure notes are just generic passwords. A secure note can be created as follows:
[code]security add-generic-password -C note -a "" -s 'My note' -p 'This is my secret. Ssst...' ./test.keychain[/code]
What makes this a secure note is the '-C note' option. The note can be retrieved as follows:
[code]security find-generic-password -a "" -s 'My note' ./test.keychain[/code]
Since secure notes created in Keychain.app have a null account, also this should work:
[code]security find-generic-password -s 'My note' ./test.keychain[/code]
Note, however, that the command line offers you the possibility of having notes with a non-empty account (which won't be visible in Keychain.app) and/or with a label which differs from the service. The latter is especially confusing, as Keychain.app will show the label, but the note will still be identified by the service. Try this:
[code]security add-generic-password -C note -a john -s 'My second note' -l 'My note' -p 'The secret goes here' ./test.keychain
security add-generic-password -C note -a bryan -s 'Yet another note' -l 'My note' -p 'This is top-secret' ./test.keychain[/code]
The above will all look as exactly the same note (with a different content) in Keychain.app. And
[code]security find-generic-password -l 'My note' ./test.keychain[/code]
will retrieve only one of them.

All in all, Keychain.app and security are pretty good tools, although there is some mismatch in their use. Given the considerations above, I would add to your code handlers to retrieve items by account/service and by account/server/protocol. Also,
[code]security unlock-keychain[/code]
should be
[code]security unlock-keychain -u[/code]
for the tool to prompt a password dialog.

Thanks for sharing this!


Filed under: b

Offline

 

#4 2011-11-26 09:23:52 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 4488

Re: Scripting Keychain Access in Lion

Thanks, partron22 and druido, for your posts. I have a Keychain Scripting script on my Tiger machine which reads a particular secure note like this:

Applescript:

on main()
   set pw to text returned of (display dialog "Enter your password" default answer "" with icon note)
   tell application "Keychain Scripting"
       tell keychain "My Keychain.keychain"
           unlock with password pw
           set stuff to password of first generic key whose name is "My note"
           lock
       end tell
   end tell
   display dialog stuff with icon note giving up after 5 * minutes
end main

main()

But it doesn't work on my Snow Leopard machine. (Not with my note, anyway. It does with the one-line note created by druido's script.) Instead, it throws an error saying there isn't enough memory to handle the generic key's 'password' property. If I change it to return the note's creation and modification dates instead, it returns totally unrelated dates from the next century!

Experimenting with the "security" code in your posts, I find the following:

• The '2>&1 >/dev/null' hack is definitely necessary for accessing the contents of the note.
• With a one-line note, the result from the shell script is in the form: "password: \"The line"\"".
• With a two-line note, the shell-script result format is: "password: 0x<hexadecimal string> \"First line\\012Second line\"". (Note the octal representation of a linefeed character.)
• With my note, the format is "password: 0x<hexadecimal string> \"<plist data containing a <NOTE> key whose value is the note text. The tabs and linefeeds are represented in octal>\"".
• Using a four-command shell script to unlock the keychain, get and store the note password, lock the keychain, and return the stored password has the effect of replacing the octal strings with the characters they represent, so AppleScript code isn't needed for this.

The Snow Leopard version of my script is thus:

Applescript:

on main()
   set pw to text returned of (display dialog "Enter your password" default answer "" with icon note)
   
   set keychain to quoted form of POSIX path of ((path to keychain folder as text) & "My Keychain.keychain")
   
   -- Unlock the keychain; store the password data from the note; lock the keychain; return the password data.
   set stuff to (do shell script "security unlock-keychain -p " & pw & " " & keychain & " ; a=$(security 2>&1 >/dev/null find-generic-password -s 'My note' -g " & keychain & ") ; security lock-keychain " & keychain & " ; echo $a")
   
   -- Extract the "quoted" part of the result.
   set astid to AppleScript's text item delimiters
   set text item delimiters to quote
   set stuff to text from text item 2 to text item -2 of stuff
   set text item delimiters to astid
   
   -- If the result's plist data, extract the note text from it.
   if (stuff begins with "<?xml version=") then
       tell application "System Events" to get value of (make new property list item with data stuff)
       set stuff to |note| of result
   end if
   
   display dialog stuff with icon note giving up after 5 * minutes
end main

main()

Last edited by Nigel Garvey (2011-11-26 09:26:08 am)


NG

Offline

 

#5 2011-11-26 12:03:43 pm

druido
Member
Registered: 2010-09-03
Posts: 96

Re: Scripting Keychain Access in Lion

Nigel Garvey wrote:

it throws an error saying there isn't enough memory to handle the generic key's 'password' property. If I change it to return the note's creation and modification dates instead, it returns totally unrelated dates from the next century!


Now we know why they've removed Keychain Scripting from Lion smile

Nigel Garvey wrote:

The '2>&1 >/dev/null' hack is definitely necessary for accessing the contents of the note.


Yes, the password (=the note's content) is sent to standard error by default.

• With a two-line note, the shell-script result format is: "password: 0x<hexadecimal string> \"First line\\012Second line\"". (Note the octal representation of a linefeed character.)


Any password (not only secure notes) that contains “unusual” or non-printable characters is returned as a hexadecimal string followed by a mixed ascii/octal representation.

Nigel Garvey wrote:

• Using a four-command shell script to unlock the keychain, get and store the note password, lock the keychain, and return the stored password has the effect of replacing the octal strings with the characters they represent, so AppleScript code isn't needed for this.


That's good smile I had not tried that.

I have to amend my previous post already: internet passwords are in fact fully identified by seven parameters: account (-a option), server (-s option), path (-p option), protocol (-r option), port (-P option), authentication type (-t option) and security domain (-d option), which some protocol requires for authentication.

Last edited by druido (2011-12-07 07:35:46 am)

Offline

 

#6 2012-07-09 06:35:31 pm

Schmye Bubbula
Member
Registered: 2003-11-23
Posts: 113

Re: Scripting Keychain Access in Lion

I tried partron22's script as-is in the first post, and when run it creates the sample Keychain entry correctly and displays the contents, but when I click the dialog's "Delete" button, it doesn't delete the entry. There were no error messages. For the life of me I can't figure out why not from inspecting the script. Any ideas why? Thanks!

- -
Edit: Tue, Jul 10, 2012, 12:42PM
I just had a friend try the post #1 script as-is, and he says that the Delete function works on his 10.7.4 system. So is this just a known Leopard thing? Is the security command set different for different versions of Mac OS X? I thought this was going to let me write scripts involving Keychain that would work with any version of Mac OS X, to expressly overcome the absence of the Keychain Scripting addition in Lion. Aaarrgghhh!

- -
Edit #2: Tue, Jul 10, 2012, 6:03PM
Oh, I see why I didn't get an error message; it's trapped in the on DeletePwrdItemFromKeychain(label, KeyKind) handler. A little troubleshooting reveals that it's error 1: "security: unknown command "delete-generic-password" — so it looks like different versions of Mac OS X may use different syntax for the security commands.

- -
Edit #3: Wed, Jul 18, 2012, 5:07PM
OK, I have a definitive answer now. After comparing the Mac OS X 10.5 vs. the 10.6/10.7 man pages for security, it turns out that commands exist only for deleting the whole keychain in 10.5, while the:

delete-generic-password
delete-internet-password


...commands don't exist in 10.5, but only in 10.6 and 10.7.

I guess with a little more trouble the same functionality could be attained in Leopard by deleting the whole keychain then recreating a new one of the same name containing all the other entries from temporarily stored values in AppleScript variables.


Model: MacBook Pro (5,2) "Mid-2009"
AppleScript: 2.0.1
Browser: Firefox 4.0.1
Operating System: Mac OS X (10.5.8)

Last edited by Schmye Bubbula (2012-07-18 03:07:30 pm)

Offline

 

#7 2014-02-02 07:56:03 pm

partron22
Member
Registered: 2011-03-18
Posts: 86

Re: Scripting Keychain Access in Lion

I just ran the code from post1 of this thread (lost my original) under Mavericks, and it created and set new keychain items nicely. It ran without changes under OS 10.9.1, 10.8.5, 10.7.5, and 10.6.8. Only trouble I noted was a tendency to leave Keychain access open when creating a new item under Snow Leopard and Lion.

Put together a bit of code to make those new keychain entries easily avalable from within Applescripts.
This code also runs without change under OS 10.9.1, 10.8.5, 10.7.5, and 10.6.8. as part of a Script app:

Applescript:

-- KeychainPasswordGetter.scpt
-- BP Feb 2014

-- Recovers info about a keychain item, including password
-- Easy to slip into new scripts.
-- You'll want to create your keychain iten before using this script

-- user settable variables
set keychainlabel to "ReStartupChooser-key" -- The name of the keychain item, in this case the Script App I've put this code in
set KeyKind to "application password" --e unless new type is "Internet password", then... --
-- end of user settable variables


set tem to GetAcctnameServicenameAndPwrdFromPwrdItem(keychainlabel, KeyKind) -- Read and display data from that new password item
set pw to item 2 of tem -- Glorious new code!
return pw

-----
-----
on GetAcctnameServicenameAndPwrdFromPwrdItem(label, KeyKind) -- This is straight from the Aug 2011 post
   set retarray to {"", "", ""}
   set Qlabel to quoted form of label
   set oldelim to text item delimiters
   
   try
       if KeyKind is equal to "Internet password" then
           set t to do shell script "security 2>&1 find-internet-password -gl " & Qlabel
       else
           set t to do shell script "security 2>&1 find-generic-password -gl " & Qlabel
       end if
       (*
        That odd 2>&1 redirects password output from stderr to stdout so we can get to it along with everything else.
        See Allan Odgaard's posting here:
        [url]http://blog.macromates.com/2006/keychain-access-from-shell/[/url]
        *)

       
       --display dialog t            -- Display raw data
       (*
           Output is messy, and needs to be parsed.
           grep and friends could work here.
           See [url]http://www.maclovin.de/2010/02/access-os-x-keychain-from-terminal/[/url]
           I'd rather use Applescript's text item delimiters here:
       *)

       set text item delimiters to "acct" -- Get Account name
       set tlst to every text item of t
       set acct to item 2 of tlst
       set text item delimiters to "\""
       set tlst to every text item of acct
       set acct to item 3 of tlst
       
       if KeyKind is equal to "Internet password" then -- Get Service name or Server
           set text item delimiters to "srvr" -- server
       else
           set text item delimiters to "svce" -- service
       end if
       set tlst to every text item of t
       set svcnam to item 2 of tlst
       set text item delimiters to "\""
       set tlst to every text item of svcnam
       set svcnam to item 3 of tlst
       
       set text item delimiters to "\"" -- Get Password
       set tlst to every text item of t
       set pw to item 2 of tlst
       --display dialog pw
       
       set retarray to {acct, pw, svcnam}
   on error
       display dialog "Sorry, can't find your keychain item." buttons "OK" default button 1 with icon caution
       set retarray to {"", "", ""}
   end try
   
   set text item delimiters to oldelim
   return retarray
end GetAcctnameServicenameAndPwrdFromPwrdItem
-----
-----

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)