pwman-tools

Hex Artifact Content
Login

Artifact 92003497491a81abb0ef4753135c7606a101f9b342ae71a608bc365948633601:


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")))).