| 1 | .\" -*-nroff-*- |
| 2 | .\" |
| 3 | .\" Describe the password safe |
| 4 | .\" |
| 5 | .\" (c) 2016 Straylight/Edgeware |
| 6 | .\" |
| 7 | . |
| 8 | .\"----- Licensing notice --------------------------------------------------- |
| 9 | .\" |
| 10 | .\" This file is part of the Python interface to Catacomb. |
| 11 | .\" |
| 12 | .\" Catacomb/Python is free software; you can redistribute it and/or modify |
| 13 | .\" it under the terms of the GNU General Public License as published by |
| 14 | .\" the Free Software Foundation; either version 2 of the License, or |
| 15 | .\" (at your option) any later version. |
| 16 | .\" |
| 17 | .\" Catacomb/Python is distributed in the hope that it will be useful, |
| 18 | .\" but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 | .\" GNU General Public License for more details. |
| 21 | .\" |
| 22 | .\" You should have received a copy of the GNU General Public License |
| 23 | .\" along with Catacomb/Python; if not, write to the Free Software Foundation, |
| 24 | .\" Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 25 | . |
| 26 | .ie t \{\ |
| 27 | . if \n(.g \{\ |
| 28 | . fam P |
| 29 | . \} |
| 30 | . ds o \(bu |
| 31 | .\} |
| 32 | .el \{\ |
| 33 | . ds o o |
| 34 | .\} |
| 35 | . |
| 36 | .de hP |
| 37 | .IP |
| 38 | \h'-\w'\fB\\$1\ \fP'u'\fB\\$1\ \fP\c |
| 39 | .. |
| 40 | . |
| 41 | .TH pwsafe 1 "13 May 2016" "Straylight/Edgeware" "Catacomb cryptographic library" |
| 42 | .SH NAME |
| 43 | pwsafe \- store passwords somewhat securely |
| 44 | . |
| 45 | .\"-------------------------------------------------------------------------- |
| 46 | .SH SYNOPSIS |
| 47 | . |
| 48 | .B pwsafe |
| 49 | .RB [ \-f |
| 50 | .IR file ] |
| 51 | .I command |
| 52 | .RI [ arguments |
| 53 | \&...] |
| 54 | .PP |
| 55 | Subcommands: |
| 56 | 'RS |
| 57 | .B changepp |
| 58 | .br |
| 59 | .B copy |
| 60 | .I dest-file |
| 61 | .RI [ glob-pattern ] |
| 62 | .br |
| 63 | .B create |
| 64 | .RB [ \-c |
| 65 | .IR cipher ] |
| 66 | .RB [ \-d |
| 67 | .IR db-type ] |
| 68 | .RB [ \-h |
| 69 | .IR hash ] |
| 70 | .RB [ \-m |
| 71 | .IR mac ] |
| 72 | .RI [ pp-tag ] |
| 73 | .br |
| 74 | .B delete |
| 75 | .I tag |
| 76 | .br |
| 77 | .RB [ find ] |
| 78 | .I label |
| 79 | .br |
| 80 | .B list |
| 81 | .RI [ glob-pattern ] |
| 82 | .br |
| 83 | .B store |
| 84 | .I label |
| 85 | .RI [ value ] |
| 86 | .br |
| 87 | .B to-pixie |
| 88 | .RI [ label |
| 89 | .RI [ pixie-tag ]] |
| 90 | .br |
| 91 | .B xfer |
| 92 | .RB [ \-d |
| 93 | .IR db-type ] |
| 94 | .I dest-file |
| 95 | .RE |
| 96 | . |
| 97 | .\"-------------------------------------------------------------------------- |
| 98 | .SH DESCRIPTION |
| 99 | . |
| 100 | The |
| 101 | .B pwsafe |
| 102 | command maintains a database of passwords |
| 103 | or other short-ish textual secrets. |
| 104 | Each password is identified by a |
| 105 | .IR label . |
| 106 | The database is ultimately protected by a master password. |
| 107 | It should quite difficult for an adversary |
| 108 | who has the database file(s) |
| 109 | but not your master password |
| 110 | to find out what any of the stored passwords are, |
| 111 | or even what the labels are. |
| 112 | .PP |
| 113 | The |
| 114 | .B pwsafe |
| 115 | program will prompt you for the password as necessary. |
| 116 | If you are running the Catacomb |
| 117 | .BR pixie (1) |
| 118 | then it will first ask the pixie for any necessary passwords, |
| 119 | and use the pixie to remember the master password for a short while. |
| 120 | .PP |
| 121 | A number of database backends are available. |
| 122 | .TP |
| 123 | .B gdbm |
| 124 | Uses the GDBM database library to store a database as a single file. |
| 125 | Provided for compatibility; |
| 126 | not recommended for new databases. |
| 127 | .TP |
| 128 | .B sqlite |
| 129 | Uses the SQLite3 library to store a database as a single file. |
| 130 | SQLite3 has good performance and integrity properties. |
| 131 | .TP |
| 132 | .B flat |
| 133 | Stores the password database as a flat text file. |
| 134 | Not recommended for large databases because performance will be bad, |
| 135 | but the simple format admits easy hacking. |
| 136 | .TP |
| 137 | .B dir |
| 138 | Stores the password database as a directory structure. |
| 139 | This uses much more disk space than the alternatives, |
| 140 | and enumerating passwords is slow, |
| 141 | but the directory structure can easily be managed by |
| 142 | a version control system such as Git. |
| 143 | .PP |
| 144 | The following command-line options are available. |
| 145 | .TP |
| 146 | .B "\-h, \-\-help" |
| 147 | Print a help summary to standard output, |
| 148 | and exit with status zero. |
| 149 | .TP |
| 150 | .B "\-v, \-\-version" |
| 151 | Print the program's version number to standard output, |
| 152 | and exit with status zero. |
| 153 | .TP |
| 154 | .B "\-u, \-\-usage" |
| 155 | Print a very terse usage summary to standard output, |
| 156 | and exit with status zero. |
| 157 | .TP |
| 158 | .BI "\-f, \-\-file=" file |
| 159 | Use |
| 160 | .I file |
| 161 | as the password database file or directory. |
| 162 | If this is not specified, |
| 163 | then the value of the |
| 164 | .B PWSAFE |
| 165 | environment variable is used; |
| 166 | if that too is unset, then the default |
| 167 | .IB home /.pwsafe \fR, |
| 168 | is used, where |
| 169 | .I home |
| 170 | is the value of the |
| 171 | .B HOME |
| 172 | environment variable. |
| 173 | It is a fatal error if |
| 174 | .B HOME |
| 175 | is unset. |
| 176 | .PP |
| 177 | The provided commands are described in their own sections below. |
| 178 | . |
| 179 | .SS "create" |
| 180 | Create a new, empty password database. |
| 181 | As a safety check, |
| 182 | the file/directory named by the top-level |
| 183 | .B \-f |
| 184 | option (or default value) |
| 185 | must not exist. |
| 186 | .PP |
| 187 | You will be prompted (twice) for a master password for the database. |
| 188 | .PP |
| 189 | The optional positional argument is the tag |
| 190 | by which the database's master password |
| 191 | will be known to the passphrase pixie. |
| 192 | The default tag is |
| 193 | .BR pwsafe . |
| 194 | .PP |
| 195 | The following options are accepted. |
| 196 | .TP |
| 197 | .BI "\-c, \-\-cipher=" cipher |
| 198 | Use the Catacomb |
| 199 | .I cipher |
| 200 | to encrypt blobs. |
| 201 | Run |
| 202 | .B catcrypt show cipher |
| 203 | for a list. |
| 204 | The default is |
| 205 | .BR rijndael-cbc . |
| 206 | .TP |
| 207 | .BI "\-d, \-\-database=" db-type |
| 208 | Use the |
| 209 | .I db-type |
| 210 | database backend. |
| 211 | See above for a list of the supported backends. |
| 212 | Note that |
| 213 | .B gdbm |
| 214 | and |
| 215 | .B sqlite |
| 216 | depend on external modules, and may not be available. |
| 217 | The default is |
| 218 | .BR flat . |
| 219 | .TP |
| 220 | .BI "\-h, \-\-hash=" hash |
| 221 | Use the Catacomb |
| 222 | .I hash |
| 223 | for key derivation and password-label mangling. |
| 224 | Run |
| 225 | .B catcrypt show hash |
| 226 | for a list. |
| 227 | The default is |
| 228 | .BR sha256 . |
| 229 | .TP |
| 230 | .BI "\-m, \-\-mac=" mac |
| 231 | Use the Catacomb |
| 232 | .I mac |
| 233 | to protect the integrity of blobs. |
| 234 | Run |
| 235 | .B catcrypt show mac |
| 236 | for a list. |
| 237 | The default is |
| 238 | .IR hash -hmac |
| 239 | where |
| 240 | .I hash |
| 241 | is the hash function chosen by the |
| 242 | .B \-h |
| 243 | option. |
| 244 | . |
| 245 | .SS "changepp" |
| 246 | Change the master password for a database. |
| 247 | This will |
| 248 | .I not |
| 249 | re-encrypt all of the records, |
| 250 | so its utility is somewhat limited. |
| 251 | See also the |
| 252 | .B copy |
| 253 | command. |
| 254 | The program will prompt you for |
| 255 | the existing master password (if it's not known by the pixie) |
| 256 | and the new one (twice, always). |
| 257 | . |
| 258 | .SS "copy" |
| 259 | Copy password records from the |
| 260 | .I file |
| 261 | to the |
| 262 | .I dest-file |
| 263 | which must be an existing password database. |
| 264 | If a |
| 265 | .B glob-pattern |
| 266 | is given, |
| 267 | then only records whose |
| 268 | .I label |
| 269 | matches the pattern are copied; |
| 270 | otherwise all password records are copied. |
| 271 | Any existing passwords in the destination database with the same labels |
| 272 | will be overwritten. |
| 273 | .PP |
| 274 | The destination need not use the same database backend |
| 275 | or cryptographic parameters as the source. |
| 276 | .PP |
| 277 | You will be prompted for the necessary master passwords. |
| 278 | . |
| 279 | .SS "delete" |
| 280 | Delete the password with the given |
| 281 | .I label |
| 282 | from the database. |
| 283 | An error is reported if there is no such password. |
| 284 | .PP |
| 285 | You will be prompted for master password if necessary. |
| 286 | . |
| 287 | .SS "find" |
| 288 | Write the password with the given label to standard output, |
| 289 | followed by a newline. |
| 290 | .PP |
| 291 | You will be prompted for master password if necessary. |
| 292 | .PP |
| 293 | This is the default operation: |
| 294 | as a convenience, |
| 295 | you can write |
| 296 | .IP |
| 297 | .B pwsafe |
| 298 | .I label |
| 299 | .PP |
| 300 | rather than |
| 301 | .IP |
| 302 | .B pwsafe |
| 303 | .B find |
| 304 | .I label |
| 305 | .PP |
| 306 | if the |
| 307 | .I label |
| 308 | isn't the same as any of |
| 309 | .BR pwsafe 's |
| 310 | command names. |
| 311 | . |
| 312 | .SS "list" |
| 313 | Write the labels of the passwords in the database, |
| 314 | one per line, |
| 315 | to standard output. |
| 316 | (If labels contain newline characters, |
| 317 | you will end up with a mess.) |
| 318 | If a |
| 319 | .I glob-pattern |
| 320 | is supplied, |
| 321 | then only labels which match the pattern are written. |
| 322 | .PP |
| 323 | You will be prompted for master password if necessary. |
| 324 | . |
| 325 | .SS "store" |
| 326 | Store a password, associating it with the given |
| 327 | .IR label . |
| 328 | .PP |
| 329 | If a |
| 330 | .I value |
| 331 | is supplied on the command line, |
| 332 | then it is used as the password value. |
| 333 | (Note that command-line arguments can be seen |
| 334 | by other users of the system, |
| 335 | and may be recorded by the shell. |
| 336 | This is usually a bad idea.) |
| 337 | .PP |
| 338 | As a special case, if the |
| 339 | .I value |
| 340 | is |
| 341 | .BR \- , |
| 342 | then the password is read from the first line of standard input; |
| 343 | the trailing newline is removed. |
| 344 | The author commonly writes |
| 345 | .IP |
| 346 | .BI "gorp -fbase64 | pwsafe store " label " \-" |
| 347 | .PP |
| 348 | to set random passwords. |
| 349 | .PP |
| 350 | Finally, if no |
| 351 | .I value |
| 352 | is given, |
| 353 | then |
| 354 | .B pwsafe |
| 355 | will prompt twice for the password. |
| 356 | .PP |
| 357 | You will be prompted for the master password if necessary |
| 358 | .I before |
| 359 | the new password value is fetched. |
| 360 | .PP |
| 361 | If there is an existing password with the same |
| 362 | .I label |
| 363 | then it is overwritten. |
| 364 | . |
| 365 | .SS "topixie" |
| 366 | With no arguments, |
| 367 | store |
| 368 | .I all |
| 369 | of the passwords in the database in the pixie, |
| 370 | with correspondingly named tags. |
| 371 | This is probably a bad idea. |
| 372 | .PP |
| 373 | With a |
| 374 | .IR label , |
| 375 | store only the labelled password in the pixie. |
| 376 | With a |
| 377 | .IR pixie-tag , |
| 378 | use that as the tag; |
| 379 | otherwise use the |
| 380 | .IR label . |
| 381 | .PP |
| 382 | You will be prompted for the master password if necessary. |
| 383 | . |
| 384 | .SS "xfer" |
| 385 | Create a new database containing all of the records of an existing one. |
| 386 | .PP |
| 387 | This works at the storage-backend level. |
| 388 | The new database contains exactly the same metadata and passwords |
| 389 | as the original. |
| 390 | It is |
| 391 | .I not |
| 392 | necessary to enter a password: |
| 393 | the blobs are simply copied over without being decrypted. |
| 394 | .PP |
| 395 | The following options are accepted. |
| 396 | .TP |
| 397 | .BI "\-d, \-\-database=" db-type |
| 398 | Use the |
| 399 | .I db-type |
| 400 | database backend. |
| 401 | See above for a list of the supported backends. |
| 402 | Note that |
| 403 | .B gdbm |
| 404 | and |
| 405 | .B sqlite |
| 406 | depend on external modules, and may not be available. |
| 407 | The default is |
| 408 | .BR flat . |
| 409 | . |
| 410 | .\"-------------------------------------------------------------------------- |
| 411 | .SH TECHNICAL DETAILS |
| 412 | . |
| 413 | The password database contains two kinds of records: |
| 414 | .I metadata records |
| 415 | hold important information about the database itself, |
| 416 | and particularly the various cryptographic options |
| 417 | chosen when the database was created, |
| 418 | and the various internal keys used to secure the database; |
| 419 | while |
| 420 | .I password records |
| 421 | actually store your encrypted passwords. |
| 422 | The various backends store these kinds records in different ways; |
| 423 | see below for the gory details. |
| 424 | . |
| 425 | .SS Metadata |
| 426 | The metadata records are as follows. |
| 427 | .TP |
| 428 | .B cipher |
| 429 | The symmetric cipher used to encrypt data. |
| 430 | This names a Catacomb |
| 431 | .B cipher |
| 432 | class. |
| 433 | .TP |
| 434 | .B hash |
| 435 | The hash function used in various places. |
| 436 | This names a Catacomb |
| 437 | .B hash |
| 438 | class. |
| 439 | .TP |
| 440 | .B key |
| 441 | A blob, |
| 442 | protected by the |
| 443 | .I derived |
| 444 | keys (see below), |
| 445 | containing the |
| 446 | .I main |
| 447 | secrecy and integrity keys. |
| 448 | The blob payload consists of the main secrecy and integrity keys, |
| 449 | each prefixed by its 16-bit length (in network byte order) |
| 450 | and concatenated. |
| 451 | .TP |
| 452 | .B mac |
| 453 | The message authentication code used to protect integrity. |
| 454 | This names a Catacomb |
| 455 | .B mac |
| 456 | class. |
| 457 | .TP |
| 458 | .B magic |
| 459 | A blob containing a string |
| 460 | used to construct the database keys for password records; |
| 461 | see below. |
| 462 | The magic string is chosen at random |
| 463 | when the database is created, |
| 464 | and never changes; |
| 465 | it is the same length as the chosen hash function's output. |
| 466 | The blob is protected by the |
| 467 | .I main |
| 468 | keys. |
| 469 | .TP |
| 470 | .B salt |
| 471 | A random string |
| 472 | mixed into the key derivation process. |
| 473 | .TP |
| 474 | .B tag |
| 475 | The passphrase tag, |
| 476 | used to identify the master password |
| 477 | to the passphrase |
| 478 | .BR pixie (1). |
| 479 | . |
| 480 | .SS Keys |
| 481 | The following keys are used. |
| 482 | .TP |
| 483 | The \fImaster password\fP |
| 484 | Remembered (hopefully) by the user; |
| 485 | used to unlock the |
| 486 | .I main |
| 487 | keys. |
| 488 | .TP |
| 489 | The \fIderived\fP keys |
| 490 | A secrecy and integrity pair, |
| 491 | derived from the |
| 492 | .I master password |
| 493 | and |
| 494 | salt using a hash function. |
| 495 | .TP |
| 496 | The \fImain\fP keys |
| 497 | A secrecy and integrity pair, |
| 498 | kept in a blob in the database |
| 499 | (the |
| 500 | .B key |
| 501 | metadata item) |
| 502 | protected by the |
| 503 | .I derived |
| 504 | keys. |
| 505 | The main keys are generated at random |
| 506 | when the database is created |
| 507 | and they never change; |
| 508 | the Catacomb default key lengths are used. |
| 509 | . |
| 510 | .SS Deriving keys from the master password |
| 511 | The keys used for protecting the |
| 512 | .I main |
| 513 | secrecy and integrity keys |
| 514 | are derived by hashing strings of the form |
| 515 | .IB purpose : password \e0 salt \fR, |
| 516 | where |
| 517 | .I purpose |
| 518 | is |
| 519 | .B cipher |
| 520 | or |
| 521 | .B mac |
| 522 | to derive the secrecy and integrity keys, respectively. |
| 523 | The |
| 524 | .I salt |
| 525 | string is the value of the |
| 526 | .B salt |
| 527 | metadata item described below. |
| 528 | .PP |
| 529 | No attempt is made to make the key derivation slow; |
| 530 | .B pwsafe |
| 531 | takes the view that you are have been specifically targetted for attack |
| 532 | by a well-resourced adversary, |
| 533 | and that you |
| 534 | .I will |
| 535 | lose if your password is guessable. |
| 536 | . |
| 537 | .SS Making a blob |
| 538 | A |
| 539 | .I blob |
| 540 | contains a |
| 541 | .IR payload , |
| 542 | protecting its secrecy and integrity. |
| 543 | A blob is constructed using a pair of secrecy and integrity keys; |
| 544 | most blobs are protected with the |
| 545 | .I main |
| 546 | keys; |
| 547 | the main keys themselves are protected with the |
| 548 | .I derived |
| 549 | keys. |
| 550 | .PP |
| 551 | The steps to construct a blob are as follows. |
| 552 | .hP 1. |
| 553 | Choose a random IV of the appropriate length for the chosen |
| 554 | .BR cipher . |
| 555 | .hP 2. |
| 556 | Encrypt the blob payload |
| 557 | using the chosen |
| 558 | .B cipher |
| 559 | with the secrecy key |
| 560 | and the IV from step 1, |
| 561 | to form a ciphertext. |
| 562 | Prefix the ciphertext with the IV |
| 563 | to form an augmented ciphertext. |
| 564 | .hP 3. |
| 565 | Compute a tag over the augmented ciphertext from step 2 |
| 566 | using the chosen |
| 567 | .B mac |
| 568 | with the integrity key. |
| 569 | Prefix the augmented ciphertext with the tag |
| 570 | to form the blob. |
| 571 | .PP |
| 572 | (It seems more usual to put the tag on the end of the ciphertext, |
| 573 | but that turned out to be pointlessly harder to implement.) |
| 574 | . |
| 575 | .SS Password records |
| 576 | Conceptually, |
| 577 | password records are indexed with a textual |
| 578 | .I label |
| 579 | chosen by the user. |
| 580 | But users may want to not only keep their passwords secret, |
| 581 | but also information about |
| 582 | .I which |
| 583 | passwords they have. |
| 584 | The |
| 585 | .B pwsafe |
| 586 | program attempts to maintain the privacy of password record labels, |
| 587 | but it isn't completely successful, as we shall see. |
| 588 | Most critically, |
| 589 | the database backends tend to leak information about |
| 590 | the |
| 591 | .I order |
| 592 | in which records were added into the database. |
| 593 | .PP |
| 594 | At the database backend, |
| 595 | the key used for looking up a password record is a hash, |
| 596 | in binary: |
| 597 | specifically, it's a hash of |
| 598 | the record label |
| 599 | prefixed by the |
| 600 | .I magic |
| 601 | string which is the payload of the blob stored in the |
| 602 | .B magic |
| 603 | metadata record. |
| 604 | .PP |
| 605 | The value of the password record is a blob, |
| 606 | protected by the |
| 607 | .I main |
| 608 | keys, |
| 609 | whose payload consists of |
| 610 | .hP \*o |
| 611 | the 16-bit network-byte-order length of the record label; |
| 612 | .hP \*o |
| 613 | the record label itself; |
| 614 | .hP \*o |
| 615 | the 16-bit network-byte-order length of the password; |
| 616 | .hP \*o |
| 617 | the password itself; and |
| 618 | .hP \*o |
| 619 | zero or more zero-valued octets, |
| 620 | so as to make the payload a multiple of 256 octets long. |
| 621 | .PP |
| 622 | The padding serves to conceal the length of the label and password |
| 623 | from an adversary who has obtained a copy of the database. |
| 624 | . |
| 625 | .SS Backend formats |
| 626 | The various password-database backends |
| 627 | represent the records described above as follows. |
| 628 | .TP |
| 629 | .B gdbm |
| 630 | A GDBM-backed database is stored in a single file. |
| 631 | A metadata record with key |
| 632 | .I r |
| 633 | and value |
| 634 | .I v |
| 635 | is stored in a GDBM record also named |
| 636 | .IR r , |
| 637 | and with value |
| 638 | .I v ; |
| 639 | a password record with hash |
| 640 | .I h |
| 641 | and blob |
| 642 | .I b |
| 643 | is stored in a GDBM record named |
| 644 | .BI $ h |
| 645 | with value |
| 646 | .IR b , |
| 647 | both in raw binary. |
| 648 | .TP |
| 649 | .B sqlite |
| 650 | A SQLite-backed database is stored in a single file. |
| 651 | It contains two tables, |
| 652 | named |
| 653 | .B meta |
| 654 | and |
| 655 | .BR passwd . |
| 656 | The |
| 657 | .B meta |
| 658 | table has a primary key |
| 659 | .B name |
| 660 | and a further column |
| 661 | .BR value ; |
| 662 | a metadata record with key |
| 663 | .I r |
| 664 | and value |
| 665 | .I v |
| 666 | is held in a |
| 667 | .B meta |
| 668 | record |
| 669 | with |
| 670 | .B name |
| 671 | .I r |
| 672 | and |
| 673 | .B value |
| 674 | .IR v ; |
| 675 | additionally, there is a record with |
| 676 | .B name |
| 677 | .B $version |
| 678 | whose |
| 679 | .B value |
| 680 | is the schema version; |
| 681 | this is currently always 0. |
| 682 | The |
| 683 | .B passwd |
| 684 | table has a primary key |
| 685 | .B label |
| 686 | and a further column |
| 687 | .BR payload ; |
| 688 | a password record with hash |
| 689 | .I h |
| 690 | and blob |
| 691 | .I b |
| 692 | is stored in a |
| 693 | .B passwd |
| 694 | record with |
| 695 | .B label |
| 696 | .IR h |
| 697 | and |
| 698 | .B payload |
| 699 | .IR b , |
| 700 | both in raw binary. |
| 701 | .TP |
| 702 | .B flat |
| 703 | A flat-file-backed database is stored in a single file, |
| 704 | with one record per line. |
| 705 | The first line must be exactly |
| 706 | .RS |
| 707 | .IP |
| 708 | .B "### pwsafe password database" |
| 709 | .PP |
| 710 | Blank lines and lines beginning with a |
| 711 | .RB ` # ' |
| 712 | are ignored. |
| 713 | .PP |
| 714 | A metadata record named |
| 715 | .I r |
| 716 | with value |
| 717 | .I v |
| 718 | is stored as a line of the form |
| 719 | .IB r\fR\(fm = v\fR\(fm |
| 720 | where |
| 721 | .IR r \fR\(fm |
| 722 | and |
| 723 | .IR v \fR\(fm |
| 724 | are encodings of the strings |
| 725 | .I r |
| 726 | and |
| 727 | .I v |
| 728 | respectively. |
| 729 | If |
| 730 | .I r |
| 731 | consists only of letters, digits, |
| 732 | and the punctuation characters |
| 733 | .RB ` \- ', |
| 734 | .RB ` _ ', |
| 735 | .RB ` : ', |
| 736 | .RB ` . ', |
| 737 | and |
| 738 | .RB ` / ' |
| 739 | then |
| 740 | .IR r \fR\(fm |
| 741 | is simply |
| 742 | .IR r ; |
| 743 | otherwise |
| 744 | .IR r \fR\(fm |
| 745 | is formed by (simultaneously) replacing |
| 746 | each space character in |
| 747 | .I r |
| 748 | with |
| 749 | .RB ` + ' |
| 750 | and each other character |
| 751 | which is not a letter, digit, or |
| 752 | one of the punctuation characters listed above |
| 753 | with |
| 754 | .RB ` % ' |
| 755 | followed by that character's ASCII code in hex, |
| 756 | and prefixing the whole lot by |
| 757 | .RB ` ! '. |
| 758 | Similarly, |
| 759 | if |
| 760 | .I v |
| 761 | consists of letters, digits, |
| 762 | and the punctuation characters listed above, |
| 763 | then |
| 764 | .IR v \fR\(fm |
| 765 | is simply |
| 766 | .IR v ; |
| 767 | otherwise |
| 768 | .IR v \fR\(fm |
| 769 | consists of a |
| 770 | .RB ` ? ' |
| 771 | followed by the base64 encoding of |
| 772 | .IR v , |
| 773 | without any trailing |
| 774 | .RB ` = ' |
| 775 | characters. |
| 776 | .PP |
| 777 | A password record with hash |
| 778 | .I h |
| 779 | and blob |
| 780 | .I b |
| 781 | is stored as a line of the form |
| 782 | .BI $ h\fR\(fm = b\fR\(fm |
| 783 | where |
| 784 | .IR h \(fm |
| 785 | and |
| 786 | .IR b \(fm |
| 787 | are the base64 encodings of |
| 788 | .I h |
| 789 | and |
| 790 | .I b |
| 791 | respectively, |
| 792 | without trailing |
| 793 | .RB ` = ' |
| 794 | characters. |
| 795 | .PP |
| 796 | The records may appear in any order. |
| 797 | The file is completely rewritten when any change is made; |
| 798 | if the file is named |
| 799 | .I f |
| 800 | then this is done by writing the new contents to |
| 801 | .IB f .new |
| 802 | and then renaming |
| 803 | .IB f .new |
| 804 | to |
| 805 | .IR f . |
| 806 | .RE |
| 807 | .TP |
| 808 | .B dir |
| 809 | A directory-backed database is stored as a directory, |
| 810 | named |
| 811 | .I d |
| 812 | in the sequel. |
| 813 | The directory must contain a file |
| 814 | .IB d /meta |
| 815 | whose first line is |
| 816 | .RS |
| 817 | .IP |
| 818 | .B "### pwsafe password directory metadata" |
| 819 | .PP |
| 820 | and directories |
| 821 | .IB d /pw |
| 822 | and |
| 823 | .IB d /tmp \fR. |
| 824 | .PP |
| 825 | Metadata records are stored in file |
| 826 | .IB d /meta |
| 827 | with one record per line, |
| 828 | exactly as for the |
| 829 | .B file |
| 830 | backend described above. |
| 831 | .PP |
| 832 | A password record with hash |
| 833 | .I h |
| 834 | and blob |
| 835 | .I b |
| 836 | is stored as file named |
| 837 | .IB d /pw/ h \fR\(fm |
| 838 | where |
| 839 | .IR h \(fm |
| 840 | is the base64 encodings of |
| 841 | .I h |
| 842 | without trailing |
| 843 | .RB ` = ' |
| 844 | characters, |
| 845 | and with all |
| 846 | .RB ` / ' |
| 847 | characters |
| 848 | replaced by |
| 849 | .RB ` . 's, |
| 850 | whose content is |
| 851 | .IR b . |
| 852 | .PP |
| 853 | The directory |
| 854 | .IB d /tmp/ |
| 855 | is used in an unspecified manner |
| 856 | when creating new password-record files. |
| 857 | The |
| 858 | .IB d /meta |
| 859 | and |
| 860 | .IB d /pw/ h \fR\(fm |
| 861 | files are updated by creating a new temporary file and renaming. |
| 862 | .RE |
| 863 | . |
| 864 | .\"-------------------------------------------------------------------------- |
| 865 | . |
| 866 | .SH BUGS |
| 867 | This is quite an old program, |
| 868 | though the manpage is new. |
| 869 | It provides more footguns than is ideal. |
| 870 | . |
| 871 | .SH SEE ALSO |
| 872 | .BR catcrypt (1), |
| 873 | .BR pixie (1). |
| 874 | . |
| 875 | .SH AUTHOR |
| 876 | Mark Wooding, <mdw@distorted.org.uk> |
| 877 | . |
| 878 | .\"----- That's all, folks -------------------------------------------------- |