KeyNub::LicDongle
KeyNub License Dongle ā Raku Distribution
use KeyNub::LicDongle;
my $secret = KeyNub::LicDongle::open(-> $d { # first dongle, or open('serial', -> $d { ... })
$d.verify-genuine; # dies unless genuine
$d.session({ # closed on every exit path
$d.app-decrypt($sealed) # <- build the licence check on this
})
});Nothing compiled. The distribution calls the SDK's flat companion API through NativeCall, which loads the native library at run time, so there is no extension to build and nothing sits in the path of the check that a customer could substitute. No dependencies beyond Rakudo itself (NativeCall is part of it); Raku 6.d, on Windows, Linux and macOS.
Setup
zef install KeyNub::LicDongleThe distribution does not carry the native library. In a clone of the SDK
repository it finds keynub_licdongle_flat for your platform in
natives/<platform>/ on its own, from the program's folder and the working
directory upwards, so the samples run with nothing set. Elsewhere, take the
library from the SDK's
natives folder
and put it in natives/<platform>/ beside your program, where the operating
system finds libraries (PATH, LD_LIBRARY_PATH, DYLD_LIBRARY_PATH), or
name it before the first call:
KeyNub::LicDongle::library-path('/opt/keynub/libkeynub_licdongle_flat.so');KEYNUB_LICDONGLE_FLAT_LIBRARY in the environment does the same. A process
loads the library once; KeyNub::LicDongle::loaded-library-path() tells which,
and library-path with a different file after that dies. On Linux, install
the udev rule described in
NATIVES.md
so the dongle is accessible without root.
Notes
Every failed call dies with
X::KeyNub::LicDongle, which carriesstatus(KeyNub::LicDongle::Status::NoDevice,Status::NotGenuine,Status::AuthRequired, ...), the rawcode, theoperationand the library'sdetailtext. Loading problems die withX::KeyNub::LicDongle::Library.CATCH { when X::KeyNub::LicDongle { say 'no dongle' if .status === KeyNub::LicDongle::Status::NoDevice; } }Results are objects (
Info,Genuine,Device,Record) with kebab-case accessors (.data-free,.write-auth-rotated);library-versionis aVersion; byte data is aBlobin and aBufout. The distribution calls the SDK's flat API: integer handles and caller-provided buffers, no C structures and no hand-written layouts.The block forms
KeyNub::LicDongle::open,Dongle.open,Dongle.open-pathand$d.sessionclose the dongle and the session on every exit path, exceptions included, and return what the block returns. ADongleopened without a block is closed byclose, or when it is collected.genuineis the boolean form for a gate and fails closed: every failure givesFalse.$d.trust-root = $deroverrides the CA root thatverify-genuinechecks against; applications do not need it.erase-all-recordsis separate fromerase-record($name): an accidentally empty name must not wipe the dongle.Records are transferred in one call; the flat API has no progress reporting.
Read docs/integration-security.md before writing the check.
exit 1 unless $d.genuineis one conditional branch, and editing one of those in a script is no effort at all. Route something the program needs throughapp-encryptandapp-decrypt, so removing the check removes the data.
Tests
zef test bindings/raku runs the tests of the distribution, which need
neither the native library nor a dongle.
raku -I bindings/raku/lib bindings/raku/test/standin_test.raku runs without
a dongle: it compiles a stand-in for the flat C API
(bindings/flat/licd_flat.c over bindings/julia/test/stub/licd_stub.c) with
the C compiler on the path and exercises every call against it.
KEYNUB_SDK_ROOT names the SDK sources when the distribution is not inside a
clone; KEYNUB_LICDONGLE_FLAT_LIBRARY names a compiled stand-in instead. The
samples are under samples/raku
(raku samples/raku/verify-and-read.raku).
Links
KeyNub License Dongle for Raku: the product, and how to order one
Source, samples and issue tracker on GitHub