(no subject)

Aug 13, 2006 08:21

A major problem with my old LiveJournal scripts is that they store and transmit the user password in cleartext. You can get some local security by saving the script run-only, but this is annoying and the password is still sent scampering across the network nude. Well I spent some time today on the issue and this is what I've come up with:

click here to open this script in your editor
(* Checkfriends 13 Aug 2006 By Michael Henley http://silvermeteors.livejournal.com/
Please retain my credit, and notify me of any derivative works. Thanks.

HOW TO USE:
1. Change values of the two items noted under "Basic"
2. In your editor choose 'Save As'
3. For a PowerPC binary, select file type "Application." For a Universal Binary, select file type "Application Bundle"
4. Under options check 'Stay Open.' Leave the other options unchecked
5. Save the script
6. Double-click the script in Finder to run it *)

-- Basic:
property user_name : "silvermeteors" -- change this to your username
property interval : 5 * minutes -- how frequently you want to checkfriends (Note that LiveJournal can tell this script to increase its interval as necessary. The minimum is typically 2 * minutes)

-- Advanced:
property local_user : short user name of (system info) -- if you're using a different keychain, replace this with its name as "string" to ease your recompiles
property last_update : "" -- if you don't want this to persist between runs, revert it to blank in either the run or quit handlers
property pass_temp : missing value -- you may skip the run handler entirely if this is specified in plaintext

on run
set ditle to "Setup"
tell application "Keychain Scripting" to try
set key_title to "checkfriends"
set pass_temp to password of first generic key of keychain local_user whose name is key_title
on error
set key_sel to name of keychains
tell me
set pass_temp to text returned of (display dialog "A LiveJournal password for user " & quoted form of user_name & " was not found on keychain " & quoted form of local_user & return & return & "Please enter your LiveJournal password:" default answer "" with title ditle with hidden answer)
set pass_check to text returned of (display dialog "Please confirm the password:" default answer "" with title ditle with hidden answer)
if pass_check is not pass_temp then throw_error("The password does not match!")
set key_sel to (choose from list key_sel default items {local_user} with prompt "Select a keychain on which to store your password:" & return & return & "(Optional, default is " & quoted form of local_user & ")" with title ditle) as Unicode text
if key_sel is "false" then throw_error("The password was not saved!")
end tell
set local_user to key_sel
make new generic key at keychain local_user with properties {service:key_title, name:key_title, account:user_name, comment:"LiveJournal checkfriends client", password:pass_temp}
end try
set pass_temp to do shell script "/sbin/md5 -qs " & pass_temp
end run

on idle
check_friends()
end idle

to check_friends()
tell application "http://www.livejournal.com/interface/xmlrpc"
tell (call xmlrpc {method name:"LJ.XMLRPC.getchallenge"}) to set a_chal to it's challenge
tell me to set a_resp to do shell script "/sbin/md5 -qs " & (a_chal & pass_temp)
tell (call xmlrpc {method name:"LJ.XMLRPC.checkfriends", parameters:{{username:user_name, auth_method:"challenge", auth_challenge:a_chal, auth_response:a_resp, lastupdate:last_update}}})
if it's new is 1 then tell me to open location ("http://" & user_name & ".livejournal.com/friends/")
set last_update to it's lastupdate
tell it's interval to if it > interval then return it
end tell
return interval
end tell
end check_friends

to throw_error(x)
display dialog x buttons {"Quit"} default button 1
quit
error number -128
end throw_error

on quit
copy missing value to pass_temp
continue quit
end quit

This offers you a couple layers of decent security. Locally, the password is stored in your encrypted user keychain. This extends all of the features available to keychains such as locking, unlocking, timing, permissions, etc. The script manages its own key, so you don't have to touch keychain access.app if you don't want to.

When the password is retrieved from the keychain, it is encrypted with MD5 and concatenated to a random challenge generated by the LiveJournal server. This combo is then encrypted again and sent back. In this way the password is never actually sent across the network. All that is sent is a code that proves you know what the password is. Challenges expire every 60 seconds, so there is very little chance of a "replay" attack.

As for what the script above does, it is a simple friends page update checker. At the moment it is encumbered slightly by the problem of false positives caused by minor and restricted updates to your FL. My next step is to have it use Safari in the background to locate and highlight what's changed.
Previous post Next post
Up