Mercurial > projects > libpws
changeset 1:e1309515d111
Add README file and manpages
author | Guido Berhoerster <guido+libpws@berhoerster.name> |
---|---|
date | Wed, 25 Mar 2015 17:10:23 +0100 |
parents | d541e748cfd8 |
children | 97097b4b6bfb |
files | Makefile README docbook-update-source-data.xsl libpws.3.xml pws3_file_create.3.xml pws_init.3.xml |
diffstat | 6 files changed, 2042 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Tue Feb 10 11:29:54 2015 +0100 +++ b/Makefile Wed Mar 25 17:10:23 2015 +0100 @@ -45,6 +45,45 @@ PAX := pax GZIP := gzip SED := sed +XSLTPROC := xsltproc +DOCBOOK5_MANPAGES_STYLESHEET = http://docbook.sourceforge.net/release/xsl-ns/current/manpages/docbook.xsl +DOCBOOK5_MANPAGES_FLAGS = --stringparam funcsynopsis.style 'ansi' \ + --stringparam man.authors.section.enabled 0 \ + --stringparam man.copyright.section.enabled 0 +DOCBOOK5_XHTML_STYLESHEET = http://docbook.sourceforge.net/release/xsl-ns/current/xhtml/docbook.xsl +DOCBOOK5_XHTML_FLAGS = --stringparam funcsynopsis.style 'ansi' \ + --stringparam generate.consistent.ids 1 \ + --stringparam refentry.generate.name 1 \ + --stringparam refentry.generate.title 0 \ + --stringparam refentry.xref.manvolnum 1 \ + --stringparam generate.id.attributes 1 \ + --stringparam make.valid.html 1 \ + --stringparam make.clean.html 1 \ + --stringparam html.cleanup 1 \ + --stringparam html.longdesc 0 \ + --stringparam ulink.target '' \ + --stringparam docbook.css.source '' \ + --stringparam css.decoration 0 \ + --stringparam default.table.width '100%' + +define generate-manpage-rule = +$(addsuffix .%,$(basename $1)): $(addsuffix .%.xml,$(basename $(firstword $1))) docbook-update-source-data.xsl + $$(XSLTPROC) \ + --xinclude \ + --stringparam package $$(PACKAGE) \ + --stringparam version $$(VERSION) \ + docbook-update-source-data.xsl $$< | \ + $$(XSLTPROC) \ + --xinclude \ + --output $(firstword $1) \ + $$(DOCBOOK5_MANPAGES_FLAGS) \ + $$(DOCBOOK5_MANPAGES_STYLESHEET) \ + - + $$(SED) 's,^\.HP \\w.*$$$$,.HP 4n,' $$@ >$$(@).tmp && mv $$(@).tmp $$@ + for alias in $(wordlist 2,$(words $1),$1); do \ + ln -sf $(notdir $(firstword $1)) $$$$alias; \ + done +endef DESTDIR ?= prefix ?= /usr/local @@ -104,11 +143,78 @@ OBJS = $(LIBPWS_OBJS) +LIBPWS_MANPAGES = libpws.3 + +PWS_INIT_MANPAGES = pws_init.3 \ + pws_finalize.3 \ + pws_set_alloc_functions.3 \ + pws_generate_uuid.3 + +PWS3_FILE_CREATE_MANPAGES = pws3_file_create.3 \ + pws3_file_destroy.3 \ + pws3_file_get_error_code.3 \ + pws3_file_get_error_message.3 \ + pws3_file_read_mem.3 \ + pws3_file_read_stream.3 \ + pws3_file_write_mem.3 \ + pws3_file_write_stream.3 \ + pws3_file_set_header_field.3 \ + pws3_file_get_header_field.3 \ + pws3_file_remove_header_field.3 \ + pws3_file_insert_empty_group.3 \ + pws3_file_get_empty_group.3 \ + pws3_file_remove_empty_group.3 \ + pws3_file_first_empty_group.3 \ + pws3_file_last_empty_group.3 \ + pws3_file_next_empty_group.3 \ + pws3_file_prev_empty_group.3 \ + pws3_file_insert_record.3 \ + pws3_file_get_record.3 \ + pws3_file_remove_record.3 \ + pws3_file_first_record.3 \ + pws3_file_last_record.3 \ + pws3_file_next_record.3 \ + pws3_file_prev_record.3 \ + pws3_field_create.3 \ + pws3_field_destroy.3 \ + pws3_field_is_header.3 \ + pws3_field_get_type.3 \ + pws3_field_get_data_type.3 \ + pws3_field_set_uuid.3 \ + pws3_field_set_text.3 \ + pws3_field_set_time.3 \ + pws3_field_set_uint8.3 \ + pws3_field_set_uint16.3 \ + pws3_field_set_uint32.3 \ + pws3_field_set_bytes.3 \ + pws3_field_get_uuid.3 \ + pws3_field_get_text.3 \ + pws3_field_get_time.3 \ + pws3_field_get_uint8.3 \ + pws3_field_get_uint16.3 \ + pws3_field_get_uint32.3 \ + pws3_field_get_bytes.3 \ + pws3_record_create.3 \ + pws3_record_destroy.3 \ + pws3_record_set_field.3 \ + pws3_record_get_field.3 \ + pws3_record_remove_field.3 + +MANPAGES = $(LIBPWS_MANPAGES) \ + $(PWS_INIT_MANPAGES) \ + $(PWS3_FILE_CREATE_MANPAGES) + +XHTML_DOCUMENTATION = $(addsuffix .xhtml,$(firstword $(LIBPWS_MANPAGES)) \ + $(firstword $(PWS_INIT_MANPAGES)) \ + $(firstword $(PWS3_FILE_CREATE_MANPAGES))) + .DEFAULT_TARGET = all .PHONY: all clean clobber dist install -all: $(LIBPWS_LIB) +all: $(LIBPWS_LIB) $(MANPAGES) + +doc: $(MANPAGES) $(XHTML_DOCUMENTATION) XCPPFLAGS = -Iinclude ifeq ($(HAVE_ARC4RANDOM),1) @@ -146,6 +252,12 @@ $(LIBPWS_LIB): $(LIBPWS_LIB_MEMBERS) +$(eval $(call generate-manpage-rule,$(LIBPWS_MANPAGES))) + +$(eval $(call generate-manpage-rule,$(PWS_INIT_MANPAGES))) + +$(eval $(call generate-manpage-rule,$(PWS3_FILE_CREATE_MANPAGES))) + %.o: %.c $(MAKEDEPEND.c) $< | $(SED) -f deps.sed >$*.d $(COMPILE.c) -o $@ $< @@ -154,16 +266,39 @@ $(AR) $(ARFLAGS) $@ $< $(RANLIB) $@ +%.xhtml: %.xml docbook-update-source-data.xsl + $(XSLTPROC) \ + --xinclude \ + --stringparam package $(PACKAGE) \ + --stringparam version $(VERSION) \ + docbook-update-source-data.xsl $< | \ + $(XSLTPROC) \ + --xinclude \ + --output $@ \ + $(DOCBOOK5_XHTML_FLAGS) \ + $(DOCBOOK5_XHTML_STYLESHEET) \ + - + install: for header in include/*.h; do \ $(INSTALL.data) $${header} \ - "$(DESTDIR)$(includedir)/$(PACKAGE)/$${header##*/}"; \ + "$(DESTDIR)$(includedir)/$${header##*/}"; \ done $(INSTALL.lib) $(LIBPWS_LIB) \ "$(DESTDIR)$(libdir)/$(notdir $(LIBPWS_LIB))" + for manpage in $(MANPAGES); do \ + if [ -L $${manpage} ]; then \ + $(INSTALL.link) $${manpage} \ + "$(DESTDIR)$(mandir)/man$${manpage##*.}/$${manpage##*/}"; \ + else \ + $(INSTALL.data) $${manpage} \ + "$(DESTDIR)$(mandir)/man$${manpage##*.}/$${manpage##*/}"; \ + fi \ + done clean: - rm -f $(LIBPWS_LIB) $(LIBPWS_OBJS) + rm -f $(LIBPWS_LIB) $(LIBPWS_OBJS) $(MANPAGES) \ + $(XHTML_DOCUMENTATION) clobber: clean rm -f $(patsubst %.o,%.d,$(OBJS))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Wed Mar 25 17:10:23 2015 +0100 @@ -0,0 +1,103 @@ +libpws +======= + +Description +----------- + +libpws provides an API for creating, reading, manipulating and writing +Password Safe files, it currently supports version 3 of the Password Safe file +format. + +Build Instructions +------------------ + +libpws requires a POSIX:2004 compatible operating system, it has been tested +to work on Linux distributions, FreeBSD, Solaris and Illumos-derived +distributions. The following tools and shared libraries are required to build +libpws: + +- GNU make >= 3.81 +- GNU or BSD install +- Nettle + +Rebuilding the man pages additionally requires the xsltproc tool from libxml2. + +Before building libpws check the commented macros in the Makefile for any +macros you may need to override depending on the used toolchain and operating +system. + +By default, all files will be installed under the "/usr/local" directory, a +different installation path prefix can be set via the `prefix` macro. In +addition, a second path prefix can be specified via the `DESTDIR` macro which +will be prepended to any path, incuding the `prefix` macro path prefix. In +contrast to `prefix`, the path specified via the `DESTDIR` macro will only be +prepended to paths during installation and not be used for constructing +internal paths. + +The following instructions assume that `make` is GNU make, on some platforms +it may be installed under a different name or a non-default path. In order to +start the build process run `make all`. After a successful build, run `make +install` to install the program, any associated data files and the +documentation. + +Previously built binaries, object files, generated data files and +documentation can be removed by running `make clean`, any additional, +generated files which are not removed by the `clean` target can be removed by +running `make clobber`. + +Contact +------- + +Please send any feedback, translations or bug reports via email to +<guido+libpws@berhoerster.name>. + +Bug Reports +----------- + +When sending bug reports, please always mention the exact version of libpws +with which the issue occurs as well as the version of the operating system you +are using and make sure that you provide sufficient information to reproduce +the issue and include any input, output, any error messages. + +In case of build issues, please also specify the implementations and versions +of the tools and shared libraries used to build the program, in particular the +compiler. + +In case of crashes, please generate a stack trace with a suitable debugger +such as gdb, lldb, dbx, or debug after a crash has occurred either by +examining the resulting core file or by running the program from the debugger +and attach it to the bug report. In order to generate a meaningful stack +trace the program as well as any dynamically linked libraries need to be built +with debugging information, see the documentation of the used compiler for the +required compiler flags. If any of the dynamically linked shared libraries do +not contain debugging information, please either install debugging information +for these libraries using mechanisms provided by your operating system or +rebuild the libraries accordingly. Please refer to the documentation of the +debugger for detailed instructions on generating backtraces. + +License +------- + +Except otherwise noted, all files are Copyright (C) 2015 Guido Berhoerster and +distributed under the following license terms: + +Copyright (C) 2015 Guido Berhoerster <guido+libpws@berhoerster.name> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docbook-update-source-data.xsl Wed Mar 25 17:10:23 2015 +0100 @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<xsl:stylesheet + version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:db="http://docbook.org/ns/docbook" + xmlns="http://docbook.org/ns/docbook" + exclude-result-prefixes="xsl db"> + + <xsl:param name="package" select="''" /> + <xsl:param name="version" select="''" /> + + <xsl:template match="db:refmeta/db:refmiscinfo[@class = 'source' or + @class = 'version']"/> + + <xsl:template match="db:refmeta"> + <xsl:copy> + <xsl:apply-templates/> + <refmiscinfo class="source"><xsl:value-of select="$package"/></refmiscinfo> + <refmiscinfo class="version"><xsl:value-of select="$version"/></refmiscinfo> + </xsl:copy> + </xsl:template> + + <xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> + +</xsl:stylesheet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpws.3.xml Wed Mar 25 17:10:23 2015 +0100 @@ -0,0 +1,213 @@ +<?xml version="1.0"?> +<!-- + +Copyright (C) 2015 Guido Berhoerster <guido+libpws@berhoerster.name> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--> +<refentry xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en"> + <info> + <author> + <personname> + <firstname>Guido</firstname> + <surname>Berhoerster</surname> + </personname> + <email>guido+libpws@berhoerster.name</email> + <personblurb/> + </author> + <date>21 March, 2015</date> + </info> + <refmeta> + <refentrytitle>libpws</refentrytitle> + <manvolnum>3</manvolnum> + <refmiscinfo class="source"/> + <refmiscinfo class="version"/> + <refmiscinfo class="manual">Library Functions</refmiscinfo> + </refmeta> + <refnamediv> + <refname>libpws</refname> + <refpurpose>library for creating and manipulating Password Safe files</refpurpose> + </refnamediv> + <refsynopsisdiv> + <cmdsynopsis> + <command>cc</command> + <arg choice="opt" rep="repeat"> + <option>flag</option> + </arg> + <arg choice="plain" rep="repeat"> + <option>file</option> + </arg> + <arg choice="plain"> + <option>-lpws</option> + </arg> + <arg choice="plain"> + <option>-lnettle</option> + </arg> + <arg choice="opt" rep="repeat"> + <option>library</option> + </arg> + </cmdsynopsis> + <funcsynopsis> + <funcsynopsisinfo> +#include <pws.h> +</funcsynopsisinfo> + </funcsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para>libpws provides an API for creating, reading, manipulating and + writing Password Safe files. The Password Safe file format is intended + for the platform-independent secure storage of passwords and associated + metadata and offers protection from unauthorized access to the file by + encrypting it using a key derived from a master password. Its design + ensures both confidentiality and integrity of its contents.</para> + <para>libpws currently supports version 3 of the Password Safe file + format.</para> + <para>The <literal><<filename + class="header">pws.h</filename>></literal> header provides type and + function declarations for all library services.</para> + <para>With the exception of <function>pws_set_alloc_functions</function> + all functions are reentrant. Functions operating on a Password Safe file + structure, a header field structure, a record field structure, and a record + structure provide no locking. A multithreaded application must either + provide its own synchronization mechanisms or restrict operations on any of + the above structures to a single thread.</para> + </refsect1> + <refsect1> + <title>Interfaces</title> + <para>The static library <filename class="libraryfile">libpws.a</filename> + provides following the public interfaces: + <simplelist type="vert" columns="2"> + <member><function>pws_init</function></member> + <member><function>pws_finalize</function></member> + <member><function>pws_set_alloc_functions</function></member> + <member><function>pws_generate_uuid</function></member> + <member><function>pws3_field_create</function></member> + <member><function>pws3_field_destroy</function></member> + <member><function>pws3_field_is_header</function></member> + <member><function>pws3_field_get_type</function></member> + <member><function>pws3_field_get_data_type</function></member> + <member><function>pws3_field_set_uuid</function></member> + <member><function>pws3_field_set_text</function></member> + <member><function>pws3_field_set_time</function></member> + <member><function>pws3_field_set_uint8</function></member> + <member><function>pws3_field_set_uint16</function></member> + <member><function>pws3_field_set_uint32</function></member> + <member><function>pws3_field_set_bytes</function></member> + <member><function>pws3_field_get_uuid</function></member> + <member><function>pws3_field_get_text</function></member> + <member><function>pws3_field_get_time</function></member> + <member><function>pws3_field_get_uint8</function></member> + <member><function>pws3_field_get_uint16</function></member> + <member><function>pws3_field_get_uint32</function></member> + <member><function>pws3_field_get_bytes</function></member> + <member><function>pws3_file_create</function></member> + <member><function>pws3_file_destroy</function></member> + <member><function>pws3_file_get_error_code</function></member> + <member><function>pws3_file_get_error_message</function></member> + <member><function>pws3_file_read_mem</function></member> + <member><function>pws3_file_read_stream</function></member> + <member><function>pws3_file_write_mem</function></member> + <member><function>pws3_file_write_stream</function></member> + <member><function>pws3_file_set_header_field</function></member> + <member><function>pws3_file_get_header_field</function></member> + <member><function>pws3_file_remove_header_field</function></member> + <member><function>pws3_file_insert_empty_group</function></member> + <member><function>pws3_file_get_empty_group</function></member> + <member><function>pws3_file_remove_empty_group</function></member> + <member><function>pws3_file_first_empty_group</function></member> + <member><function>pws3_file_last_empty_group</function></member> + <member><function>pws3_file_next_empty_group</function></member> + <member><function>pws3_file_prev_empty_group</function></member> + <member><function>pws3_file_insert_record</function></member> + <member><function>pws3_file_get_record</function></member> + <member><function>pws3_file_remove_record</function></member> + <member><function>pws3_file_first_record</function></member> + <member><function>pws3_file_last_record</function></member> + <member><function>pws3_file_next_record</function></member> + <member><function>pws3_file_prev_record</function></member> + </simplelist></para> + <para>It defines the following C preprocessor macros which are documented + in the + <citerefentry><refentrytitle>pws_init</refentrytitle><manvolnum>3</manvolnum></citerefentry> + manual page: + <simplelist type="vert"> + <member><function>LIBPWS_VERSION_MAJOR</function></member> + <member><function>LIBPWS_VERSION_MINOR</function></member> + <member><function>LIBPWS_VERSION_MICRO</function></member> + <member><function>PWS3_VERSION</function></member> + <member><function>PWS3_MAX_FIELD_SIZE</function></member> + <member><function>PWS3_MAX_PASSWORD_LEN</function></member> + <member><function>PWS3_UUID_SIZE</function></member> + </simplelist></para> + </refsect1> + <refsect1> + <title>Types</title> + <para>libpws provides the following data structures: + <variablelist> + <varlistentry> + <term>struct pws3_file</term> + <listitem> + <para>Opaque data structure representing a Password Safe version 3 + file.</para> + </listitem> + </varlistentry> + <varlistentry> + <term>struct pws3_record</term> + <listitem> + <para>Opaque data structure representing a Password Safe version 3 + record.</para> + </listitem> + </varlistentry> + <varlistentry> + <term>struct pws3_field</term> + <listitem> + <para>Opaque data structure representing a Password Safe version 3 + typed field belonging to the header or a record, depending on the + type it may hold a UUID, string, time, 8-bit, 16-bit, or 32-bit + wide unsigned integer or raw data.</para> + </listitem> + </varlistentry> + </variablelist></para> + </refsect1> + <refsect1> + <title>Security</title> + <para>The aforementioned protection of confidentiality and integrity of + the file contents only applies to the stored file. When reading a Password + Safe file using libpws, the file contents are decrypted and stored in + memory where they might be compromised, e.g. by a malicious application or + a privileged user. Furthermore, parts of the process memory may be paged to + the swap area by the operating system.</para> + <para>libpws provides hooks for allocating and freeing memory used to + store sensitive information which may be used to mitigate such issues + using operating system specific facilities.</para> + <para>libpws has not been formally audited, use at your own risk.</para> + </refsect1> + <refsect1> + <title>See Also</title> + <para><citerefentry><refentrytitle>pws_init</refentrytitle> + <manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>pws3_file_create</refentrytitle> + <manvolnum>3</manvolnum></citerefentry>, <link + xlink:href="https://pwsafe.org/"/></para> + </refsect1> +</refentry>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pws3_file_create.3.xml Wed Mar 25 17:10:23 2015 +0100 @@ -0,0 +1,1400 @@ +<?xml version="1.0"?> +<!-- + +Copyright (C) 2015 Guido Berhoerster <guido+libpws@berhoerster.name> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--> +<refentry xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en"> + <info> + <author> + <personname> + <firstname>Guido</firstname> + <surname>Berhoerster</surname> + </personname> + <email>guido+libpws@berhoerster.name</email> + <personblurb/> + </author> + <date>21 March, 2015</date> + </info> + <refmeta> + <refentrytitle>libpws</refentrytitle> + <manvolnum>3</manvolnum> + <refmiscinfo class="source"/> + <refmiscinfo class="version"/> + <refmiscinfo class="manual">Library Functions</refmiscinfo> + </refmeta> + <refnamediv> + <refname>pws3_file_create</refname> + <refname>pws3_file_destroy</refname> + <refname>pws3_file_get_error_code</refname> + <refname>pws3_file_get_error_message</refname> + <refname>pws3_file_read_mem</refname> + <refname>pws3_file_read_stream</refname> + <refname>pws3_file_write_mem</refname> + <refname>pws3_file_write_stream</refname> + <refname>pws3_file_set_header_field</refname> + <refname>pws3_file_get_header_field</refname> + <refname>pws3_file_remove_header_field</refname> + <refname>pws3_file_insert_empty_group</refname> + <refname>pws3_file_get_empty_group</refname> + <refname>pws3_file_remove_empty_group</refname> + <refname>pws3_file_first_empty_group</refname> + <refname>pws3_file_last_empty_group</refname> + <refname>pws3_file_next_empty_group</refname> + <refname>pws3_file_prev_empty_group</refname> + <refname>pws3_file_insert_record</refname> + <refname>pws3_file_get_record</refname> + <refname>pws3_file_remove_record</refname> + <refname>pws3_file_first_record</refname> + <refname>pws3_file_last_record</refname> + <refname>pws3_file_next_record</refname> + <refname>pws3_file_prev_record</refname> + <refname>pws3_field_create</refname> + <refname>pws3_field_destroy</refname> + <refname>pws3_field_is_header</refname> + <refname>pws3_field_get_type</refname> + <refname>pws3_field_get_data_type</refname> + <refname>pws3_field_set_uuid</refname> + <refname>pws3_field_set_text</refname> + <refname>pws3_field_set_time</refname> + <refname>pws3_field_set_uint8</refname> + <refname>pws3_field_set_uint16</refname> + <refname>pws3_field_set_uint32</refname> + <refname>pws3_field_set_bytes</refname> + <refname>pws3_field_get_uuid</refname> + <refname>pws3_field_get_text</refname> + <refname>pws3_field_get_time</refname> + <refname>pws3_field_get_uint8</refname> + <refname>pws3_field_get_uint16</refname> + <refname>pws3_field_get_uint32</refname> + <refname>pws3_field_get_bytes</refname> + <refname>pws3_record_create</refname> + <refname>pws3_record_destroy</refname> + <refname>pws3_record_set_field</refname> + <refname>pws3_record_get_field</refname> + <refname>pws3_record_remove_field</refname> + <refpurpose>create and manipulate Password Safe File Version 3 + files</refpurpose> + </refnamediv> + <refsynopsisdiv> + <cmdsynopsis> + <command>cc</command> + <arg choice="opt" rep="repeat"> + <option>flag</option> + </arg> + <arg choice="plain" rep="repeat"> + <option>file</option> + </arg> + <arg choice="plain"> + <option>-lpws</option> + </arg> + <arg choice="plain"> + <option>-lnettle</option> + </arg> + <arg choice="opt" rep="repeat"> + <option>library</option> + </arg> + </cmdsynopsis> + <funcsynopsis> + <funcsynopsisinfo> +#include <pws.h> +</funcsynopsisinfo> + <funcprototype> + <funcdef>struct pws3_file + *<function>pws3_file_create</function></funcdef> + <void/> + </funcprototype> + <funcprototype> + <funcdef>void <function>pws3_file_destroy</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>enum pws_error_code + <function>pws3_file_get_error_code</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>const char * + <function>pws3_file_get_error_message</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_file_read_mem</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>const char + *<parameter><replaceable>password</replaceable></parameter></paramdef> + <paramdef>unsigned char + *<parameter><replaceable>s</replaceable></parameter></paramdef> + <paramdef>size_t + <parameter><replaceable>n</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_file_read_stream</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>const char + *<parameter><replaceable>password</replaceable></parameter></paramdef> + <paramdef>FILE + *<parameter><replaceable>fp</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_file_write_mem</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>const char + *<parameter><replaceable>password</replaceable></parameter></paramdef> + <paramdef>uint32_t + <parameter><replaceable>n_iter</replaceable></parameter></paramdef> + <paramdef>unsigned char + **<parameter><replaceable>memp</replaceable></parameter></paramdef> + <paramdef>size_t + *<parameter><replaceable>mem_sizep</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_file_write_stream</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>const char + *<parameter><replaceable>password</replaceable></parameter></paramdef> + <paramdef>uint32_t + <parameter><replaceable>n_iter</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>void <function>pws3_file_set_header_field</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_field * + <function>pws3_file_get_header_field</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>uint8_t + <parameter><replaceable>field_type</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_field * + <function>pws3_file_remove_header_field</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>uint8_t + <parameter><replaceable>field_type</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>void + <function>pws3_file_insert_empty_group</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_field * + <function>pws3_file_get_empty_group</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>const char + *<parameter><replaceable>group_name</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_field * + <function>pws3_file_remove_empty_group</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>const char + *<parameter><replaceable>group_name</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_field * + <function>pws3_file_first_empty_group</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_field * + <function>pws3_file_last_empty_group</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_field * + <function>pws3_file_next_empty_group</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_field * + <function>pws3_file_prev_empty_group</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>void <function>pws3_file_insert_record</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>struct pws3_record + *<parameter><replaceable>record</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_record * + <function>pws3_file_get_record</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>const unsigned char + <parameter><replaceable>uuid</replaceable>[static + PWS3_UUID_SIZE]</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_record * + <function>pws3_file_remove_record</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>const unsigned char + <parameter><replaceable>uuid</replaceable>[static + PWS3_UUID_SIZE]</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_record * + <function>pws3_file_first_record</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_record * + <function>pws3_file_last_record</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_record * + <function>pws3_file_next_record</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>struct pws3_record + *<parameter><replaceable>record</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_record * + <function>pws3_file_prev_record</function></funcdef> + <paramdef>struct pws3_file + *<parameter><replaceable>pws_file</replaceable></parameter></paramdef> + <paramdef>struct pws3_record + *<parameter><replaceable>record</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>struct pws3_field * + <function>pws3_field_create</function></funcdef> + <paramdef>int + <parameter><replaceable>is_header</replaceable></parameter></paramdef> + <paramdef>uint8_t + <parameter><replaceable>field_type</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>void <function>pws3_field_destroy</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int + <function>pws3_field_is_header</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>uint8_t * + <function>pws3_field_get_type</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>enum pws_data_type * + <function>pws3_field_get_data_type</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_field_set_uuid</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + <paramdef>const unsigned char + <parameter><replaceable>uuid</replaceable>[static + PWS3_UUID_SIZE]</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_field_set_text</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + <paramdef>const char + <parameter><replaceable>s</replaceable>[static 1]</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_field_set_time</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + <paramdef>time_t + <parameter><replaceable>time</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_field_set_uint8</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + <paramdef>uint8_t + <parameter><replaceable>u8</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_field_set_uint16</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + <paramdef>uint16_t + <parameter><replaceable>u16</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_field_set_uint32</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + <paramdef>uint32_t + <parameter><replaceable>u32</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws3_field_set_bytes</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + <paramdef>const unsigned char + <parameter><replaceable>s</replaceable>[static 1]</parameter></paramdef> + <paramdef>size_t + <parameter><replaceable>n</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>const unsigned char * + <function>pws3_field_get_uuid</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>const char * + <function>pws3_field_get_text</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>time_t + <function>pws3_field_get_time</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>uint8_t + <function>pws3_field_get_uint8</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>uint16_t + <function>pws3_field_get_uint16</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>uint32_t + <function>pws3_field_get_uint32</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>void <function>pws3_field_get_bytes</function></funcdef> + <paramdef>struct pws3_field + *<parameter><replaceable>field</replaceable></parameter></paramdef> + <paramdef>const unsigned char + **<parameter><replaceable>pp</replaceable></parameter></paramdef> + <paramdef>size_t + *<parameter><replaceable>np</replaceable></parameter></paramdef> + </funcprototype> + </funcsynopsis> + <synopsis> +<constant>PWS3_VERSION</constant> + +<constant>PWS3_MAX_FIELD_LEN</constant> + +<constant>PWS3_MAX_PASSWORD_LEN</constant> + +<constant>PWS3_UUID_SIZE</constant> + +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; +</synopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <refsect2> + <title>Introduction</title> + <para>The <function>pws3_*()</function> 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.</para> + <para>A header or record field value can be of one of seven basic data + types defined below: + <table xml:id="table-data-types"> + <title>Header and Record Field Value Data Types</title> + <tgroup cols="3" align="left" colsep="1" rowsep="1"> + <thead> + <row> + <entry>Data Type</entry> + <entry>C Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry><constant>PWS_DATA_TYPE_UUID</constant></entry> + <entry><code>unsigned char [PWS3_UUID_SIZE]</code></entry> + <entry>UUID</entry> + </row> + <row> + <entry><constant>PWS_DATA_TYPE_TEXT</constant></entry> + <entry><code>char *</code></entry> + <entry>NUL-delimited UTF-8 encoded string</entry> + </row> + <row> + <entry><constant>PWS_DATA_TYPE_TIME</constant></entry> + <entry><code>time_t</code></entry> + <entry>system-specific representation of time</entry> + </row> + <row> + <entry><constant>PWS_DATA_TYPE_UINT8</constant></entry> + <entry><code>uint8_t</code></entry> + <entry>8-bit wide unsigned integer</entry> + </row> + <row> + <entry><constant>PWS_DATA_TYPE_UINT16</constant></entry> + <entry><code>uint16_t</code></entry> + <entry>16-bit wide unsigned integer</entry> + </row> + <row> + <entry><constant>PWS_DATA_TYPE_UINT32</constant></entry> + <entry><code>uint32_t</code></entry> + <entry>32-bit wide unsigned integer</entry> + </row> + <row> + <entry><constant>PWS_DATA_TYPE_BYTES</constant></entry> + <entry><code>unsigned char *</code></entry> + <entry>array of bytes</entry> + </row> + </tbody> + </tgroup> + </table> + </para> + <para>The data type of each header field is defined in + <xref linkend="table-header-fields"/> and the data type of each record + field is defined in <xref linkend="table-record-fields"/>. Each header + field, with the exception of the empty groups header field, can only + occur once. The version header field + (<constant>PWS3_HEADER_FIELD_VERSION</constant>) 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 + <citerefentry><refentrytitle>libpws</refentrytitle><manvolnum>3</manvolnum></citerefentry>. + The supported version is defined by the <constant>PWS3_VERSION</constant> + 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 + <constant>PWS_DATA_TYPE_BYTES</constant> data type. All strings are + expected to be in UTF-8 encoding.</para> + <para>The only mandatory record field is the UUID field which uniquely + identifies a record in the file.</para> + <para>The complete and authoritative specification of the file format is + included with the original Password Safe application available from <link + xlink:href="https://pwsafe.org/"/>.</para> + </refsect2> + <refsect2> + <title>Password Safe File Data Structure</title> + <para>The <function>pws3_file_create()</function> 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 + <constant>PWS3_VERSION</constant> macro.</para> + <para>The <function>pws3_file_destroy()</function> function deallocates + all header fields and records of the file structure passed to it and then + deallocates the file structure itself.</para> + <para>The <function>pws3_file_read_mem()</function> and + <function>pws3_file_read_stream()</function> functions read and parse a + Password Safe file into the given data structure passed via the + <parameter>pws_file</parameter> argument, replacing any existing header + fields and records. The key used to decrypt the file is derived from the + given <parameter>password</parameter> parameter. The + <function>pws3_file_read_mem()</function> function reads the file from a + block of memory <parameter>s</parameter> with the size of + <parameter>n</parameter> bytes. The + <function>pws3_file_read_stream()</function> reads the file from the + stream of the <parameter>fp</parameter> file pointer.</para> + <para>The <function>pws3_file_write_mem()</function> and + <function>pws3_file_write_stream()</function> functions write a new + Password Safe file from the given datat structure. The key used to + encrypt the file is derived from the <parameter>password</parameter> + argument using the number of iterations to stretch the key determined by + the <parameter>n_iter</parameter> argument. The + <function>pws3_file_write_mem()</function> will allocate and place the + file contents into memory and return the location and size to the + locations <parameter>sp</parameter> and <parameter>np</parameter> + point to. The <function>pws3_file_write_stream()</function> will write the + file contents to the stream of the <parameter>fp</parameter> file + pointer.</para> + </refsect2> + <refsect2> + <title>Fields</title> + <para>Both header and record fields are stored in + <varname>pws3_field</varname> structures which are allocated and + initialized with the <function>pws3_field_create()</function> function. + Depending on whether <parameter>is_header</parameter> is non-zero either + a header field or a record field data structure of the given field type + will be created.</para> + <para>The <function>pws3_field_destroy()</function> function + deallocates the given field data structure and its content.</para> + <para>The <function>pws3_field_is_header()</function> function + can be used to test whether the given field data structure refers to a + header field or a record field.</para> + <para>The <function>pws3_field_get_type()</function> function + returns the field type of the given field data structure.</para> + <para>The <function>pws3_field_get_data_type()</function> function + returns the data type of the given field structure.</para> + <para>The <function>pws3_field_set_uuid()</function>, + <function>pws3_field_set_text()</function>, + <function>pws3_field_set_time()</function>, + <function>pws3_field_set_uint8()</function>, + <function>pws3_field_set_uint16()</function>, + <function>pws3_field_set_uint32()</function>, and + <function>pws3_field_set_bytes()</function> 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 <xref + linkend="table-header-fields"/> in case of header fields or that in <xref + linkend="table-record-fields"/> in case of record fields.</para> + <para>The <function>pws3_field_get_time()</function>, + <function>pws3_field_get_uint8()</function>, + <function>pws3_field_get_uint16()</function>, and + <function>pws3_field_get_uint32()</function> functions return the + value of the given field. The + <function>pws3_field_get_uuid()</function>, + <function>pws3_field_get_text()</function>, and + <function>pws3_field_get_bytes()</function> 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 + <xref linkend="table-header-fields"/> in case of header fields and that + in <xref linkend="table-record-fields"/> in case of record fields. + Returned pointers are only valid until a field is modified or + deallocated.</para> + </refsect2> + <refsect2> + <title>Header Fields</title> + <para>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: + <table xml:id="table-header-fields"> + <title>Header Fields</title> + <tgroup cols="4" align="left" colsep="1" rowsep="1"> + <thead> + <row> + <entry>Header Field Type</entry> + <entry>Numeric Value</entry> + <entry>Data Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​VERSION</constant></entry> + <entry><literal>0x00</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​UINT16</constant></entry> + <entry>file format version</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​UUID</constant></entry> + <entry><literal>0x01</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​UUID</constant></entry> + <entry>UUID</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​NON_​DEFAULT_​PREFERENCES</constant></entry> + <entry><literal>0x02</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>non-default preferences</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​TREE_​DISPLAY_​STATUS</constant></entry> + <entry><literal>0x03</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>expandended/​collapsed state of the tree of groups</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​SAVE_​TIMESTAMP</constant></entry> + <entry><literal>0x04</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TIME</constant></entry> + <entry>time when the file was last saved</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​SAVE_​USER_​HOST</constant></entry> + <entry><literal>0x05</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>name of the user who last saved the file and name of the host where the file was saved</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​SAVE_​APPLICATION</constant></entry> + <entry><literal>0x06</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>name of the application used to save the file</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​SAVE_​USER</constant></entry> + <entry><literal>0x07</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>name of the user who last saved the file</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​SAVE_​HOST</constant></entry> + <entry><literal>0x08</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>name of the host where the file was last saved</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​DATABASE_​NAME</constant></entry> + <entry><literal>0x09</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>logical name for referring to the file</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​DATABASE_​DESCRIPTION</constant></entry> + <entry><literal>0x0a</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>description of the file</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​DATABASE_​FILTERS</constant></entry> + <entry><literal>0x0b</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>filters for this file</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​RESERVED_​1</constant></entry> + <entry><literal>0x0c</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​BYTES</constant></entry> + <entry>reserved</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​RESERVED_​2</constant></entry> + <entry><literal>0x0d</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​BYTES</constant></entry> + <entry>reserved</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​RESERVED_​3</constant></entry> + <entry><literal>0x0e</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​BYTES</constant></entry> + <entry>reseved</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​RECENTLY_​USED_​ENTRIES</constant></entry> + <entry><literal>0x0f</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>list of recently used entries</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​NAMED_​PASSWORD_​POLICIES</constant></entry> + <entry><literal>0x10</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>named password policies</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​EMPTY_​GROUPS</constant></entry> + <entry><literal>0x11</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>empty groups which contain no entries</entry> + </row> + <row> + <entry><constant>PWS3_​HEADER_​FIELD_​YUBICO</constant></entry> + <entry><literal>0x12</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>reserved</entry> + </row> + </tbody> + </tgroup> + </table> + </para> + <para>The <function>pws3_file_set_header_field()</function> 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 + <constant>PWS3_HEADER_FIELD_EMPTY_GROUPS</constant> for which + <function>pws3_file_set_header_field()</function> has the same effect as + calling the <function>pws3_file_insert_empty_group()</function> + function.</para> + <para>The <function>pws3_file_get_header_field()</function> function + returns a pointer to the header field data structure of the given header + field type. In case of the + <constant>PWS3_HEADER_FIELD_EMPTY_GROUPS</constant> field type a pointer + to the first empty group field is returned.</para> + <para>The <function>pws3_file_remove_header_field()</function> 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 + <constant>PWS3_HEADER_FIELD_EMPTY_GROUPS</constant> field type the first + empty group is removed.</para> + <para>The <function>pws3_file_insert_empty_group()</function> function + inserts the given empty groups field into the file, an existing field for + a group of the same name is replaced.</para> + <para>The <function>pws3_file_get_empty_group()</function> function + returns a pointer to the header field datat structure representing an + empty group of the given name.</para> + <para>The <function>pws3_file_remove_empty_group()</function> 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.</para> + <para>The <function>pws3_file_first_empty_group()</function> function + returns a pointer to the first empty group header field.</para> + <para>The <function>pws3_file_last_empty_group()</function> function + returns a pointer to the last empty group header field.</para> + <para>The <function>pws3_file_next_empty_group()</function> function + returns a pointer to the next empty group header filed data structure + following the given <parameter>field</parameter>.</para> + <para>The <function>pws3_file_prev_empty_groupious()</function> function + returns a pointer to the previous empty group header filed data structure + preceding the given <parameter>field</parameter>.</para> + </refsect2> + <refsect2> + <title>Records</title> + <para>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: + <table xml:id="table-record-fields"> + <title>Record Fields</title> + <tgroup cols="4" align="left" colsep="1" rowsep="1"> + <thead> + <row> + <entry>Record Field Type</entry> + <entry>Numeric Value</entry> + <entry>Data Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​UUID</constant></entry> + <entry><literal>0x01</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​UUID</constant></entry> + <entry>UUID identifying the record</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​GROUP</constant></entry> + <entry><literal>0x02</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>group name the record is a member of</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​TITLE</constant></entry> + <entry><literal>0x03</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>title</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​USERNAME</constant></entry> + <entry><literal>0x04</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>username</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​NOTES</constant></entry> + <entry><literal>0x05</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>notes</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​PASSWORD</constant></entry> + <entry><literal>0x06</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>password</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​CREATION_​TIME</constant></entry> + <entry><literal>0x07</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TIME</constant></entry> + <entry>time when the record was created</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​PASSWORD_​MODIFICATION_​TIME</constant></entry> + <entry><literal>0x08</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TIME</constant></entry> + <entry>time when the password was last modified</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​ACCESS_​TIME</constant></entry> + <entry><literal>0x09</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TIME</constant></entry> + <entry>time when the record was last accessed</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​PASSWORD_​EXPIRY_​TIME</constant></entry> + <entry><literal>0x0a</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TIME</constant></entry> + <entry>time when the password expires</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​RESERVED_​1</constant></entry> + <entry><literal>0x0b</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​BYTES</constant></entry> + <entry>reserved</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​MODIFICATION_​TIME</constant></entry> + <entry><literal>0x0c</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TIME</constant></entry> + <entry>time at whcih the record was last modified</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​URL</constant></entry> + <entry><literal>0x0d</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>URL</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​AUTOTYPE</constant></entry> + <entry><literal>0x0e</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>text to be typed when using the autotype feature</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​PASSWORD_​HISTORY</constant></entry> + <entry><literal>0x0f</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>creation time and values of previously used passwords</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​PASSWORD_​POLICY</constant></entry> + <entry><literal>0x10</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>password policy</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​PASSWORD_​EXPIRY_​INTERVAL</constant></entry> + <entry><literal>0x11</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​UINT32</constant></entry> + <entry>days until the password expires</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​RUN_​COMMAND</constant></entry> + <entry><literal>0x12</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>command</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​DOUBLE_​CLICK_​ACTION</constant></entry> + <entry><literal>0x13</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​BYTES</constant></entry> + <entry>action on double clicking</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​EMAIL_​ADDRESS</constant></entry> + <entry><literal>0x14</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>email address</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​PROTECTED</constant></entry> + <entry><literal>0x15</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​UINT8</constant></entry> + <entry>flag whether the record is protected from modification</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​ALLOWED_​PASSWORD_​SYMBOLS</constant></entry> + <entry><literal>0x16</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>allowed symbols for generating passwords</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​SHIFT_​DOUBLE_​CLICK_​ACTION</constant></entry> + <entry><literal>0x17</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​BYTES</constant></entry> + <entry>action on pressing shift and double clicking</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​PASSWORD_​POLICY_​NAME</constant></entry> + <entry><literal>0x18</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​TEXT</constant></entry> + <entry>name of password policy saved in the header</entry> + </row> + <row> + <entry><constant>PWS3_​RECORD_​FIELD_​KEYBOARD_​SHORTCUT</constant></entry> + <entry><literal>0x19</literal></entry> + <entry><constant>PWS_​DATA_​TYPE_​BYTES</constant></entry> + <entry>keyboard shortcut</entry> + </row> + </tbody> + </tgroup> + </table> + </para> + <para>The <function>pws3_record_create()</function> function allocates + and creates a record data structure, generates an UUID record field and + adds it to the record.</para> + <para>The <function>pws3_record_destroy()</function> function deallocates + the given record data structure and all its record fields.</para> + <para>The <function>pws3_file_record_field_set()</function> function sets + the record field on the given record, replacing an existing field of the + same type.</para> + <para>The <function>pws3_file_record_field_get()</function> function + returns a pointer to the record field data structure of the given record + field type.</para> + <para>The <function>pws3_file_record_field_remove()</function> 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.</para> + <para>The <function>pws3_file_insert_record()</function> function inserts + the given record into the file, an existing record with the same UUID is + replaced.</para> + <para>The <function>pws3_file_get_record()</function> function returns a + pointer to the record structure representing a record with the given + UUID.</para> + <para>The <function>pws3_file_remove_record()</function> 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.</para> + <para>The <function>pws3_file_first_record()</function> function returns a + pointer to the first record.</para> + <para>The <function>pws3_file_last_record()</function> function returns a + pointer to the last record.</para> + <para>The <function>pws3_file_next_record()</function> function returns a + pointer to the next record following the given + <parameter>record</parameter>.</para> + <para>The <function>pws3_file_prev_record()</function> + function returns a pointer to the previous group preceding the given + <parameter>record</parameter>.</para> + </refsect2> + <refsect2> + <title>Macros</title> + <para>The macro <constant>PWS3_VERSION</constant> contains the supported + version of the Password Safe version 3 file format.</para> + <para>The macro <constant>PWS3_MAX_FIELD_SIZE</constant> contains the + maxium size for header and record fields in bytes and + <constant>PWS3_MAX_PASSWORD_LEN</constant> contains the maxium password + length in bytes.</para> + <para>The macro <constant>PWS3_UUID_SIZE</constant> contains the size of + UUIDs in bytes.</para> + </refsect2> + </refsect1> + <refsect1> + <title>Return Values</title> + <para>The <function>pws3_file_create()</function> function returns a + pointer to a Password Safe file data structure if successful and + <constant>NULL</constant> in case of an error.</para> + <para>The <function>pws3_file_read_mem()</function>, + <function>pws3_file_read_stream()</function>, + <function>pws3_file_write_mem()</function>, and + <function>pws3_file_write_stream()</function> functions return + <returnvalue>0</returnvalue> on success and <returnvalue>-1</returnvalue> + to indicate an error.</para> + <para>The <function>pws3_file_get_header_field()</function> function + returns a pointer to the header field data structure of the requested type + and <constant>NULL</constant> if such a field does not exist.</para> + <para>The <function>pws3_file_remove_header_field()</function> function + returns a pointer to the header field data structure which was removed from + the file or <constant>NULL</constant> if such a field does not exist.</para> + <para>The <function>pws3_file_get_empty_group()</function> function returns + a pointer to the header field data structure corresponding to the requested + empty group and <constant>NULL</constant> if a group of that name does not + exist.</para> + <para>The <function>pws3_file_remove_empty_group()</function> function + returns a pointer to the header field data structure of the empty group + which was removed from the file or <constant>NULL</constant> if a group of + that name does not exist.</para> + <para>The <function>pws3_file_first_empty_group()</function> function + returns a pointer to the first of the empty group header fields or + <constant>NULL</constant> if there are no such fields.</para> + <para>The <function>pws3_file_last_empty_group()</function> function + returns a pointer to the last of the empty group header fields or + <constant>NULL</constant> if there are no such fields.</para> + <para>The <function>pws3_file_next_empty_group()</function> function + returns a pointer to the next empty group header field or + <constant>NULL</constant> if there are no more such fields.</para> + <para>The <function>pws3_file_prev_empty_group()</function> function + returns a pointer to the previous empty group header field or + <constant>NULL</constant> if there are no more such fields.</para> + <para>The <function>pws3_file_get_record()</function> function returns a + pointer to the record data structure of the requested record or + <constant>NULL</constant> if that record does not exist.</para> + <para>The <function>pws3_file_remove_record()</function> function returns a + pointer to the record data structure which was removed from the file or + <constant>NULL</constant> if no such record exists.</para> + <para>The <function>pws3_file_first_record()</function> function returns a + pointer to the record data structure of the first record or + <constant>NULL</constant> if no records exist.</para> + <para>The <function>pws3_file_last_record()</function> function returns a + pointer to the record data structure of the last record or + <constant>NULL</constant> if no records exist.</para> + <para>The <function>pws3_file_next_record()</function> function returns a + pointer to the record data structure of the next record or + <constant>NULL</constant> if no records exist.</para> + <para>The <function>pws3_file_prev_record()</function> function returns a + pointer to the record data structure of the previous record or + <constant>NULL</constant> if no records exist.</para> + <para>The <function>pws3_field_create()</function> function returns a + pointer to the new header field data structure on success and + <constant>NULL</constant> on failure.</para> + <para>The <function>pws3_field_get_type()</function> function returns + the field type of the header field structure.</para> + <para>The <function>pws3_field_get_data_type()</function> function + returns the data type of the header field structure.</para> + <para>The <function>pws3_field_set_uuid()</function>, + <function>pws3_field_set_text()</function>, + <function>pws3_field_set_time()</function>, + <function>pws3_field_set_uint8()</function>, + <function>pws3_field_set_uint16()</function>, + <function>pws3_field_set_uint32()</function>, and + <function>pws3_field_set_bytes()</function> functions return + <returnvalue>0</returnvalue> on success and <returnvalue>-1</returnvalue> + on failure.</para> + <para>The <function>pws3_field_get_time()</function>, + <function>pws3_field_get_uint8()</function>, + <function>pws3_field_get_uint16()</function>, and + <function>pws3_field_get_uint32()</function> functions return a + value of the type corresponding to the type of header field.</para> + <para>The <function>pws3_field_get_uuid()</function> function + returns a pointer to a UUID.</para> + <para>The <function>pws3_field_get_text()</function> function + returns a pointer to a string or <constant>NULL</constant> if no value has + been set.</para> + <para>The <function>pws3_record_create()</function> function returns a + pointer to a record data structure if successful and + <constant>NULL</constant> on failure.</para> + <para>The <function>pws3_record_get_field()</function> function returns a + pointer to the record field data structure of the requested type or + <constant>NULL</constant> if such a field does not exist.</para> + <para>The <function>pws3_record_remove_field()</function> function returns + a pointer to the record field data structure which was removed from the + record or <constant>NULL</constant> if such a field does not exist.</para> + </refsect1> + <refsect1> + <title>Errors</title> + <para>If the <function>pws3_file_read_mem()</function>, + <function>pws3_file_read_stream()</function>, + <function>pws3_file_write_mem()</function>, and + <function>pws3_file_write_stream()</function> functions fail, an error code + indicating the nature of the error may be obtained using the + <function>pws3_file_get_error_code()</function> function and a pointer to a + detailed error message may be retrieved using the + <function>pws3_file_get_error_message()</function> function. The above + functions may fail if:</para> + <variablelist> + <varlistentry> + <term><errorname>PWS_ERR_GENERIC_ERROR</errorname></term> + <listitem> + <para>An unknown error occurred.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><errorname>PWS_ERR_NO_MEMORY</errorname></term> + <listitem> + <para>There was not enough space to allocate memory.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><errorname>PWS_ERR_IO_ERROR</errorname></term> + <listitem> + <para>An I/O error occurred.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><errorname>PWS_ERR_TRUNCATED_FILE</errorname></term> + <listitem> + <para>The file appears to be truncated.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><errorname>PWS_ERR_INVALID_CHECKSUM</errorname></term> + <listitem> + <para>The calculated checksum does not match the checksum of the + file.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><errorname>PWS_ERR_INVALID_RECORD</errorname></term> + <listitem> + <para>A record is invalid.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><errorname>PWS_ERR_INVALID_HEADER</errorname></term> + <listitem> + <para>A header is invalid.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><errorname>PWS_ERR_UNSUPPORTED_VERSION</errorname></term> + <listitem> + <para>The file format version is not supported.</para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + <refsect1> + <title>Examples</title> + <example> + <title>Creating a Password Safe file</title> + <para>The following code creates a new Password Safe file and sets the + save application header field:</para> + <programlisting> +<![CDATA[ +#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); +]]> +</programlisting> + </example> + <example> + <title>Print the title of each record</title> + <para>The following code loops over each record of an existing Password + Safe file and prints the content of the title field if it exists:</para> + <programlisting> +<![CDATA[ +#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"); +} +]]> +</programlisting> + </example> + <example> + <title>Add a new record to a file</title> + <para>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:</para> + <programlisting> +<![CDATA[ +#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); +]]> +</programlisting> + </example> + <example> + <title>Reading a Password Safe file</title> + <para>The following code opens a Password Safe file named + <filename>example.pwsafe3</filename> and parses it:</para> + <programlisting> +<![CDATA[ +#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 */ +} +]]> +</programlisting> + </example> + <example> + <title>Writing a Password Safe file</title> + <para>The following code writes a Password Safe file to a file + named <filename>example.pwsafe3</filename>:</para> + <programlisting> +<![CDATA[ +#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); +]]> +</programlisting> + </example> + </refsect1> + <refsect1> + <title>See Also</title> + <para><citerefentry><refentrytitle>libpws</refentrytitle> + <manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>pws_init</refentrytitle> + <manvolnum>3</manvolnum></citerefentry>, + <link xlink:href="https://pwsafe.org/"/></para> + </refsect1> +</refentry>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pws_init.3.xml Wed Mar 25 17:10:23 2015 +0100 @@ -0,0 +1,159 @@ +<?xml version="1.0"?> +<!-- + +Copyright (C) 2015 Guido Berhoerster <guido+libpws@berhoerster.name> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--> +<refentry xmlns="http://docbook.org/ns/docbook" xml:lang="en"> + <info> + <author> + <personname> + <firstname>Guido</firstname> + <surname>Berhoerster</surname> + </personname> + <email>guido+libpws@berhoerster.name</email> + <personblurb/> + </author> + <date>21 March, 2015</date> + </info> + <refmeta> + <refentrytitle>libpws</refentrytitle> + <manvolnum>3</manvolnum> + <refmiscinfo class="source"/> + <refmiscinfo class="version"/> + <refmiscinfo class="manual">Library Functions</refmiscinfo> + </refmeta> + <refnamediv> + <refname>pws_init</refname> + <refname>pws_finalize</refname> + <refname>pws_set_alloc_functions</refname> + <refname>pws_generate_uuid</refname> + <refpurpose>initalize and deinitialize libpws</refpurpose> + </refnamediv> + <refsynopsisdiv> + <cmdsynopsis> + <command>cc</command> + <arg choice="opt" rep="repeat"> + <option>flag</option> + </arg> + <arg choice="plain" rep="repeat"> + <option>file</option> + </arg> + <arg choice="plain"> + <option>-lpws</option> + </arg> + <arg choice="plain"> + <option>-lnettle</option> + </arg> + <arg choice="opt" rep="repeat"> + <option>library</option> + </arg> + </cmdsynopsis> + <funcsynopsis> + <funcsynopsisinfo> +#include <pws.h> +</funcsynopsisinfo> + <funcprototype> + <funcdef>int <function>pws_init</function></funcdef> + <void/> + </funcprototype> + <funcprototype> + <funcdef>void <function>pws_finalize</function></funcdef> + <void/> + </funcprototype> + <funcprototype> + <funcdef>void <function>pws_set_alloc_functions</function></funcdef> + <paramdef>void + *<funcparams>*<replaceable>alloc_function</replaceable></funcparams><funcparams>size_t</funcparams></paramdef> + <paramdef>void + *<funcparams>*<replaceable>realloc_function</replaceable></funcparams><funcparams>void *, size_t</funcparams></paramdef> + <paramdef>void <funcparams>*<replaceable>free_function</replaceable></funcparams><funcparams>void + *, size_t</funcparams></paramdef> + <paramdef>void + *<funcparams>*<replaceable>secure_alloc_function</replaceable></funcparams><funcparams>size_t</funcparams></paramdef> + <paramdef>void + *<funcparams>*<replaceable>secure_realloc_function</replaceable></funcparams><funcparams>void *, size_t</funcparams></paramdef> + <paramdef>void <funcparams>*<replaceable>secure_free_function</replaceable></funcparams><funcparams>void + *, size_t</funcparams></paramdef> + </funcprototype> + <funcprototype> + <funcdef>int <function>pws_generate_uuid</function></funcdef> + <paramdef>unsigned char [static PWS3_UUID_SIZE]</paramdef> + </funcprototype> + </funcsynopsis> + <synopsis> +<constant>LIBPWS_VERSION_MAJOR</constant> + +<constant>LIBPWS_VERSION_MINOR</constant> + +<constant>LIBPWS_VERSION_MICRO</constant> + </synopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para>The <function>pws_init()</function> function initializes + <citerefentry><refentrytitle>libpws</refentrytitle><manvolnum>3</manvolnum></citerefentry> + and must be called before any other function from this library.</para> + <para>The <function>pws_finalize()</function> function deinitializes + <citerefentry><refentrytitle>libpws</refentrytitle><manvolnum>3</manvolnum></citerefentry> + after which no other function from this library may be called.</para> + <para>The <function>pws_set_alloc_functions()</function> function specifies + the functions which are used by + <citerefentry><refentrytitle>libpws</refentrytitle><manvolnum>3</manvolnum></citerefentry> + to allocate, reallocate or free memory allowing for the use of custom + allocators. <function>pws_secure_alloc</function>, + <function>pws_secure_realloc</function>, and + <function>pws_secure_free</function> are used to allocate, reallocate, and + free memory containing potentially sensitive information such as passwords, + this e.g. allows for wrapping the acutal allocation using operating system + specific facilities to prevent memory from being paged to the swap area or + to overwrite memory before deallocating it. Any argument set to + <constant>NULL</constant> will result in the default function being used, + these are <function>malloc</function>, <function>realloc</function>, and a + wrapper around <function>free</function>. This function must be called + after <function>pws_init</function> and before calling any other function + from this library. It is not reentrant.</para> + <para>The <function>pws_uuid_create()</function> function generates a new + random UUID following RFC4122 and places it in the array passed to + it.</para> + <para>The macros <constant>LIBPWS_VERSION_MAJOR</constant>, + <constant>LIBPWS_VERSION_MINOR</constant>, and + <constant>LIBPWS_VERSION_MICRO</constant> can be used to check the major, + minor, and micro version of the library.</para> + </refsect1> + <refsect1> + <title>Return Values</title> + <para>The <function>pws_init()</function> function returns + <returnvalue>0</returnvalue> if the library was initialized successfully and + <returnvalue>-1</returnvalue> on failure.</para> + <para>The <function>pws_generate_uuid()</function> returns + <returnvalue>0</returnvalue> if a new random UUID has been generated and + <returnvalue>-1</returnvalue> on failure.</para> + </refsect1> + <refsect1> + <title>See Also</title> + <para><citerefentry><refentrytitle>libpws</refentrytitle> + <manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>pws3_file_create</refentrytitle> + <manvolnum>3</manvolnum></citerefentry>, RFC4122</para> + </refsect1> +</refentry>