2021-09-16 00:58:49 +00:00
|
|
|
{ lib
|
|
|
|
, fetchFromGitHub
|
|
|
|
, runCommand
|
|
|
|
, yallback
|
|
|
|
, yara
|
|
|
|
}:
|
|
|
|
|
|
|
|
/* TODO/CAUTION:
|
|
|
|
|
|
|
|
I don't want to discourage use, but I'm not sure how stable
|
|
|
|
the API is. Have fun, but be prepared to track changes! :)
|
|
|
|
|
|
|
|
For _now_, binlore is basically a thin wrapper around
|
|
|
|
`<invoke yara> | <postprocess with yallback>` with support
|
|
|
|
for running it on a derivation, saving the result in the
|
|
|
|
store, and aggregating results from a set of packages.
|
|
|
|
|
|
|
|
In the longer term, I suspect there are more uses for this
|
|
|
|
general pattern (i.e., run some analysis tool that produces
|
|
|
|
a deterministic output and cache the result per package...).
|
|
|
|
|
|
|
|
I'm not sure how that'll look and if it'll be the case that
|
|
|
|
binlore automatically collects all of them, or if you'll be
|
|
|
|
configuring which "kind(s)" of lore it generates. Nailing
|
|
|
|
that down will almost certainly mean reworking the API.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
let
|
|
|
|
src = fetchFromGitHub {
|
|
|
|
owner = "abathur";
|
|
|
|
repo = "binlore";
|
2022-04-08 06:43:34 +00:00
|
|
|
rev = "v0.2.0";
|
|
|
|
hash = "sha256-bBJky7Km+mieHTqoMz3mda3KaKxr9ipYpfQqn/4w8J0=";
|
2021-09-16 00:58:49 +00:00
|
|
|
};
|
|
|
|
/*
|
|
|
|
binlore has one one more yallbacks responsible for
|
|
|
|
routing the appropriate lore to a named file in the
|
|
|
|
appropriate format. At some point I might try to do
|
|
|
|
something fancy with this, but for now the answer to
|
|
|
|
*all* questions about the lore are: the bare minimum
|
|
|
|
to get resholve over the next feature hump in time to
|
|
|
|
hopefully slip this feature in before the branch-off.
|
|
|
|
*/
|
|
|
|
# TODO: feeling really uninspired on the API
|
|
|
|
loreDef = {
|
|
|
|
# YARA rule file
|
2022-10-16 13:20:24 +00:00
|
|
|
rules = (src + "/execers.yar");
|
2021-09-16 00:58:49 +00:00
|
|
|
# output filenames; "types" of lore
|
|
|
|
types = [ "execers" "wrappers" ];
|
|
|
|
# shell rule callbacks; see github.com/abathur/yallback
|
2022-10-16 13:20:24 +00:00
|
|
|
yallback = (src + "/execers.yall");
|
2021-09-16 00:58:49 +00:00
|
|
|
# TODO:
|
|
|
|
# - echo for debug, can be removed at some point
|
|
|
|
# - I really just wanted to put the bit after the pipe
|
|
|
|
# in here, but I'm erring on the side of flexibility
|
|
|
|
# since this form will make it easier to pilot other
|
|
|
|
# uses of binlore.
|
|
|
|
callback = lore: drv: overrides: ''
|
2022-04-08 06:43:34 +00:00
|
|
|
if [[ -d "${drv}/bin" ]] || [[ -d "${drv}/lib" ]] || [[ -d "${drv}/libexec" ]]; then
|
2021-09-16 00:58:49 +00:00
|
|
|
echo generating binlore for $drv by running:
|
2022-04-08 06:43:34 +00:00
|
|
|
echo "${yara}/bin/yara --scan-list --recursive ${lore.rules} <(printf '%s\n' ${drv}/{bin,lib,libexec}) | ${yallback}/bin/yallback ${lore.yallback}"
|
2021-09-16 00:58:49 +00:00
|
|
|
else
|
2022-04-08 06:43:34 +00:00
|
|
|
echo "failed to generate binlore for $drv (none of ${drv}/{bin,lib,libexec} exist)"
|
2021-09-16 00:58:49 +00:00
|
|
|
fi
|
|
|
|
'' +
|
|
|
|
/*
|
|
|
|
Override lore for some packages. Unsure, but for now:
|
|
|
|
1. start with the ~name (pname-version)
|
|
|
|
2. remove characters from the end until we find a match
|
|
|
|
in overrides/
|
|
|
|
3. execute the override script with the list of expected
|
|
|
|
lore types
|
|
|
|
*/
|
|
|
|
''
|
|
|
|
i=''${#identifier}
|
|
|
|
filter=
|
|
|
|
while [[ $i > 0 ]] && [[ -z "$filter" ]]; do
|
|
|
|
if [[ -f "${overrides}/''${identifier:0:$i}" ]]; then
|
|
|
|
filter="${overrides}/''${identifier:0:$i}"
|
|
|
|
echo using "${overrides}/''${identifier:0:$i}" to generate overriden binlore for $drv
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
((i--)) || true # don't break build
|
|
|
|
done # || true # don't break build
|
2022-04-08 06:43:34 +00:00
|
|
|
if [[ -d "${drv}/bin" ]] || [[ -d "${drv}/lib" ]] || [[ -d "${drv}/libexec" ]]; then
|
|
|
|
${yara}/bin/yara --scan-list --recursive ${lore.rules} <(printf '%s\n' ${drv}/{bin,lib,libexec}) | ${yallback}/bin/yallback ${lore.yallback} "$filter"
|
2021-09-16 00:58:49 +00:00
|
|
|
fi
|
|
|
|
'';
|
|
|
|
};
|
2022-10-16 13:20:24 +00:00
|
|
|
overrides = (src + "/overrides");
|
2021-09-16 00:58:49 +00:00
|
|
|
|
|
|
|
in rec {
|
2022-04-08 06:43:34 +00:00
|
|
|
collect = { lore ? loreDef, drvs, strip ? [ ] }: (runCommand "more-binlore" { } ''
|
2021-09-16 00:58:49 +00:00
|
|
|
mkdir $out
|
|
|
|
for lorefile in ${toString lore.types}; do
|
2022-04-08 06:43:34 +00:00
|
|
|
cat ${lib.concatMapStrings (x: x + "/$lorefile ") (map (make lore) (map lib.getBin (builtins.filter lib.isDerivation drvs)))} > $out/$lorefile
|
|
|
|
substituteInPlace $out/$lorefile ${lib.concatMapStrings (x: "--replace '${x}/' '' ") strip}
|
2021-09-16 00:58:49 +00:00
|
|
|
done
|
|
|
|
'');
|
|
|
|
# TODO: echo for debug, can be removed at some point
|
|
|
|
make = lore: drv: runCommand "${drv.name}-binlore" {
|
|
|
|
identifier = drv.name;
|
|
|
|
drv = drv;
|
|
|
|
} (''
|
|
|
|
mkdir $out
|
|
|
|
touch $out/{${builtins.concatStringsSep "," lore.types}}
|
|
|
|
|
|
|
|
${lore.callback lore drv overrides}
|
|
|
|
|
|
|
|
echo binlore for $drv written to $out
|
|
|
|
'');
|
|
|
|
}
|