Artifact 92003497491a81abb0ef4753135c7606a101f9b342ae71a608bc365948633601:
- Executable file
lastpass2pwman.lisp
— part of check-in
[1ead16f19c]
at
2013-02-03 21:42:51
on branch master
— Store secure notes in the "launch" field as it's 256 vs 64 char
And secure notes are likely to be longer. Since whole file is encrypted
anyway, doesn't matter which field you use to store things in. Saves
patching PWman to make the password field accept more chars.Add note to README regarding this known limitation. (user: atomicules@lavabit.com size: 3231)
0000: 3b 43 4c 69 73 70 20 73 63 72 69 70 74 20 66 6f ;CLisp script fo 0010: 72 20 53 42 43 4c 20 74 6f 20 63 6f 6e 76 65 72 r SBCL to conver 0020: 74 20 6c 61 73 74 70 61 73 73 20 43 53 56 20 65 t lastpass CSV e 0030: 78 70 6f 72 74 20 74 6f 20 50 57 6d 61 6e 20 66 xport to PWman f 0040: 6f 72 6d 61 74 0a 3b 53 65 65 20 52 45 41 44 4d ormat.;See READM 0050: 45 20 66 6f 72 20 75 73 61 67 65 20 69 6e 73 74 E for usage inst 0060: 72 75 63 74 69 6f 6e 73 0a 0a 3b 4c 6f 61 64 20 ructions..;Load 0070: 71 75 69 63 6b 6c 69 73 70 0a 28 6c 6f 61 64 20 quicklisp.(load 0080: 22 7e 2f 2e 73 62 63 6c 72 63 22 29 0a 3b 4c 6f "~/.sbclrc").;Lo 0090: 61 64 20 6c 69 62 72 61 72 69 65 73 0a 28 71 6c ad libraries.(ql 00a0: 3a 71 75 69 63 6b 6c 6f 61 64 20 22 63 73 76 2d :quickload "csv- 00b0: 70 61 72 73 65 72 22 29 0a 28 71 6c 3a 71 75 69 parser").(ql:qui 00c0: 63 6b 6c 6f 61 64 20 22 78 6d 6c 73 22 29 0a 0a ckload "xmls").. 00d0: 3b 4e 6f 74 65 20 74 6f 20 73 65 6c 66 3a 20 53 ;Note to self: S 00e0: 74 61 72 74 20 77 69 74 68 20 32 6e 64 20 2a 70 tart with 2nd *p 00f0: 6f 73 69 78 2d 61 72 67 76 2a 20 61 73 20 66 69 osix-argv* as fi 0100: 72 73 74 20 69 73 20 61 6c 77 61 79 73 20 2f 70 rst is always /p 0110: 61 74 68 2f 74 6f 2f 73 62 63 6c 2c 20 65 74 63 ath/to/sbcl, etc 0120: 0a 3b 67 70 67 69 64 20 74 6f 20 65 6e 63 72 79 .;gpgid to encry 0130: 70 74 20 66 69 6c 65 20 77 69 74 68 0a 28 64 65 pt file with.(de 0140: 66 70 61 72 61 6d 65 74 65 72 20 67 70 67 69 64 fparameter gpgid 0150: 20 28 73 65 63 6f 6e 64 20 2a 70 6f 73 69 78 2d (second *posix- 0160: 61 72 67 76 2a 29 29 0a 3b 43 68 65 63 6b 20 66 argv*)).;Check f 0170: 6f 72 20 73 75 70 70 6c 69 65 64 20 66 69 6c 65 or supplied file 0180: 6e 61 6d 65 2c 20 6f 74 68 65 72 77 69 73 65 20 name, otherwise 0190: 61 73 73 75 6d 65 20 63 61 6c 6c 65 64 20 6c 61 assume called la 01a0: 73 74 70 61 73 73 2e 63 73 76 0a 28 64 65 66 70 stpass.csv.(defp 01b0: 61 72 61 6d 65 74 65 72 20 69 6e 66 69 6c 65 20 arameter infile 01c0: 28 69 66 20 28 6e 75 6c 6c 20 28 74 68 69 72 64 (if (null (third 01d0: 20 2a 70 6f 73 69 78 2d 61 72 67 76 2a 29 29 20 *posix-argv*)) 01e0: 22 6c 61 73 74 70 61 73 73 2e 63 73 76 22 20 28 "lastpass.csv" ( 01f0: 74 68 69 72 64 20 2a 70 6f 73 69 78 2d 61 72 67 third *posix-arg 0200: 76 2a 29 29 29 0a 3b 72 65 61 64 20 74 68 65 20 v*))).;read the 0210: 6c 61 73 74 70 61 73 73 20 66 69 6c 65 20 61 6e lastpass file an 0220: 64 20 62 75 69 6c 64 20 75 70 20 68 61 73 68 20 d build up hash 0230: 66 6f 72 20 65 61 63 68 20 67 72 6f 75 70 0a 28 for each group.( 0240: 64 65 66 70 61 72 61 6d 65 74 65 72 20 2a 6c 61 defparameter *la 0250: 73 74 70 61 73 73 2a 20 28 6d 61 6b 65 2d 68 61 stpass* (make-ha 0260: 73 68 2d 74 61 62 6c 65 29 29 0a 28 63 73 76 2d sh-table)).(csv- 0270: 70 61 72 73 65 72 3a 6d 61 70 2d 63 73 76 2d 66 parser:map-csv-f 0280: 69 6c 65 20 69 6e 66 69 6c 65 0a 09 28 6c 61 6d ile infile..(lam 0290: 62 64 61 20 28 6c 6e 29 0a 09 09 28 69 66 20 28 bda (ln)...(if ( 02a0: 67 65 74 68 61 73 68 20 28 72 65 61 64 2d 66 72 gethash (read-fr 02b0: 6f 6d 2d 73 74 72 69 6e 67 20 28 73 75 62 73 74 om-string (subst 02c0: 69 74 75 74 65 20 23 5c 2d 20 23 5c 53 70 61 63 itute #\- #\Spac 02d0: 65 20 28 73 69 78 74 68 20 6c 6e 29 29 29 20 2a e (sixth ln))) * 02e0: 6c 61 73 74 70 61 73 73 2a 29 20 3b 47 72 6f 75 lastpass*) ;Grou 02f0: 70 0a 09 09 09 3b 4e 6f 74 65 2c 20 77 69 74 68 p....;Note, with 0300: 6f 75 74 20 28 69 6e 74 65 72 6e 20 28 73 74 72 out (intern (str 0310: 69 6e 67 2d 75 70 63 61 73 65 20 6f 72 20 28 72 ing-upcase or (r 0320: 65 61 64 2d 66 72 6f 6d 2d 73 74 72 69 6e 67 20 ead-from-string 0330: 6b 65 79 73 20 61 72 65 6e 27 74 20 73 65 74 20 keys aren't set 0340: 70 72 6f 70 65 72 6c 79 20 61 6e 64 20 73 6f 6d properly and som 0350: 65 74 68 69 6e 67 20 62 69 7a 61 72 72 65 20 68 ething bizarre h 0360: 61 70 70 65 6e 73 0a 09 09 09 28 73 65 74 66 0a appens....(setf. 0370: 09 09 09 09 28 67 65 74 68 61 73 68 20 28 72 65 ....(gethash (re 0380: 61 64 2d 66 72 6f 6d 2d 73 74 72 69 6e 67 20 28 ad-from-string ( 0390: 73 75 62 73 74 69 74 75 74 65 20 23 5c 2d 20 23 substitute #\- # 03a0: 5c 53 70 61 63 65 20 28 73 69 78 74 68 20 6c 6e \Space (sixth ln 03b0: 29 29 29 20 2a 6c 61 73 74 70 61 73 73 2a 29 0a ))) *lastpass*). 03c0: 09 09 09 09 28 61 70 70 65 6e 64 20 28 67 65 74 ....(append (get 03d0: 68 61 73 68 20 28 72 65 61 64 2d 66 72 6f 6d 2d hash (read-from- 03e0: 73 74 72 69 6e 67 20 28 73 75 62 73 74 69 74 75 string (substitu 03f0: 74 65 20 23 5c 2d 20 23 5c 53 70 61 63 65 20 28 te #\- #\Space ( 0400: 73 69 78 74 68 20 6c 6e 29 29 29 20 2a 6c 61 73 sixth ln))) *las 0410: 74 70 61 73 73 2a 29 20 28 6c 69 73 74 20 6c 6e tpass*) (list ln 0420: 29 29 29 20 3b 61 70 70 65 6e 64 20 6b 65 79 0a ))) ;append key. 0430: 09 09 09 28 73 65 74 66 0a 09 09 09 09 28 67 65 ...(setf.....(ge 0440: 74 68 61 73 68 20 28 72 65 61 64 2d 66 72 6f 6d thash (read-from 0450: 2d 73 74 72 69 6e 67 20 28 73 75 62 73 74 69 74 -string (substit 0460: 75 74 65 20 23 5c 2d 20 23 5c 53 70 61 63 65 20 ute #\- #\Space 0470: 28 73 69 78 74 68 20 6c 6e 29 29 29 20 2a 6c 61 (sixth ln))) *la 0480: 73 74 70 61 73 73 2a 29 0a 09 09 09 09 28 6c 69 stpass*).....(li 0490: 73 74 20 6c 6e 29 29 29 29 20 3a 73 6b 69 70 2d st ln)))) :skip- 04a0: 6c 69 6e 65 73 20 31 29 20 3b 63 72 65 61 74 65 lines 1) ;create 04b0: 20 6b 65 79 0a 3b 57 72 69 74 65 20 68 61 73 68 key.;Write hash 04c0: 20 6f 75 74 20 61 73 20 58 4d 4c 0a 28 77 69 74 out as XML.(wit 04d0: 68 2d 6f 70 65 6e 2d 66 69 6c 65 20 28 73 74 72 h-open-file (str 04e0: 65 61 6d 20 22 70 77 6d 61 6e 2e 74 78 74 22 20 eam "pwman.txt" 04f0: 3a 64 69 72 65 63 74 69 6f 6e 20 3a 6f 75 74 70 :direction :outp 0500: 75 74 20 3a 69 66 2d 65 78 69 73 74 73 20 3a 73 ut :if-exists :s 0510: 75 70 65 72 73 65 64 65 29 0a 09 28 66 6f 72 6d upersede)..(form 0520: 61 74 20 73 74 72 65 61 6d 20 22 3c 3f 78 6d 6c at stream "<?xml 0530: 20 76 65 72 73 69 6f 6e 3d 5c 22 31 2e 30 5c 22 version=\"1.0\" 0540: 3f 3e 3c 50 57 4d 61 6e 5f 50 61 73 73 77 6f 72 ?><PWMan_Passwor 0550: 64 4c 69 73 74 20 76 65 72 73 69 6f 6e 3d 5c 22 dList version=\" 0560: 33 5c 22 3e 3c 50 77 4c 69 73 74 20 6e 61 6d 65 3\"><PwList name 0570: 3d 5c 22 4d 61 69 6e 5c 22 3e 22 29 0a 09 3b 46 =\"Main\">")..;F 0580: 6f 72 20 65 61 63 68 20 6b 65 79 20 69 6e 20 68 or each key in h 0590: 61 73 68 0a 09 28 77 69 74 68 2d 68 61 73 68 2d ash..(with-hash- 05a0: 74 61 62 6c 65 2d 69 74 65 72 61 74 6f 72 20 28 table-iterator ( 05b0: 67 72 6f 75 70 20 2a 6c 61 73 74 70 61 73 73 2a group *lastpass* 05c0: 29 0a 09 09 28 6c 6f 6f 70 0a 09 09 09 28 6d 75 )...(loop....(mu 05d0: 6c 74 69 70 6c 65 2d 76 61 6c 75 65 2d 62 69 6e ltiple-value-bin 05e0: 64 20 28 72 65 74 75 72 6e 65 64 3f 20 67 72 6f d (returned? gro 05f0: 75 70 6e 61 6d 65 20 67 72 6f 75 70 65 6e 74 72 upname groupentr 0600: 69 65 73 29 20 28 67 72 6f 75 70 29 0a 09 09 09 ies) (group).... 0610: 28 69 66 20 72 65 74 75 72 6e 65 64 3f 0a 09 09 (if returned?... 0620: 09 09 28 70 72 6f 67 6e 0a 09 09 09 09 09 28 66 ..(progn......(f 0630: 6f 72 6d 61 74 20 73 74 72 65 61 6d 20 22 3c 50 ormat stream "<P 0640: 77 4c 69 73 74 20 6e 61 6d 65 3d 5c 22 7e 61 5c wList name=\"~a\ 0650: 22 3e 22 20 67 72 6f 75 70 6e 61 6d 65 29 0a 09 ">" groupname).. 0660: 09 09 09 09 3b 54 68 65 6e 20 6c 6f 6f 70 20 74 ....;Then loop t 0670: 68 72 6f 75 67 68 20 65 61 63 68 20 65 6e 74 72 hrough each entr 0680: 79 20 69 6e 20 67 72 6f 75 70 0a 09 09 09 09 09 y in group...... 0690: 28 6c 6f 6f 70 20 66 6f 72 20 65 6e 74 72 79 20 (loop for entry 06a0: 69 6e 20 67 72 6f 75 70 65 6e 74 72 69 65 73 0a in groupentries. 06b0: 09 09 09 09 09 09 64 6f 20 28 66 6f 72 6d 61 74 ......do (format 06c0: 20 73 74 72 65 61 6d 0a 09 09 09 09 09 09 09 22 stream........" 06d0: 3c 50 77 49 74 65 6d 3e 3c 6e 61 6d 65 3e 7e 61 <PwItem><name>~a 06e0: 3c 2f 6e 61 6d 65 3e 3c 68 6f 73 74 3e 7e 61 3c </name><host>~a< 06f0: 2f 68 6f 73 74 3e 3c 75 73 65 72 3e 7e 61 3c 2f /host><user>~a</ 0700: 75 73 65 72 3e 3c 70 61 73 73 77 64 3e 7e 61 3c user><passwd>~a< 0710: 2f 70 61 73 73 77 64 3e 3c 6c 61 75 6e 63 68 3e /passwd><launch> 0720: 7e 61 3c 2f 6c 61 75 6e 63 68 3e 3c 2f 50 77 49 ~a</launch></PwI 0730: 74 65 6d 3e 22 0a 09 09 09 09 09 09 09 28 78 6d tem>"........(xm 0740: 6c 73 3a 74 6f 78 6d 6c 20 28 66 69 66 74 68 20 ls:toxml (fifth 0750: 65 6e 74 72 79 29 29 0a 09 09 09 09 09 09 09 28 entry))........( 0760: 78 6d 6c 73 3a 74 6f 78 6d 6c 20 28 66 69 72 73 xmls:toxml (firs 0770: 74 20 65 6e 74 72 79 29 29 0a 09 09 09 09 09 09 t entry))....... 0780: 09 28 78 6d 6c 73 3a 74 6f 78 6d 6c 20 28 73 65 .(xmls:toxml (se 0790: 63 6f 6e 64 20 65 6e 74 72 79 29 29 0a 09 09 09 cond entry)).... 07a0: 09 09 09 09 28 69 66 20 28 6e 75 6c 6c 20 28 74 ....(if (null (t 07b0: 68 69 72 64 20 65 6e 74 72 79 29 29 20 3b 53 65 hird entry)) ;Se 07c0: 63 75 72 65 20 4e 6f 74 65 73 20 68 61 76 65 20 cure Notes have 07d0: 6e 6f 20 70 61 73 73 77 6f 72 64 0a 09 09 09 09 no password..... 07e0: 09 09 09 09 22 22 20 3b 70 75 74 20 6e 6f 74 68 ...."" ;put noth 07f0: 69 6e 67 20 69 6e 20 70 77 6d 61 6e 20 70 61 73 ing in pwman pas 0800: 73 77 6f 72 64 20 66 69 65 6c 64 20 69 66 20 53 sword field if S 0810: 65 63 75 72 65 20 4e 6f 74 65 0a 09 09 09 09 09 ecure Note...... 0820: 09 09 09 28 78 6d 6c 73 3a 74 6f 78 6d 6c 20 28 ...(xmls:toxml ( 0830: 74 68 69 72 64 20 65 6e 74 72 79 29 29 29 20 0a third entry))) . 0840: 09 09 09 09 09 09 09 28 69 66 20 28 6e 75 6c 6c .......(if (null 0850: 20 28 74 68 69 72 64 20 65 6e 74 72 79 29 29 20 (third entry)) 0860: 0a 09 09 09 09 09 09 09 09 28 78 6d 6c 73 3a 74 .........(xmls:t 0870: 6f 78 6d 6c 20 28 66 6f 75 72 74 68 20 65 6e 74 oxml (fourth ent 0880: 72 79 29 29 20 3b 55 73 65 20 6c 61 75 6e 63 68 ry)) ;Use launch 0890: 20 66 69 65 6c 64 20 66 6f 72 20 53 65 63 75 72 field for Secur 08a0: 65 20 4e 6f 74 65 73 20 61 73 20 69 74 20 69 73 e Notes as it is 08b0: 20 6c 6f 6e 67 65 72 0a 09 09 09 09 09 09 09 09 longer......... 08c0: 22 22 29 29 29 0a 09 09 09 09 09 28 66 6f 72 6d "")))......(form 08d0: 61 74 20 73 74 72 65 61 6d 20 22 3c 2f 50 77 4c at stream "</PwL 08e0: 69 73 74 3e 22 29 29 0a 09 09 09 09 28 72 65 74 ist>")).....(ret 08f0: 75 72 6e 29 29 29 29 29 0a 09 28 66 6f 72 6d 61 urn)))))..(forma 0900: 74 20 73 74 72 65 61 6d 20 22 3c 2f 50 77 4c 69 t stream "</PwLi 0910: 73 74 3e 3c 2f 50 57 4d 61 6e 5f 50 61 73 73 77 st></PWMan_Passw 0920: 6f 72 64 4c 69 73 74 3e 22 29 29 0a 3b 4d 6f 76 ordList>")).;Mov 0930: 65 20 6f 72 69 67 69 6e 61 6c 20 66 69 6c 65 20 e original file 0940: 74 6f 20 62 61 63 6b 75 70 0a 28 72 65 6e 61 6d to backup.(renam 0950: 65 2d 66 69 6c 65 20 28 63 6f 6e 63 61 74 65 6e e-file (concaten 0960: 61 74 65 20 27 73 74 72 69 6e 67 20 28 73 62 2d ate 'string (sb- 0970: 75 6e 69 78 3a 3a 70 6f 73 69 78 2d 67 65 74 65 unix::posix-gete 0980: 6e 76 20 22 48 4f 4d 45 22 29 20 22 2f 2e 70 77 nv "HOME") "/.pw 0990: 6d 61 6e 2e 64 62 22 29 20 28 63 6f 6e 63 61 74 man.db") (concat 09a0: 65 6e 61 74 65 20 27 73 74 72 69 6e 67 20 28 73 enate 'string (s 09b0: 62 2d 75 6e 69 78 3a 3a 70 6f 73 69 78 2d 67 65 b-unix::posix-ge 09c0: 74 65 6e 76 20 22 48 4f 4d 45 22 29 20 22 2f 2e tenv "HOME") "/. 09d0: 70 77 6d 61 6e 2e 64 62 2e 62 61 6b 22 29 29 0a pwman.db.bak")). 09e0: 3b 67 70 67 20 65 6e 63 72 70 79 74 20 74 68 65 ;gpg encrpyt the 09f0: 20 66 69 6c 65 0a 28 6c 65 74 20 28 28 70 72 6f file.(let ((pro 0a00: 63 20 28 73 62 2d 65 78 74 3a 72 75 6e 2d 70 72 c (sb-ext:run-pr 0a10: 6f 67 72 61 6d 20 22 67 70 67 22 20 28 6c 69 73 ogram "gpg" (lis 0a20: 74 20 22 2d 61 22 20 22 2d 72 22 20 67 70 67 69 t "-a" "-r" gpgi 0a30: 64 20 22 2d 6f 22 20 28 63 6f 6e 63 61 74 65 6e d "-o" (concaten 0a40: 61 74 65 20 27 73 74 72 69 6e 67 20 28 73 62 2d ate 'string (sb- 0a50: 75 6e 69 78 3a 3a 70 6f 73 69 78 2d 67 65 74 65 unix::posix-gete 0a60: 6e 76 20 22 48 4f 4d 45 22 29 20 22 2f 2e 70 77 nv "HOME") "/.pw 0a70: 6d 61 6e 2e 64 62 22 29 20 22 2d 65 22 20 22 70 man.db") "-e" "p 0a80: 77 6d 61 6e 2e 74 78 74 22 29 20 3a 73 65 61 72 wman.txt") :sear 0a90: 63 68 20 3a 65 6e 76 69 72 6f 6e 6d 65 6e 74 29 ch :environment) 0aa0: 29 29 0a 09 28 69 66 20 28 3d 20 30 20 28 73 62 ))..(if (= 0 (sb 0ab0: 2d 65 78 74 3a 70 72 6f 63 65 73 73 2d 65 78 69 -ext:process-exi 0ac0: 74 2d 63 6f 64 65 20 70 72 6f 63 29 29 0a 09 09 t-code proc))... 0ad0: 3b 49 66 20 74 68 61 74 20 77 61 73 20 73 75 63 ;If that was suc 0ae0: 63 65 73 73 66 75 6c 2c 20 74 68 65 6e 20 64 65 cessful, then de 0af0: 6c 65 74 65 20 74 68 65 20 75 6e 2d 65 6e 63 72 lete the un-encr 0b00: 79 70 74 65 64 20 66 69 6c 65 73 0a 09 09 28 70 ypted files...(p 0b10: 72 6f 67 6e 0a 09 09 09 28 64 65 6c 65 74 65 2d rogn....(delete- 0b20: 66 69 6c 65 20 69 6e 66 69 6c 65 29 0a 09 09 09 file infile).... 0b30: 28 64 65 6c 65 74 65 2d 66 69 6c 65 20 22 70 77 (delete-file "pw 0b40: 6d 61 6e 2e 74 78 74 22 29 29 0a 09 09 3b 49 66 man.txt"))...;If 0b50: 20 6e 6f 74 20 72 65 73 74 6f 72 65 20 62 61 63 not restore bac 0b60: 6b 75 70 20 61 6e 64 20 6c 65 61 76 65 20 70 6c kup and leave pl 0b70: 61 69 6e 20 74 65 78 74 20 66 69 6c 65 73 20 28 ain text files ( 0b80: 6f 74 68 65 72 77 69 73 65 20 77 69 6c 6c 20 66 otherwise will f 0b90: 61 69 6c 20 6e 65 78 74 20 74 69 6d 65 20 6f 6e ail next time on 0ba0: 20 61 62 6f 76 65 20 72 65 6e 61 6d 65 29 0a 09 above rename).. 0bb0: 09 28 70 72 6f 67 6e 0a 09 09 09 28 72 65 6e 61 .(progn....(rena 0bc0: 6d 65 2d 66 69 6c 65 20 28 63 6f 6e 63 61 74 65 me-file (concate 0bd0: 6e 61 74 65 20 27 73 74 72 69 6e 67 20 28 73 62 nate 'string (sb 0be0: 2d 75 6e 69 78 3a 3a 70 6f 73 69 78 2d 67 65 74 -unix::posix-get 0bf0: 65 6e 76 20 22 48 4f 4d 45 22 29 20 22 2f 2e 70 env "HOME") "/.p 0c00: 77 6d 61 6e 2e 64 62 2e 62 61 6b 22 29 20 28 63 wman.db.bak") (c 0c10: 6f 6e 63 61 74 65 6e 61 74 65 20 27 73 74 72 69 oncatenate 'stri 0c20: 6e 67 20 28 73 62 2d 75 6e 69 78 3a 3a 70 6f 73 ng (sb-unix::pos 0c30: 69 78 2d 67 65 74 65 6e 76 20 22 48 4f 4d 45 22 ix-getenv "HOME" 0c40: 29 20 22 2f 2e 70 77 6d 61 6e 2e 64 62 22 29 29 ) "/.pwman.db")) 0c50: 0a 09 09 09 28 70 72 69 6e 74 20 22 43 6f 75 6c ....(print "Coul 0c60: 64 6e 27 74 20 65 6e 63 72 79 70 74 20 66 69 6c dn't encrypt fil 0c70: 65 2c 20 70 6c 61 69 6e 20 74 65 78 74 20 66 69 e, plain text fi 0c80: 6c 65 73 20 68 61 76 65 20 6e 6f 74 20 62 65 65 les have not bee 0c90: 6e 20 64 65 6c 65 74 65 64 22 29 29 29 29 0a n deleted")))).