pwman-tools

Check-in [f2061c8df2]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:GPG encrypt the file and remove plain text files as part of the script

Since that is kind of the point of scripting and automation. Might as
well get the computer to do as much as possible of the task.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | master | trunk
Files: files | file ages | folders
SHA3-256: f2061c8df26b90994e420d0bb4d29be5b5a1d89ec58b383b826124aeb7bf2f60
User & Date: atomicules@lavabit.com 2012-09-03 08:17:49
Context
2012-12-10
09:40
Capitalise name. check-in: 35b06b14a8 user: atomicules@lavabit.com tags: master, trunk
2012-09-03
08:17
GPG encrypt the file and remove plain text files as part of the script

Since that is kind of the point of scripting and automation. Might as
well get the computer to do as much as possible of the task. check-in: f2061c8df2 user: atomicules@lavabit.com tags: master, trunk

2012-08-22
08:04
Skip first line of the CSV file (header)

Closes #1. check-in: 5b2827f458 user: atomicules@lavabit.com tags: master, trunk

Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to README.markdown.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#Lastpass2pwman

CLisp script to convert [Lastpass](https://lastpass.com) CSV export to [pwman](http://pwman.sourceforge.net) format.

Mainly done as a little learning exercise in Lisp for me, but also because I use Lastpass and also want to use a command line based password manager. Unfortunately there doesn't seem to be a command line client for Lastpass so I'm going to use pwman and every so often do a one way update of passwords.

## How to use

Developed and tested in SBCL. Use as follows

	sbcl --script /path/to/this/script </path/to/lastpass/export>

The path to the Lastpass export is optional. If not supplied assumes file is called "lastpass.csv" and is in current directory. Exports a file called "pwman.txt" to current directory. This is in plain text and so needs encoding via GPG: 

	gpg -r <yourgpgid@domain.com> -o ~/.pwman.db -e pwman.txt

This will encrypt the file and overwrite the pwman password database. Remember to delete the plain text files afterwards!


|







|

|
<
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13




#Lastpass2pwman

CLisp script for SBCL to convert [Lastpass](https://lastpass.com) CSV export to [pwman](http://pwman.sourceforge.net) format.

Mainly done as a little learning exercise in Lisp for me, but also because I use Lastpass and also want to use a command line based password manager. Unfortunately there doesn't seem to be a command line client for Lastpass so I'm going to use pwman and every so often do a one way update of passwords.

## How to use

Developed and tested in SBCL. Use as follows

	sbcl --script /path/to/this/script <gpg id used with pwman> </path/to/lastpass/export>

The path to the Lastpass export is optional. If not supplied assumes file is called "lastpass.csv" and is in current directory. The script works by first exporting a plain text file called "pwman.txt" to current directory, however, this is then immediately encrypted via GPG and replaces the `.pwman.db` file. Both plain text files (the Lastpass export and `pwman.txt`) are then deleted - unless an error occurs with the encryption, in which case the script notifies the user and leaves the files.




Changes to lastpass2pwman.lisp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25



26
27
28
29
30
31
32
33
34
35
36
37
38













;CLisp script to convert lastpass CSV export to pwman format
;Tested in SBCL. Use as follows
;
;	sbcl --script /path/to/this/script </path/to/lastpass/export>
;
;The path to the Lastpass export is optional. If not supplied assumes file is
;called "lastpass.csv" and is in current directory. Exports a file called
;"pwman.txt" to current directory. This is in plain text and so needs encoding 
;via GPG. 
;
;	gpg -r <yourgpgid@domain.com> -o ~/.pwman.db -e pwman.txt
;
;This will overwrite the pwman password database
;Remember to delete the plain text files afterwards!

;Load quicklisp
(load "~/.sbclrc")
;Load libraries
(ql:quickload "csv-parser")
(ql:quickload "xmls")

;Check for supplied filename, otherwise assume called lastpass.csv
;It's 2nd *posix-argv* as first is always /path/to/sbcl, etc.

(defparameter infile (if (null (second *posix-argv*)) "lastpass.csv" (second *posix-argv*)))




(with-open-file (stream "pwman.txt" :direction :output :if-exists :supersede)
	(format stream "<?xml version=\"1.0\"?><PWMan_PasswordList version=\"3\"><PwList name=\"Main\">")
	(csv-parser:map-csv-file infile 
		(lambda (ln)
			(format stream
				"<PwItem><name>~a</name><host>~a</host><user>~a</user><passwd>~a</passwd><launch></launch></PwItem>"
				(xmls:toxml (fifth ln))
				(xmls:toxml (first ln))
				(xmls:toxml (second ln))
				(if (null (third ln)) ;Secure Notes have no password 
					(xmls:toxml (fourth ln)) ;Use extra field if Secure Note
					(xmls:toxml (third ln))))) :skip-lines 1)
	(format stream "</PwList></PWMan_PasswordList>"))













|
|
<
<
<
<
<
<
<
<
<
<
<
<







<
|
>
|
<
>
>
>













>
>
>
>
>
>
>
>
>
>
>
>
>
1
2












3
4
5
6
7
8
9

10
11
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
;CLisp script for SBCL to convert lastpass CSV export to pwman format
;See README for usage instructions













;Load quicklisp
(load "~/.sbclrc")
;Load libraries
(ql:quickload "csv-parser")
(ql:quickload "xmls")


;Note to self: Start with 2nd *posix-argv* as first is always /path/to/sbcl, etc.
;gpgid to encrypt file with
(defparameter gpgid (second *posix-argv*))

;Check for supplied filename, otherwise assume called lastpass.csv
(defparameter infile (if (null (third *posix-argv*)) "lastpass.csv" (third *posix-argv*)))
;read the lastpass file and convert to PWman format
(with-open-file (stream "pwman.txt" :direction :output :if-exists :supersede)
	(format stream "<?xml version=\"1.0\"?><PWMan_PasswordList version=\"3\"><PwList name=\"Main\">")
	(csv-parser:map-csv-file infile 
		(lambda (ln)
			(format stream
				"<PwItem><name>~a</name><host>~a</host><user>~a</user><passwd>~a</passwd><launch></launch></PwItem>"
				(xmls:toxml (fifth ln))
				(xmls:toxml (first ln))
				(xmls:toxml (second ln))
				(if (null (third ln)) ;Secure Notes have no password 
					(xmls:toxml (fourth ln)) ;Use extra field if Secure Note
					(xmls:toxml (third ln))))) :skip-lines 1)
	(format stream "</PwList></PWMan_PasswordList>"))
;Move original file to backup
(rename-file (concatenate 'string (sb-unix::posix-getenv "HOME") "/.pwman.db") (concatenate 'string (sb-unix::posix-getenv "HOME") "/.pwman.db.bak")) 
;gpg encrpyt the file
(let ((proc (sb-ext:run-program "gpg" (list "-r" gpgid "-o" (concatenate 'string (sb-unix::posix-getenv "HOME") "/.pwman.db") "-e" "pwman.txt") :search :environment)))
	(if (= 0 (sb-ext:process-exit-code proc))
		;If that was successful, then delete the un-encrypted files
		(progn 
			(delete-file infile) 
			(delete-file "pwman.txt"))
		;If not restore backup and leave plain text files (otherwise will fail next time on above rename)
		(progn
			(rename-file (concatenate 'string (sb-unix::posix-getenv "HOME") "/.pwman.db.bak") (concatenate 'string (sb-unix::posix-getenv "HOME") "/.pwman.db")) 
			(print "Couldn't encrypt file, plain text files have not been deleted"))))