Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ lib 2, fetchFromGitHub 3, runCommand 4, yallback 5, yara 6}: 7 8/* TODO/CAUTION: 9 10I don't want to discourage use, but I'm not sure how stable 11the API is. Have fun, but be prepared to track changes! :) 12 13For _now_, binlore is basically a thin wrapper around 14`<invoke yara> | <postprocess with yallback>` with support 15for running it on a derivation, saving the result in the 16store, and aggregating results from a set of packages. 17 18In the longer term, I suspect there are more uses for this 19general pattern (i.e., run some analysis tool that produces 20a deterministic output and cache the result per package...). 21 22I'm not sure how that'll look and if it'll be the case that 23binlore automatically collects all of them, or if you'll be 24configuring which "kind(s)" of lore it generates. Nailing 25that down will almost certainly mean reworking the API. 26 27*/ 28 29let 30 src = fetchFromGitHub { 31 owner = "abathur"; 32 repo = "binlore"; 33 rev = "v0.2.0"; 34 hash = "sha256-bBJky7Km+mieHTqoMz3mda3KaKxr9ipYpfQqn/4w8J0="; 35 }; 36 /* 37 binlore has one one more yallbacks responsible for 38 routing the appropriate lore to a named file in the 39 appropriate format. At some point I might try to do 40 something fancy with this, but for now the answer to 41 *all* questions about the lore are: the bare minimum 42 to get resholve over the next feature hump in time to 43 hopefully slip this feature in before the branch-off. 44 */ 45 # TODO: feeling really uninspired on the API 46 loreDef = { 47 # YARA rule file 48 rules = (src + "/execers.yar"); 49 # output filenames; "types" of lore 50 types = [ "execers" "wrappers" ]; 51 # shell rule callbacks; see github.com/abathur/yallback 52 yallback = (src + "/execers.yall"); 53 # TODO: 54 # - echo for debug, can be removed at some point 55 # - I really just wanted to put the bit after the pipe 56 # in here, but I'm erring on the side of flexibility 57 # since this form will make it easier to pilot other 58 # uses of binlore. 59 callback = lore: drv: overrides: '' 60 if [[ -d "${drv}/bin" ]] || [[ -d "${drv}/lib" ]] || [[ -d "${drv}/libexec" ]]; then 61 echo generating binlore for $drv by running: 62 echo "${yara}/bin/yara --scan-list --recursive ${lore.rules} <(printf '%s\n' ${drv}/{bin,lib,libexec}) | ${yallback}/bin/yallback ${lore.yallback}" 63 else 64 echo "failed to generate binlore for $drv (none of ${drv}/{bin,lib,libexec} exist)" 65 fi 66 '' + 67 /* 68 Override lore for some packages. Unsure, but for now: 69 1. start with the ~name (pname-version) 70 2. remove characters from the end until we find a match 71 in overrides/ 72 3. execute the override script with the list of expected 73 lore types 74 */ 75 '' 76 i=''${#identifier} 77 filter= 78 while [[ $i > 0 ]] && [[ -z "$filter" ]]; do 79 if [[ -f "${overrides}/''${identifier:0:$i}" ]]; then 80 filter="${overrides}/''${identifier:0:$i}" 81 echo using "${overrides}/''${identifier:0:$i}" to generate overriden binlore for $drv 82 break 83 fi 84 ((i--)) || true # don't break build 85 done # || true # don't break build 86 if [[ -d "${drv}/bin" ]] || [[ -d "${drv}/lib" ]] || [[ -d "${drv}/libexec" ]]; then 87 ${yara}/bin/yara --scan-list --recursive ${lore.rules} <(printf '%s\n' ${drv}/{bin,lib,libexec}) | ${yallback}/bin/yallback ${lore.yallback} "$filter" 88 fi 89 ''; 90 }; 91 overrides = (src + "/overrides"); 92 93in rec { 94 collect = { lore ? loreDef, drvs, strip ? [ ] }: (runCommand "more-binlore" { } '' 95 mkdir $out 96 for lorefile in ${toString lore.types}; do 97 cat ${lib.concatMapStrings (x: x + "/$lorefile ") (map (make lore) (map lib.getBin (builtins.filter lib.isDerivation drvs)))} > $out/$lorefile 98 substituteInPlace $out/$lorefile ${lib.concatMapStrings (x: "--replace '${x}/' '' ") strip} 99 done 100 ''); 101 # TODO: echo for debug, can be removed at some point 102 make = lore: drv: runCommand "${drv.name}-binlore" { 103 identifier = drv.name; 104 drv = drv; 105 } ('' 106 mkdir $out 107 touch $out/{${builtins.concatStringsSep "," lore.types}} 108 109 ${lore.callback lore drv overrides} 110 111 echo binlore for $drv written to $out 112 ''); 113}