Mercurial > cgi-bin > hgweb.cgi > PassMan
comparison src/main/kotlin/name/blackcap/passman/PasswordSubcommand.kt @ 15:0fc90892a3ae
Add password subcommand.
author | David Barts <n5jrn@me.com> |
---|---|
date | Fri, 03 Feb 2023 18:48:13 -0800 |
parents | |
children | ea65ab890f66 |
comparison
equal
deleted
inserted
replaced
14:4dae7a15ee48 | 15:0fc90892a3ae |
---|---|
1 package name.blackcap.passman | |
2 | |
3 import java.nio.file.Files | |
4 import java.nio.file.Path | |
5 import java.nio.file.StandardCopyOption | |
6 import kotlin.system.exitProcess | |
7 | |
8 class PasswordSubcommand : Subcommand() { | |
9 override fun run(args: Array<String>) { | |
10 // Parse arguments | |
11 if (args.size > 0 && (args[0] == "-h" || args[0].startsWith("--h"))) { | |
12 println("usage: passman password") | |
13 exitProcess(0) | |
14 } | |
15 if (!args.isEmpty()) { | |
16 die("unexpected arguments", 2) | |
17 } | |
18 | |
19 // Open databases | |
20 println("Changing database encryption key...") | |
21 val oldPath = Path.of(DB_FILE) | |
22 val oldDb = Database.open(fileName = DB_FILE, passwordPrompt = "Old database key: ") | |
23 val newPath = Path.of(NEW_DB_FILE) | |
24 if (Files.exists(newPath)) { | |
25 println("WARNING: deleting ${see(NEW_DB_FILE)}") | |
26 Files.delete(newPath) | |
27 } | |
28 val newDb = Database.open(fileName = NEW_DB_FILE, passwordPrompt = "New database key: ", create = true) | |
29 | |
30 // Copy old to new | |
31 println("WARNING: do not interrupt this process or data may be lost!") | |
32 copyRecords(oldDb, newDb) | |
33 | |
34 // Wrap up | |
35 oldDb.connection.close() | |
36 newDb.connection.close() | |
37 Files.move(newPath, oldPath, StandardCopyOption.REPLACE_EXISTING) | |
38 println("Database key changed.") | |
39 } | |
40 | |
41 private fun copyRecords(oldDb: Database, newDb: Database) { | |
42 oldDb.connection.prepareStatement("select name, username, password, notes, created, modified, accessed from passwords").use { old -> | |
43 val results = old.executeQuery() | |
44 while (results.next()) { | |
45 newDb.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created, modified, accessed) values (?, ?, ?, ?, ?, ?, ?, ?)").use { new -> | |
46 // id and name | |
47 val name = results.getDecryptedString(1, oldDb.encryption)!! | |
48 new.setLong(1, newDb.makeKey(name)) | |
49 new.setEncryptedString(2, name, newDb.encryption) | |
50 // username | |
51 new.setEncryptedString(3, | |
52 results.getDecryptedString(2, oldDb.encryption)!!, newDb.encryption) | |
53 // password | |
54 val password = results.getDecrypted(3, oldDb.encryption)!! | |
55 new.setEncrypted(4, password, newDb.encryption) | |
56 password.clear() | |
57 // notes | |
58 new.setEncryptedString(5, | |
59 results.getDecryptedString(4, oldDb.encryption), newDb.encryption) | |
60 // created, modified, accessed | |
61 new.setDateOrNull(6, results.getLong(5)) | |
62 new.setDateOrNull(7, results.getLong(6)) | |
63 new.setDateOrNull(8, results.getLong(7)) | |
64 new.executeUpdate() | |
65 } | |
66 } | |
67 } | |
68 } | |
69 } |