Name
pws3_file_create, pws3_file_destroy, pws3_file_get_error_code, pws3_file_get_error_message, pws3_file_read_mem, pws3_file_read_stream, pws3_file_write_mem, pws3_file_write_stream, pws3_file_set_header_field, pws3_file_get_header_field, pws3_file_remove_header_field, pws3_file_insert_empty_group, pws3_file_get_empty_group, pws3_file_remove_empty_group, pws3_file_first_empty_group, pws3_file_last_empty_group, pws3_file_next_empty_group, pws3_file_prev_empty_group, pws3_file_insert_record, pws3_file_get_record, pws3_file_remove_record, pws3_file_first_record, pws3_file_last_record, pws3_file_next_record, pws3_file_prev_record, pws3_field_create, pws3_field_destroy, pws3_field_is_header, pws3_field_get_type, pws3_field_get_data_type, pws3_field_set_uuid, pws3_field_set_text, pws3_field_set_time, pws3_field_set_uint8, pws3_field_set_uint16, pws3_field_set_uint32, pws3_field_set_bytes, pws3_field_get_uuid, pws3_field_get_text, pws3_field_get_time, pws3_field_get_uint8, pws3_field_get_uint16, pws3_field_get_uint32, pws3_field_get_bytes, pws3_record_create, pws3_record_destroy, pws3_record_set_field, pws3_record_get_field, pws3_record_remove_field — create and manipulate Password Safe File Version 3 files
Synopsis
cc
[
flag
...]
file
...
-lpws
-lnettle
[
library
...]
#include <pws.h>
struct pws3_file
*pws3_file_create( | void) ; |
void pws3_file_destroy( | struct pws3_file
*pws_file) ; |
enum pws_error_code
pws3_file_get_error_code( | struct pws3_file
*pws_file) ; |
const char *
pws3_file_get_error_message( | struct pws3_file
*pws_file) ; |
int pws3_file_read_mem( | struct pws3_file *pws_file, |
const char *password, | |
unsigned char *s, | |
size_t
n) ; |
int pws3_file_read_stream( | struct pws3_file *pws_file, |
const char *password, | |
FILE
*fp) ; |
int pws3_file_write_mem( | struct pws3_file *pws_file, |
const char *password, | |
uint32_t n_iter, | |
unsigned char **memp, | |
size_t
*mem_sizep) ; |
int pws3_file_write_stream( | struct pws3_file *pws_file, |
const char *password, | |
uint32_t
n_iter) ; |
void pws3_file_set_header_field( | struct pws3_file *pws_file, |
struct pws3_field
*field) ; |
struct pws3_field *
pws3_file_get_header_field( | struct pws3_file *pws_file, |
uint8_t
field_type) ; |
struct pws3_field *
pws3_file_remove_header_field( | struct pws3_file *pws_file, |
uint8_t
field_type) ; |
void
pws3_file_insert_empty_group( | struct pws3_file *pws_file, |
struct pws3_field
*field) ; |
struct pws3_field *
pws3_file_get_empty_group( | struct pws3_file *pws_file, |
const char
*group_name) ; |
struct pws3_field *
pws3_file_remove_empty_group( | struct pws3_file *pws_file, |
const char
*group_name) ; |
struct pws3_field *
pws3_file_first_empty_group( | struct pws3_file
*pws_file) ; |
struct pws3_field *
pws3_file_last_empty_group( | struct pws3_file
*pws_file) ; |
struct pws3_field *
pws3_file_next_empty_group( | struct pws3_file *pws_file, |
struct pws3_field
*field) ; |
struct pws3_field *
pws3_file_prev_empty_group( | struct pws3_file *pws_file, |
struct pws3_field
*field) ; |
void pws3_file_insert_record( | struct pws3_file *pws_file, |
struct pws3_record
*record) ; |
struct pws3_record *
pws3_file_get_record( | struct pws3_file *pws_file, |
const unsigned char
uuid[static
PWS3_UUID_SIZE]) ; |
struct pws3_record *
pws3_file_remove_record( | struct pws3_file *pws_file, |
const unsigned char
uuid[static
PWS3_UUID_SIZE]) ; |
struct pws3_record *
pws3_file_first_record( | struct pws3_file
*pws_file) ; |
struct pws3_record *
pws3_file_last_record( | struct pws3_file
*pws_file) ; |
struct pws3_record *
pws3_file_next_record( | struct pws3_file *pws_file, |
struct pws3_record
*record) ; |
struct pws3_record *
pws3_file_prev_record( | struct pws3_file *pws_file, |
struct pws3_record
*record) ; |
struct pws3_field *
pws3_field_create( | int is_header, |
uint8_t
field_type) ; |
void pws3_field_destroy( | struct pws3_field
*field) ; |
int
pws3_field_is_header( | struct pws3_field
*field) ; |
uint8_t *
pws3_field_get_type( | struct pws3_field
*field) ; |
enum pws_data_type *
pws3_field_get_data_type( | struct pws3_field
*field) ; |
int pws3_field_set_uuid( | struct pws3_field *field, |
const unsigned char
uuid[static
PWS3_UUID_SIZE]) ; |
int pws3_field_set_text( | struct pws3_field *field, |
const char
s[static 1]) ; |
int pws3_field_set_time( | struct pws3_field *field, |
time_t
time) ; |
int pws3_field_set_uint8( | struct pws3_field *field, |
uint8_t
u8) ; |
int pws3_field_set_uint16( | struct pws3_field *field, |
uint16_t
u16) ; |
int pws3_field_set_uint32( | struct pws3_field *field, |
uint32_t
u32) ; |
int pws3_field_set_bytes( | struct pws3_field *field, |
const unsigned char s[static 1], | |
size_t
n) ; |
const unsigned char *
pws3_field_get_uuid( | struct pws3_field
*field) ; |
const char *
pws3_field_get_text( | struct pws3_field
*field) ; |
time_t
pws3_field_get_time( | struct pws3_field
*field) ; |
uint8_t
pws3_field_get_uint8( | struct pws3_field
*field) ; |
uint16_t
pws3_field_get_uint16( | struct pws3_field
*field) ; |
uint32_t
pws3_field_get_uint32( | struct pws3_field
*field) ; |
void pws3_field_get_bytes( | struct pws3_field *field, |
const unsigned char **pp, | |
size_t
*np) ; |
PWS3_VERSION
PWS3_MAX_FIELD_LEN
PWS3_MAX_PASSWORD_LEN
PWS3_UUID_SIZE
struct pws3_field; struct pws3_record; struct pws3_file; enum pws_error_code; enum pws_data_type; enum pws3_header_field_type; enum pws3_record_field_type;
Description
Introduction
The pws3_*()
family of functions allows
creating, reading, writing, and manipulating Password Safe version 3
files. Password Safe version 3 files consist of a header and a body part.
The header is comprised of both mandatory and optional typed header
fields which hold file-wide metadata. The body consists of records which
in turn hold passwords and associated metadata in typed record
fields.
A header or record field value can be of one of seven basic data types defined below:
Data Type | C Type | Description |
---|---|---|
PWS_DATA_TYPE_UUID | unsigned char [PWS3_UUID_SIZE] | UUID |
PWS_DATA_TYPE_TEXT | char * | NUL-delimited UTF-8 encoded string |
PWS_DATA_TYPE_TIME | time_t | system-specific representation of time |
PWS_DATA_TYPE_UINT8 | uint8_t | 8-bit wide unsigned integer |
PWS_DATA_TYPE_UINT16 | uint16_t | 16-bit wide unsigned integer |
PWS_DATA_TYPE_UINT32 | uint32_t | 32-bit wide unsigned integer |
PWS_DATA_TYPE_BYTES | unsigned char * | array of bytes |
The data type of each header field is defined in
Table 2, “Header Fields” and the data type of each record
field is defined in Table 3, “Record Fields”. Each header
field, with the exception of the empty groups header field, can only
occur once. The version header field
(PWS3_HEADER_FIELD_VERSION
) is mandatory and must
not be removed. When reading a file its value is checked and an error is
returned if the file format version newer than the one supported by
libpws(3).
The supported version is defined by the PWS3_VERSION
macro, when creating a new file structure the version header field will be
set to its value by default. Non-standard header and record fields will
be preserved when a file is read and subsequently written again, they may
be read and manipulated as if they had
PWS_DATA_TYPE_BYTES
data type. All strings are
expected to be in UTF-8 encoding.
The only mandatory record field is the UUID field which uniquely identifies a record in the file.
The complete and authoritative specification of the file format is included with the original Password Safe application available from https://pwsafe.org/.
Password Safe File Data Structure
The pws3_file_create()
function allocates and
intializes a Password Safe file data structure representing a Password
Safe version 3 file. It automatically creates the mandatory version header
field and initializes it to the value of the
PWS3_VERSION
macro.
The pws3_file_destroy()
function deallocates
all header fields and records of the file structure passed to it and then
deallocates the file structure itself.
The pws3_file_read_mem()
and
pws3_file_read_stream()
functions read and parse a
Password Safe file into the given data structure passed via the
pws_file
argument, replacing any existing header
fields and records. The key used to decrypt the file is derived from the
given password
parameter. The
pws3_file_read_mem()
function reads the file from a
block of memory s
with the size of
n
bytes. The
pws3_file_read_stream()
reads the file from the
stream of the fp
file pointer.
The pws3_file_write_mem()
and
pws3_file_write_stream()
functions write a new
Password Safe file from the given datat structure. The key used to
encrypt the file is derived from the password
argument using the number of iterations to stretch the key determined by
the n_iter
argument. The
pws3_file_write_mem()
will allocate and place the
file contents into memory and return the location and size to the
locations sp
and np
point to. The pws3_file_write_stream()
will write the
file contents to the stream of the fp
file
pointer.
Fields
Both header and record fields are stored in
pws3_field
structures which are allocated and
initialized with the pws3_field_create()
function.
Depending on whether is_header
is non-zero either
a header field or a record field data structure of the given field type
will be created.
The pws3_field_destroy()
function
deallocates the given field data structure and its content.
The pws3_field_is_header()
function
can be used to test whether the given field data structure refers to a
header field or a record field.
The pws3_field_get_type()
function
returns the field type of the given field data structure.
The pws3_field_get_data_type()
function
returns the data type of the given field structure.
The pws3_field_set_uuid()
,
pws3_field_set_text()
,
pws3_field_set_time()
,
pws3_field_set_uint8()
,
pws3_field_set_uint16()
,
pws3_field_set_uint32()
, and
pws3_field_set_bytes()
functions set the
content of the given field. The given data is always copied and
existing content is replaced. The data type used by the function must
match the data type of the field specified in Table 2, “Header Fields” in case of header fields or that in Table 3, “Record Fields” in case of record fields.
The pws3_field_get_time()
,
pws3_field_get_uint8()
,
pws3_field_get_uint16()
, and
pws3_field_get_uint32()
functions return the
value of the given field. The
pws3_field_get_uuid()
,
pws3_field_get_text()
, and
pws3_field_get_bytes()
functions return a
pointer to the data of the given field if it has been set. The data type
used by the function must match the data type of the field specified in
Table 2, “Header Fields” in case of header fields and that
in Table 3, “Record Fields” in case of record fields.
Returned pointers are only valid until a field is modified or
deallocated.
Header Fields
Header fields are used to store metadata for the whole file, each type of header field with the exception of the empty groups header field only occurs once. The following header fields are supported:
Header Field Type | Numeric Value | Data Type | Description |
---|---|---|---|
PWS3_HEADER_FIELD_VERSION | 0x00 | PWS_DATA_TYPE_UINT16 | file format version |
PWS3_HEADER_FIELD_UUID | 0x01 | PWS_DATA_TYPE_UUID | UUID |
PWS3_HEADER_FIELD_NON_DEFAULT_PREFERENCES | 0x02 | PWS_DATA_TYPE_TEXT | non-default preferences |
PWS3_HEADER_FIELD_TREE_DISPLAY_STATUS | 0x03 | PWS_DATA_TYPE_TEXT | expandended/collapsed state of the tree of groups |
PWS3_HEADER_FIELD_SAVE_TIMESTAMP | 0x04 | PWS_DATA_TYPE_TIME | time when the file was last saved |
PWS3_HEADER_FIELD_SAVE_USER_HOST | 0x05 | PWS_DATA_TYPE_TEXT | name of the user who last saved the file and name of the host where the file was saved |
PWS3_HEADER_FIELD_SAVE_APPLICATION | 0x06 | PWS_DATA_TYPE_TEXT | name of the application used to save the file |
PWS3_HEADER_FIELD_SAVE_USER | 0x07 | PWS_DATA_TYPE_TEXT | name of the user who last saved the file |
PWS3_HEADER_FIELD_SAVE_HOST | 0x08 | PWS_DATA_TYPE_TEXT | name of the host where the file was last saved |
PWS3_HEADER_FIELD_DATABASE_NAME | 0x09 | PWS_DATA_TYPE_TEXT | logical name for referring to the file |
PWS3_HEADER_FIELD_DATABASE_DESCRIPTION | 0x0a | PWS_DATA_TYPE_TEXT | description of the file |
PWS3_HEADER_FIELD_DATABASE_FILTERS | 0x0b | PWS_DATA_TYPE_TEXT | filters for this file |
PWS3_HEADER_FIELD_RESERVED_1 | 0x0c | PWS_DATA_TYPE_BYTES | reserved |
PWS3_HEADER_FIELD_RESERVED_2 | 0x0d | PWS_DATA_TYPE_BYTES | reserved |
PWS3_HEADER_FIELD_RESERVED_3 | 0x0e | PWS_DATA_TYPE_BYTES | reseved |
PWS3_HEADER_FIELD_RECENTLY_USED_ENTRIES | 0x0f | PWS_DATA_TYPE_TEXT | list of recently used entries |
PWS3_HEADER_FIELD_NAMED_PASSWORD_POLICIES | 0x10 | PWS_DATA_TYPE_TEXT | named password policies |
PWS3_HEADER_FIELD_EMPTY_GROUPS | 0x11 | PWS_DATA_TYPE_TEXT | empty groups which contain no entries |
PWS3_HEADER_FIELD_YUBICO | 0x12 | PWS_DATA_TYPE_TEXT | reserved |
PWS3_HEADER_FIELD_PASSWORD_TIMESTAMP | 0x13 | PWS_DATA_TYPE_TIME | time the master password was last changed |
The pws3_file_set_header_field()
function sets
the header field on the given file. An existing field of the same type is
replaced with the exception of fields of type
PWS3_HEADER_FIELD_EMPTY_GROUPS
for which
pws3_file_set_header_field()
has the same effect as
calling the pws3_file_insert_empty_group()
function.
The pws3_file_get_header_field()
function
returns a pointer to the header field data structure of the given header
field type. In case of the
PWS3_HEADER_FIELD_EMPTY_GROUPS
field type a pointer
to the first empty group field is returned.
The pws3_file_remove_header_field()
function
removes the header field from the given file and returns a pointer to it.
It is the responsibility of the caller to deallocate the header field
data structure. In case of the
PWS3_HEADER_FIELD_EMPTY_GROUPS
field type the first
empty group is removed.
The pws3_file_insert_empty_group()
function
inserts the given empty groups field into the file, an existing field for
a group of the same name is replaced.
The pws3_file_get_empty_group()
function
returns a pointer to the header field datat structure representing an
empty group of the given name.
The pws3_file_remove_empty_group()
function
removes the field representing the empty group of the given name from the
file and returns a pointer to the header field data structure. It is the
responsibility of the caller to deallocate the header field data
structure.
The pws3_file_first_empty_group()
function
returns a pointer to the first empty group header field.
The pws3_file_last_empty_group()
function
returns a pointer to the last empty group header field.
The pws3_file_next_empty_group()
function
returns a pointer to the next empty group header filed data structure
following the given field
.
The pws3_file_prev_empty_groupious()
function
returns a pointer to the previous empty group header filed data structure
preceding the given field
.
Records
Records consist of at least one or more typed fields, they are identified by an UUID which is the only mandatory field and must not be removed. For presentational purposes records may be organized in hierarchical groups. The following record fields are supported:
Record Field Type | Numeric Value | Data Type | Description |
---|---|---|---|
PWS3_RECORD_FIELD_UUID | 0x01 | PWS_DATA_TYPE_UUID | UUID identifying the record |
PWS3_RECORD_FIELD_GROUP | 0x02 | PWS_DATA_TYPE_TEXT | group name the record is a member of |
PWS3_RECORD_FIELD_TITLE | 0x03 | PWS_DATA_TYPE_TEXT | title |
PWS3_RECORD_FIELD_USERNAME | 0x04 | PWS_DATA_TYPE_TEXT | username |
PWS3_RECORD_FIELD_NOTES | 0x05 | PWS_DATA_TYPE_TEXT | notes |
PWS3_RECORD_FIELD_PASSWORD | 0x06 | PWS_DATA_TYPE_TEXT | password |
PWS3_RECORD_FIELD_CREATION_TIME | 0x07 | PWS_DATA_TYPE_TIME | time when the record was created |
PWS3_RECORD_FIELD_PASSWORD_MODIFICATION_TIME | 0x08 | PWS_DATA_TYPE_TIME | time when the password was last modified |
PWS3_RECORD_FIELD_ACCESS_TIME | 0x09 | PWS_DATA_TYPE_TIME | time when the record was last accessed |
PWS3_RECORD_FIELD_PASSWORD_EXPIRY_TIME | 0x0a | PWS_DATA_TYPE_TIME | time when the password expires |
PWS3_RECORD_FIELD_RESERVED_1 | 0x0b | PWS_DATA_TYPE_BYTES | reserved |
PWS3_RECORD_FIELD_MODIFICATION_TIME | 0x0c | PWS_DATA_TYPE_TIME | time at whcih the record was last modified |
PWS3_RECORD_FIELD_URL | 0x0d | PWS_DATA_TYPE_TEXT | URL |
PWS3_RECORD_FIELD_AUTOTYPE | 0x0e | PWS_DATA_TYPE_TEXT | text to be typed when using the autotype feature |
PWS3_RECORD_FIELD_PASSWORD_HISTORY | 0x0f | PWS_DATA_TYPE_TEXT | creation time and values of previously used passwords |
PWS3_RECORD_FIELD_PASSWORD_POLICY | 0x10 | PWS_DATA_TYPE_TEXT | password policy |
PWS3_RECORD_FIELD_PASSWORD_EXPIRY_INTERVAL | 0x11 | PWS_DATA_TYPE_UINT32 | days until the password expires |
PWS3_RECORD_FIELD_RUN_COMMAND | 0x12 | PWS_DATA_TYPE_TEXT | command |
PWS3_RECORD_FIELD_DOUBLE_CLICK_ACTION | 0x13 | PWS_DATA_TYPE_BYTES | action on double clicking |
PWS3_RECORD_FIELD_EMAIL_ADDRESS | 0x14 | PWS_DATA_TYPE_TEXT | email address |
PWS3_RECORD_FIELD_PROTECTED | 0x15 | PWS_DATA_TYPE_UINT8 | flag whether the record is protected from modification |
PWS3_RECORD_FIELD_ALLOWED_PASSWORD_SYMBOLS | 0x16 | PWS_DATA_TYPE_TEXT | allowed symbols for generating passwords |
PWS3_RECORD_FIELD_SHIFT_DOUBLE_CLICK_ACTION | 0x17 | PWS_DATA_TYPE_BYTES | action on pressing shift and double clicking |
PWS3_RECORD_FIELD_PASSWORD_POLICY_NAME | 0x18 | PWS_DATA_TYPE_TEXT | name of password policy saved in the header |
PWS3_RECORD_FIELD_KEYBOARD_SHORTCUT | 0x19 | PWS_DATA_TYPE_BYTES | keyboard shortcut |
PWS3_RECORD_FIELD_RESERVED_2 | 0x1a | PWS_DATA_TYPE_UUID | reserved |
PWS3_RECORD_FIELD_TWO_FACTOR_KEY | 0x1b | PWS_DATA_TYPE_BYTES | two factor key |
PWS3_RECORD_FIELD_CREDIT_CARD_NUMBER | 0x1c | PWS_DATA_TYPE_TEXT | credit card number |
PWS3_RECORD_FIELD_CREDIT_CARD_EXPIRATION | 0x1d | PWS_DATA_TYPE_TEXT | credit card expiration |
PWS3_RECORD_FIELD_CREDIT_CARD_VERIFICATION_VALUE | 0x1e | PWS_DATA_TYPE_TEXT | credit card verification value |
PWS3_RECORD_FIELD_CREDIT_CARD_PIN | 0x1f | PWS_DATA_TYPE_TEXT | credit card PIN |
PWS3_RECORD_FIELD_QR_CODE | 0x20 | PWS_DATA_TYPE_TEXT | QR code |
PWS3_RECORD_FIELD_TESTING_1 | 0xdf | PWS_DATA_TYPE_BYTES | testing |
The pws3_record_create()
function allocates
and creates a record data structure, generates an UUID record field and
adds it to the record.
The pws3_record_destroy()
function deallocates
the given record data structure and all its record fields.
The pws3_file_record_field_set()
function sets
the record field on the given record, replacing an existing field of the
same type.
The pws3_file_record_field_get()
function
returns a pointer to the record field data structure of the given record
field type.
The pws3_file_record_field_remove()
function
removes the record field from the given record and returns a pointer to
it. It is the responsibility of the caller to deallocate the record field
data structure.
The pws3_file_insert_record()
function inserts
the given record into the file, an existing record with the same UUID is
replaced.
The pws3_file_get_record()
function returns a
pointer to the record structure representing a record with the given
UUID.
The pws3_file_remove_record()
function removes
the record with the given UUID from the file and returns a pointer to the
record data structure. It is the responsibility of the caller to
deallocate the record data structure.
The pws3_file_first_record()
function returns a
pointer to the first record.
The pws3_file_last_record()
function returns a
pointer to the last record.
The pws3_file_next_record()
function returns a
pointer to the next record following the given
record
.
The pws3_file_prev_record()
function returns a pointer to the previous group preceding the given
record
.
Macros
The macro PWS3_VERSION
contains the supported
version of the Password Safe version 3 file format.
The macro PWS3_MAX_FIELD_SIZE
contains the
maxium size for header and record fields in bytes and
PWS3_MAX_PASSWORD_LEN
contains the maxium password
length in bytes.
The macro PWS3_UUID_SIZE
contains the size of
UUIDs in bytes.
Return Values
The pws3_file_create()
function returns a
pointer to a Password Safe file data structure if successful and
NULL
in case of an error.
The pws3_file_read_mem()
,
pws3_file_read_stream()
,
pws3_file_write_mem()
, and
pws3_file_write_stream()
functions return
0 on success and -1
to indicate an error.
The pws3_file_get_header_field()
function
returns a pointer to the header field data structure of the requested type
and NULL
if such a field does not exist.
The pws3_file_remove_header_field()
function
returns a pointer to the header field data structure which was removed from
the file or NULL
if such a field does not exist.
The pws3_file_get_empty_group()
function returns
a pointer to the header field data structure corresponding to the requested
empty group and NULL
if a group of that name does not
exist.
The pws3_file_remove_empty_group()
function
returns a pointer to the header field data structure of the empty group
which was removed from the file or NULL
if a group of
that name does not exist.
The pws3_file_first_empty_group()
function
returns a pointer to the first of the empty group header fields or
NULL
if there are no such fields.
The pws3_file_last_empty_group()
function
returns a pointer to the last of the empty group header fields or
NULL
if there are no such fields.
The pws3_file_next_empty_group()
function
returns a pointer to the next empty group header field or
NULL
if there are no more such fields.
The pws3_file_prev_empty_group()
function
returns a pointer to the previous empty group header field or
NULL
if there are no more such fields.
The pws3_file_get_record()
function returns a
pointer to the record data structure of the requested record or
NULL
if that record does not exist.
The pws3_file_remove_record()
function returns a
pointer to the record data structure which was removed from the file or
NULL
if no such record exists.
The pws3_file_first_record()
function returns a
pointer to the record data structure of the first record or
NULL
if no records exist.
The pws3_file_last_record()
function returns a
pointer to the record data structure of the last record or
NULL
if no records exist.
The pws3_file_next_record()
function returns a
pointer to the record data structure of the next record or
NULL
if no records exist.
The pws3_file_prev_record()
function returns a
pointer to the record data structure of the previous record or
NULL
if no records exist.
The pws3_field_create()
function returns a
pointer to the new header field data structure on success and
NULL
on failure.
The pws3_field_get_type()
function returns
the field type of the header field structure.
The pws3_field_get_data_type()
function
returns the data type of the header field structure.
The pws3_field_set_uuid()
,
pws3_field_set_text()
,
pws3_field_set_time()
,
pws3_field_set_uint8()
,
pws3_field_set_uint16()
,
pws3_field_set_uint32()
, and
pws3_field_set_bytes()
functions return
0 on success and -1
on failure.
The pws3_field_get_time()
,
pws3_field_get_uint8()
,
pws3_field_get_uint16()
, and
pws3_field_get_uint32()
functions return a
value of the type corresponding to the type of header field.
The pws3_field_get_uuid()
function
returns a pointer to a UUID.
The pws3_field_get_text()
function
returns a pointer to a string or NULL
if no value has
been set.
The pws3_record_create()
function returns a
pointer to a record data structure if successful and
NULL
on failure.
The pws3_record_get_field()
function returns a
pointer to the record field data structure of the requested type or
NULL
if such a field does not exist.
The pws3_record_remove_field()
function returns
a pointer to the record field data structure which was removed from the
record or NULL
if such a field does not exist.
Errors
If the pws3_file_read_mem()
,
pws3_file_read_stream()
,
pws3_file_write_mem()
, and
pws3_file_write_stream()
functions fail, an error code
indicating the nature of the error may be obtained using the
pws3_file_get_error_code()
function and a pointer to a
detailed error message may be retrieved using the
pws3_file_get_error_message()
function. The above
functions may fail if:
- PWS_ERR_GENERIC_ERROR
An unknown error occurred.
- PWS_ERR_NO_MEMORY
There was not enough space to allocate memory.
- PWS_ERR_IO_ERROR
An I/O error occurred.
- PWS_ERR_TRUNCATED_FILE
The file appears to be truncated.
- PWS_ERR_INVALID_CHECKSUM
The calculated checksum does not match the checksum of the file.
- PWS_ERR_INVALID_RECORD
A record is invalid.
- PWS_ERR_INVALID_HEADER
A header is invalid.
- PWS_ERR_UNSUPPORTED_VERSION
The file format version is not supported.
Examples
The following code creates a new Password Safe file and sets the save application header field:
#include <pws.h> /* ... */ struct pws3_file *file; struct pws3_field *application_field; /* ... */ /* initialize libpws */ if (pws_init() != 0) { /* handle error */ } /* ... */ /* create a new empty file structure */ file = pws3_file_create(); if (file == NULL) { /* handle error */ } /* create new empty save application field */ application_field = pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_APPLICATION); if (application_field == NULL) { /* handle error */ } /* set the value of the field */ if (pws3_field_set_text(application_field, "PasswordManager 2.0") != 0) { /* handle error */ } /* set the header save application field in the file to the new field */ pws3_file_set_field(file, application_field);
The following code loops over each record of an existing Password Safe file and prints the content of the title field if it exists:
#include <stdio.h> #include <pws.h> /* ... */ struct pws3_file *file; struct pws3_record *record; struct pws3_field *title_field; /* ... */ /* interate over each record */ for (record = pws3_file_first_record(file); record != NULL; record = pws3_file_next_record(file, record)) { /* retrieve title field */ title_field = pws3_record_get_field(record, PWS3_RECORD_FIELD_TITLE); /* print the title field or "No title" if it does not exitst */ printf("Title: %s\n", (title_field != NULL) ? pws3_record_field_get_text(PWS3_RECORD_FIELD_TITLE) : "No title"); }
The following code creates a new record with a password field, a title field, and a creation time field and adds it to an existing Password Safe file:
#include <time.h> #include <pws.h> /* ... */ struct pws3_file *file; struct pws3_record *record; struct pws3_field *password_field; struct pws3_field *title_field; struct pws3_field *ctime_field; time_t now; /* ... */ /* create new record */ record = pws3_record_create(); if (record == NULL) { /* handle error */ } /* create a password field */ password_field = pws3_record_field_create(PWS3_RECORD_FIELD_PASSWORD); if (password_field == NULL) { /* handle error */ } /* set the value of the password field to "PaSsWoRd" */ if (pws3_record_field_set_text(password_field, "PaSsWoRd") != 0) { /* handle error */ } /* set the password field of the record to the new field */ pws3_record_set_field(record, password_field); /* create a title field */ title_field = pws3_record_field_create(PWS3_RECORD_FIELD_TITLE); if (title_field == NULL) { /* handle error */ } /* set the value of the title field to "Foo Bar" */ if (pws3_record_field_set_text(title_field, "Foo Bar") != 0) { /* handle error */ } /* set the title field of the record to the new field */ pws3_record_set_field(record, title_field); /* create a new creation time field */ ctime_field = pws3_record_field_create(PWS3_RECORD_FIELD_CREATION_TIME); if (ctime_field == NULL) { /* handle error */ } /* set the value of the creation time field to the current time */ pws3_record_field_set_time(ctime_field, time(NULL)); /* set the creation time field of the record to the new field */ pws3_record_set_field(record, ctime_field); /* insert the new record into the file */ pws3_file_insert_record(file, record);
The following code opens a Password Safe file named
example.pwsafe3
and parses it:
#include <stdio.h> #include <pws.h> /* ... */ FILE *fp; struct pws3_file *file; /* ... */ /* initialize libpws */ if (pws_init() != 0) { /* handle error */ } /* ... */ /* create a new empty file structure */ file = pws3_file_create(); if (file == NULL) { /* handle error */ } /* open the file */ fp = fopen("example.pwsafe3", "r"); if (fp == NULL) { /* handle error */ } /* read and parse the file contents into the file structure */ if (pws3_file_read_stream(file, "PaSsWoRd", fp) != 0) { fprintf(stderr, "error: %s\n", pws3_file_get_error_message(file)); /* handle error */ }
The following code writes a Password Safe file to a file
named example.pwsafe3
:
#include <stdio.h> #include <pws.h> /* ... */ FILE *fp; struct pws3_file *file; /* ... */ fp = fopen("example.pwsafe3", "w"); if (fp == NULL) { /* handle error */ } if (pws3_file_write_stream(file, "FoOBaR", 10000, fp) != 0) { /* handle error */ } fflush(fp); fclose(fp);
See Also
libpws(3), pws_init(3), https://pwsafe.org/