- Zig 98.8%
- C 1.2%
| .forgejo/workflows | changed runs on | |
| c | added test for accessing entries of a group | |
| docs | more documentation added | |
| src | fixed error in new interface for Entry | |
| .gitignore | tests pass with Zig 0.16.0 | |
| build.zig | updated to compile with Zig 0.16.0 | |
| build.zig.zon | updated to compile with Zig 0.16.0 | |
| README.md | changed interface for callng open() and new() | |
KDBX - Keepass Database XML
This Zig module allows you to integrate KDBX support into your application. This format is used by password databases like KeePass and KeePassXC to store passwords, passkeys and other credentials.
Currently only KDBX4 is supported.
Gzip support is currently disabled when using
Database.save. Gzip compression is automatically disabled for databases (see #4). This has NO security implications but will slightly increase the database size.
Getting Started
(追記) Zig (追記ここまで)
First add this project as a dependency to your build.zig.zon file:
# Replace <VERSION TAG> with the version you want to use ...
zig fetch --save https://codeberg.org/r4gus/kdbx/archive/<VERSION TAG>.tar.gz
# e.g. zig fetch --save https://codeberg.org/r4gus/kdbx/archive/0.5.0.tar.gz
# ... or use the master branch
zig fetch --save git+https://codeberg.org/r4gus/kdbx
Then, within your build.zig add the following code:
constkdbx_dep=b.dependency("kdbx",.{.target=target,.optimize=optimize,});constkdbx_module=kdbx_dep.module("kdbx");// ...exe.root_module.addImport("kdbx",kdbx_module);Then within your project just use @import("kdbx").
(追記) C/ C++ (追記ここまで)
Comming soon...
Usage
(追記) Zig (追記ここまで)
Reading a database
conststd=@import("std");constkdbx=@import("kdbx");vargpa=std.heap.GeneralPurposeAllocator(.{}){};constallocator=gpa.allocator();pubfnmain(init:std.process.Init)!void{varf=trystd.Io.Dir.cwd().openFile("test.kdbx",init.io.{});deferf.close(io);// Please always use a buffer and NOT '&.{}' as there// seems to be a bug with the reader interface when using// no buffer.varbuffer:[1024]u8=undefined;varreader=f.reader(init.io,&buffer);constdb_key=kdbx.DatabaseKey{.password=tryallocator.dupe(u8,"1234"),.allocator=allocator,};deferdb_key.deinit();vardatabase=trykdbx.Database.open(&reader.interface,allocator,io,.{.key=db_key,});deferdatabase.deinit();// The root group can be accessed via `database.body.root`.// Iterate over all entries of the root group:for(database.body.root.entries.items)|entry|{_=entry;//... do something with the entry}// Iterate over all groups of the root group:for(database.body.root.groups.items)|group|{_=group;//... do something with the group. Each group// can contain more entries and groups.}}Writing a database
When saving, the inner XML data structure is generated from the Zig objects that represent the database, i.e., unsupported fields are lost when reading and then writing a existing database.
If in doubt, backup your database!
Feel free to open pull requests for missing features.
conststd=@import("std");constkdbx=@import("kdbx");vargpa=std.heap.GeneralPurposeAllocator(.{}){};constallocator=gpa.allocator();pubfnmain(init:std.process.Init)!void{// First we create a new database.vardatabase=trykdbx.Database.new(allocator,init.io,.{});deferdatabase.deinit();// Now lets create an entry.varentry1=kdbx.Entry.new(allocator);errdeferentry1.deinit();tryentry1.set(init.io,"Title","Demo Entry",false);tryentry1.set(init.io,"UserName","max",false);tryentry1.set(init.io,"Password","supersecret",true);// Then we add the entry to our newly created database.trydatabase.body.root.addEntry(entry1);// To save the database, we need to select a database key/ password.// We can use the same key to later decrypt the database.constdb_key=kdbx.DatabaseKey{.password=tryallocator.dupe(u8,"1234"),.allocator=allocator,};deferdb_key.deinit();// A database can be saved by calling the `save` function on// a database object. The function expects a writer as the first// argument. This makes it easy to write the database to different// container types (e.g. a ArrayList as seen below) or a file.varsaved_db=std.Io.Writer.Allocating.init(allocator);defersaved_db.deinit();trydatabase.save(&saved_db.writer,db_key,allocator,init.io);}(追記) C/ C++ (追記ここまで)
The C library is work in progress.
You can find an example in c/examples/cexample1.c
Comming soon...