diff options
author | Timo Teräs <timo.teras@iki.fi> | 2014-05-10 01:10:59 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2014-05-10 01:12:00 +0300 |
commit | 6fbca72d680bb7ce7bccb41c86becf1762b042c1 (patch) | |
tree | c4beb6bfd620ad2eca86079fa04452ad0e1b9618 /testing/aaudit | |
parent | 9562bf59198a9b1ae90daec9bad97d545a781080 (diff) | |
download | aports-6fbca72d680bb7ce7bccb41c86becf1762b042c1.tar.bz2 aports-6fbca72d680bb7ce7bccb41c86becf1762b042c1.tar.xz |
testing/aaudit: rewrite client in lua, use json in configs
also use json to talk between client and server. and make the
client program handle all command line flags.
Diffstat (limited to 'testing/aaudit')
-rw-r--r-- | testing/aaudit/APKBUILD | 76 | ||||
-rwxr-xr-x[-rw-r--r--] | testing/aaudit/aaudit | 79 | ||||
-rw-r--r-- | testing/aaudit/aaudit-common.lua | 31 | ||||
-rwxr-xr-x | testing/aaudit/aaudit-repo-create | 51 | ||||
-rwxr-xr-x | testing/aaudit/aaudit-repo-update | 25 | ||||
-rw-r--r-- | testing/aaudit/aaudit-server.conf | 29 | ||||
-rw-r--r-- | testing/aaudit/aaudit-server.json | 20 | ||||
-rw-r--r-- | testing/aaudit/aaudit-server.lua (renamed from testing/aaudit/aaudit.lua) | 194 | ||||
-rwxr-xr-x | testing/aaudit/aaudit-shell | 19 | ||||
-rwxr-xr-x | testing/aaudit/aaudit-update-keys | 18 | ||||
-rw-r--r-- | testing/aaudit/aaudit.json | 5 |
11 files changed, 326 insertions, 221 deletions
diff --git a/testing/aaudit/APKBUILD b/testing/aaudit/APKBUILD index f471ed92fa..5dcb358aca 100644 --- a/testing/aaudit/APKBUILD +++ b/testing/aaudit/APKBUILD @@ -1,57 +1,71 @@ # Contributor: Timo Teräs <timo.teras@iki.fi> # Maintainer: Timo Teräs <timo.teras@iki.fi> pkgname=aaudit -pkgver=0.3 +pkgver=0.4 pkgrel=0 pkgdesc="Alpine Auditor" url="http://alpinelinux.org" arch="noarch" license="GPL" -depends="" +depends="lua5.2 lua5.2-posix lua5.2-cjson" makedepends="" install="" subpackages="$pkgname-server" replaces="" -client_bin="aaudit" -server_bin="aaudit-repo-create aaudit-repo-update aaudit-shell" -server_lua="aaudit.lua" -source="$client_bin $server_lua $server_bin aaudit-server.conf" +source="aaudit-common.lua + aaudit-server.lua + aaudit + aaudit-shell + aaudit-update-keys + aaudit.json + aaudit-server.json + " +_luaver="5.2" build() { return 0 } package() { - mkdir -p "$pkgdir"/usr/bin - cp $client_bin "$pkgdir"/usr/bin + mkdir -p "$pkgdir"/etc/aaudit \ + "$pkgdir"/usr/bin \ + "$pkgdir"/usr/share/lua/$_luaver/aaudit + cp aaudit.json "$pkgdir"/etc/aaudit + cp aaudit-common.lua "$pkgdir"/usr/share/lua/$_luaver/aaudit/common.lua + cp aaudit "$pkgdir"/usr/bin } server() { - depends="lua5.2 lua5.2-posix git" + depends="aaudit git lua5.2 lua5.2-posix lua5.2-cjson" mkdir -p "$subpkgdir"/etc/aaudit \ "$subpkgdir"/usr/libexec/aaudit \ - "$subpkgdir"/usr/share/lua/5.2/ - cp aaudit-server.conf "$subpkgdir"/etc/aaudit - cp $server_lua "$subpkgdir"/usr/share/lua/5.2/ - cp $server_bin "$subpkgdir"/usr/libexec/aaudit + "$subpkgdir"/usr/bin \ + "$subpkgdir"/usr/share/lua/$_luaver/aaudit + cp aaudit-server.json "$subpkgdir"/etc/aaudit + cp aaudit-server.lua "$subpkgdir"/usr/share/lua/$_luaver/aaudit/server.lua + cp aaudit-update-keys "$subpkgdir"/usr/bin + cp aaudit-shell "$subpkgdir"/usr/libexec/aaudit } -md5sums="e8ea430114aab3f07704060605670e0b aaudit -c7733c44b464e6e8efe73826d075af17 aaudit.lua -b11fe0d8285a00a135f8ac9af0206449 aaudit-repo-create -b900f83afedc4fb1dae2f74c9380fb72 aaudit-repo-update -0958044c64d1b5c475939687a5620a41 aaudit-shell -274e2126de7f30170ad6d6acc1bb9ef1 aaudit-server.conf" -sha256sums="093ded6192adc7ee81ec1e435bac4652355950c30c573cbd0d2f9ab1307f1ade aaudit -c4e64cd76a23a6e10f944f88904ec7bc511be90af0659526745086fb732530f7 aaudit.lua -f01ecd5b99cadbc591d8472f6010d34ad3136085aa35c93d7da56b29a251f6c1 aaudit-repo-create -2c108a129411373be55a4e4add7ca5c005e05f1ca48be813e9903f7ef84f1e7e aaudit-repo-update -8a24abf3ff360f74afbf408d38ad5336a17f59bf0ec9ff553cae4fe0a4bfc376 aaudit-shell -23e75c1c935d2cd516c489c0c6835178e864595daef45975da54897296aebcf6 aaudit-server.conf" -sha512sums="b52acc614c4437ed54f348daeb887aca965b62b4e45bbd1f95b731f5e03b360277476b513254e05306387cdea1f196a86b4d9cf5bbc76916707164b45364521d aaudit -9d64ba1904639aca31f34aa384cdfce7ddefd17959dfb08904811015343e36959904707ff667879e0fa5587f199ff4dac0213a42d484f983801914dc61ae2899 aaudit.lua -a8c875eb726e267d6fb56f41cb5c39c45e6f8af8a7a55059bcaff8a0fe8498dac2c90bb21c88e37c34658c574bf2afa8f6ef24e725f602ee1153ba04d9cc84d5 aaudit-repo-create -e59320cbc6bd7a07687a261399b7df4ef00e349240bee64539a9dfd925b05fb6c679f0f8efb42d1429a7c1d6b918d429a6acb0bc3d4d7f6ef059f9562b748abf aaudit-repo-update -492f342115dfe1b622601d11edeb2e5bc87512412645c9f242ce5fe870e6c6a5ee333aa8e3dcb7f9b7f72ebce8b8cb88d6446af39255485c0bd3786ab2c81982 aaudit-shell -b370c408c242cb4d4c349ca2208e69cdc44c750990c8aacb62e2d8b018cdb87e25c5955fe144352f0fd5c41ff0329ed1118fb3a977aa40e13ddb6b115bf4dd2a aaudit-server.conf" +md5sums="b81b0707b297a69dacbc1606324de029 aaudit-common.lua +4ad8c883f09133a1b9357f7ac156040c aaudit-server.lua +b24162b7fa31161eab71485b1077f8ea aaudit +07c54e8cb44f195456be7a18b15a0be1 aaudit-shell +feef077f56f40002ca11846512d347af aaudit-update-keys +e14ded329626ca1d6dd48e5bef0bc7e2 aaudit.json +dc9a54c08ea299ad268301266f3da989 aaudit-server.json" +sha256sums="ee1998e730356c2de0ff9d5e27d9e0277e3c1f051777146b7c5b820437edfd7f aaudit-common.lua +3a9384089b0cb73c151b67eaedd66a244b48c0c2a86f5fe0ccadda6e0cbe8863 aaudit-server.lua +198b92b5a0eb8e13c3fad87f3afffda1e749243c785e72b54db190413a513595 aaudit +a99ab6908d780f07b756f5d2416924250b61e88c92ea0aa91af88a05dfc9edff aaudit-shell +660dcf86f02a9d0e3ff47cb359e0291a0921d03215e368552a2878d2d691a9cc aaudit-update-keys +f61efebc04756c8bfb7cb955b7af5db6a3c5dabdd005f690db812c7e77567cf5 aaudit.json +878fa7c12ddd28d679703cdf7ab31f69473609d16da9604545f78132cc59d562 aaudit-server.json" +sha512sums="aaa378fd710d17cb3663954648e97dd5128406cc6f37e9834075046aed1912dcc9e448b6c96502350b8d3496e00b7803cae671a4be2c12c584a84dc0b6e843e9 aaudit-common.lua +fa74091c9f8f2614f68d828560734b92f16b592b40e9552464ef84dc54f2600f7df91e9ba6159c3a91d54f8d4160078ac022e585633a87edc0cbc6e280a29be9 aaudit-server.lua +b15515979003382527842cf3fd0c150fb1ff96009518e7cd71c42ab0cf091cee000384d2b8b71c6cc8c4c93ee64cb70bef726d98b3e2b87fff9db7afbc83dc57 aaudit +974a4e733a61c07719ae75bc1ffc39f01d5adf7bc7f813aa358201bd18711eafeaa42705d9b8d4a869cdb27687091c8998b7eafd1d10a778a429d0efa787bda0 aaudit-shell +aec728a9a1e4c92baeb94a9d95e1785ea166652a157571fe2e848e71c1246635ecb99512e92435e1314c620b1fa8e4f37400350bed78bd375db4a63828c500f0 aaudit-update-keys +e769f0f77fe54ba1ab35efc80cc6426e34a2ee1d053ac9e7cc5aa316cfcef0c9658d2f0e2c47f7ae282bb9cc07107065fcc13034b2f9125c182378b7c73b7d99 aaudit.json +dcc099fe53603a09de225a888242ce329cdb51af3cd0a88dea23cb56d794eb2a442dcdf93b3db18158f8745d5d33de5c82d106f99b1c616fd4936512dfae75d8 aaudit-server.json" diff --git a/testing/aaudit/aaudit b/testing/aaudit/aaudit index 489fd30164..a1e835272f 100644..100755 --- a/testing/aaudit/aaudit +++ b/testing/aaudit/aaudit @@ -1,9 +1,70 @@ -#!/bin/sh -CONF="/etc/aaudit/aaudit.conf" -[ -r "$CONF" ] && . "$CONF" -AAUDIT_USER=${AAUDIT_USER:-aaudit} -if [ -z "$AAUDIT_SERVER" ]; then - echo "Initialize $CONF with AAUDIT_SERVER=<hostname> first!" - exit 0 -fi -exec ssh $AAUDIT_USER@$AAUDIT_SERVER "$@" +#!/usr/bin/lua5.2 + +local posix = require 'posix' +local json = require 'cjson' +local aac = require 'aaudit.common' + +local function usage() + print([[ +Usage: aaudit [create|commit] [OPTIONS...] + +Valid options for create: + -s SERV Use server SERV + -d DESC Description for repository (default: hostname) + -t ADDR Specify ADDR as target device (default: local source IP) + -m MSG Specify message for the initial commit + -g GRP Add in group GRP + +Valid options for commit: + -m MSG Specify message for the commit + -r RT Related to ticket RT + -c RT Closes ticket RT +]]) + os.exit(1) +end + +local conf = aac.readconfig() or {} +local req = {} + +for ret, optval in posix.getopt(arg, 's:d:t:m:g:r:c:') do + if ret == 's' then + conf.server = optval + elseif ret == 'd' then + conf.description = optval + elseif ret == 't' then + conf.target_address = optval + elseif ret == 'm' then + req.message = optval + elseif ret == 'g' then + req.groups = req.groups or {} + table.insert(req.groups, optval) + elseif ret == 'r' then + req.ticket = optval + elseif ret == 'c' then + req.ticket = optval + req.ticket_action = "close" + else + usage() + end +end + +if conf.server == nil then + print("Error: No server configured.") + usage() +end + +req.command = arg[1] +if arg[1] == "create" then + req.description = conf.description or aac.readfile("/etc/hostname"):gsub("\n","") + req.ssh_host_key = aac.readfile("/etc/ssh/ssh_host_ecdsa_key.pub") + or aac.readfile("/etc/ssh/ssh_host_dsa_key.pub") + or aac.readfile("/etc/ssh/ssh_host_rsa_key.pub") + aac.writeconfig(conf) +elseif arg[1] == "commit" then +else + usage() +end + +local F = io.popen(("ssh -T %s@%s "):format(conf.user or "aaudit", conf.server), "w") +F:write(json.encode(req)) +F:close() diff --git a/testing/aaudit/aaudit-common.lua b/testing/aaudit/aaudit-common.lua new file mode 100644 index 0000000000..d7b1bc4837 --- /dev/null +++ b/testing/aaudit/aaudit-common.lua @@ -0,0 +1,31 @@ +local M = {} + +local posix = require 'posix' +local json = require 'cjson' + +M.config = "/etc/aaudit/aaudit.json" + +function M.readfile(fn) + local F = io.open(fn, "r") + if F == nil then return nil end + local ret = F:read("*all") + F:close() + return ret +end + +function M.readconfig(fn) + fn = fn or M.config + local success, res = pcall(json.decode, M.readfile(fn)) + if not success then io.stderr:write(("Error reading %s: %s\n"):format(fn, res)) end + return res +end + +function M.writefile(content, fn) + assert(io.open(fn, "w")):write(content):close() +end + +function M.writeconfig(config, fn) + M.writefile(json.encode(config), fn or M.config) +end + +return M diff --git a/testing/aaudit/aaudit-repo-create b/testing/aaudit/aaudit-repo-create deleted file mode 100755 index 7b3ce91220..0000000000 --- a/testing/aaudit/aaudit-repo-create +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/lua5.2 - -local posix = require 'posix' -local aaudit = require 'aaudit' - -local function usage() - print("usage: aaudit-repo-create [-a ADDRESS] -d DESCRIPTION [-i COMMIT_IDENTITY] [-m COMMIT_MESSAGE] [-g GROUPS]") - os.exit(1) -end - -local C = { initial=true } -local groups = {} -local address, description - -for ret, optval in posix.getopt(arg, 'a:d:g:i:m:') do - if ret == 'a' then - address = optval - elseif ret == 'd' then - description = optval - elseif ret == 'g' then - groups['"'..optval..'"'] = true - elseif ret == 'i' then - C.identity = optval - elseif ret == 'm' then - C.message = optval - else - usage() - end -end - -if not address or not description then usage() end - --- For now default to use address as the repository name -local repo, repohome = address, aaudit.repohome(address) - --- Create repository + write config -os.execute(([[ -mkdir -p %s; cd %s -git init --quiet --bare -]]):format(repohome, repohome)) - -aaudit.write_file(("%s/aaudit.conf"):format(repohome), ([[ -address = "%s"; -description = "%s"; -groups = { %s }; -]]):format(address, description, table.concat(groups, ', '))) - -aaudit.write_file(("%s/description"):format(repohome), ("%s (%s)"):format(description, address)) - --- Initial import of configuration -aaudit.import_commit(repohome, C) diff --git a/testing/aaudit/aaudit-repo-update b/testing/aaudit/aaudit-repo-update deleted file mode 100755 index 3aa4cc5854..0000000000 --- a/testing/aaudit/aaudit-repo-update +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/lua5.2 - -local posix = require 'posix' -local aaudit = require 'aaudit' - -local function usage() - print("usage: aaudit-repo-update [-i COMMIT_IDENTITY] [-m COMMIT_MESSAGE]") - os.exit(1) -end - -local C = { } -local address -for ret, optval in posix.getopt(arg, 'a:i:m:') do - if ret == 'a' then - address = optval - elseif ret == 'i' then - C.identity = optval - elseif ret == 'm' then - C.message = optval - else - usage() - end -end - -aaudit.import_commit(aaudit.repohome(address), C) diff --git a/testing/aaudit/aaudit-server.conf b/testing/aaudit/aaudit-server.conf deleted file mode 100644 index 34ad9b2cec..0000000000 --- a/testing/aaudit/aaudit-server.conf +++ /dev/null @@ -1,29 +0,0 @@ --- smtp_server = "<server>"; - -identities = { -}; - -groups = { - all = { - notify_email = { "engineers@alpine.local" }; - track_filemode = true; - - no_track = { - "*/.git/*", - "*.apk-new", - "*~", - "etc/unbound/root.hints", - "etc/chrony/chrony.drift", - "etc/ld.so.cache", - }; - no_notify = { - "etc/acf/password", - }; - no_diff = { - "etc/shadow*", - "*.crt", - "*.pem", - "*.pfx", - }; - }; -}; diff --git a/testing/aaudit/aaudit-server.json b/testing/aaudit/aaudit-server.json new file mode 100644 index 0000000000..b2edcef650 --- /dev/null +++ b/testing/aaudit/aaudit-server.json @@ -0,0 +1,20 @@ +{ + "smtp_server": "localhost", + "identities": { + "_default": "Alpine Auditor <auditor@alpine.local>" + }, + "groups": { + "all": { + "notify_email": [ "Notify Group <config-changes@alpine.local>" ], + "track_filemode": true, + "no_track": [ + "*/.git/*", "*.apk-new", "*~", + "etc/unbound/root.hints", + "etc/chrony/chrony.drift", + "etc/ld.so.cache" + ], + "no_notify": [ "etc/acf/password" ], + "no_diff": [ "etc/shadow*", "*.crt","*.pem", "*.pfx" ] + } + } +} diff --git a/testing/aaudit/aaudit.lua b/testing/aaudit/aaudit-server.lua index 915c177e71..56fed28c14 100644 --- a/testing/aaudit/aaudit.lua +++ b/testing/aaudit/aaudit-server.lua @@ -1,40 +1,13 @@ local M = {} local posix = require 'posix' +local json = require 'cjson' +local aac = require 'aaudit.common' -function M.repohome(repo) - return ("%s/%s.git"):format(os.getenv("HOME"), repo) -end - -function M.write_file(filename, content) - assert(io.open(filename, "w")):write(content):close() -end - -local function load_config(filename) - local F = assert(io.open(filename, "r")) - local cfg = "return {" .. F:read("*all").. "}" - F:close() - return loadstring(cfg, "config:"..filename)() -end +local HOME = os.getenv("HOME") local function merge_bool(a, b) return a or b end -local function merge_dict(a, b) for k, v in pairs(b) do a[k] = v end return a end -local function merge_array(a, b) for i=1,#b do a[#a+1] = b[i] end return a end - -local function load_repo_configs(repohome) - local G = load_config(("%s/aaudit.conf"):format(os.getenv("HOME"))) - local R = load_config(("%s/aaudit.conf"):format(repohome)) - -- merge global and per-repository group configs - local RG = (G.groups or {}).all - for g in pairs(R.groups or {}) do - RG.notify_emails = merge_dict(RG.notify_emails, g.notify_emails) - RG.track_filemode = merge_bool(RG.track_filemode, g.track_filemode) - RG.no_track = merge_array(RG.no_track, g.no_track) - RG.no_notify = merge_array(RG.no_notify, g.no_notify) - RG.no_diff = merge_array(RG.no_diff, g.no_diff) - end - return G, R, RG -end +local function merge_array(a, b) if b then for i=1,#b do a[#a+1] = b[i] end end return a end local function match_file(fn, match_list) if not match_list then return false end @@ -96,7 +69,7 @@ local function read_header_block(block) return header end -local function import_tar(TAR, GIT, CI, RG) +local function import_tar(TAR, GIT, req, G) local branch_ref = "refs/heads/import" local from_ref = "refs/heads/master" local blocksize = 512 @@ -137,7 +110,7 @@ local function import_tar(TAR, GIT, CI, RG) end if header.typeflag:match("^[0-46]$") and - not match_file(header.name, RG.no_track) then + not match_file(header.name, G.no_track) then GIT:write('blob\n', 'mark :', nextmark, '\n') if header.typeflag == "2" then GIT:write('data ', tostring(#header.linkname), '\n', header.linkname, '\n') @@ -151,7 +124,7 @@ local function import_tar(TAR, GIT, CI, RG) if header.mtime > author_time then author_time = header.mtime end end end - if RG.track_filemode then + if G.track_filemode then GIT:write('blob\n', 'mark :', nextmark, '\n', 'data <<END_OF_PERMISSONS\n') for path, v in sortedpairs(all_files) do @@ -162,20 +135,20 @@ local function import_tar(TAR, GIT, CI, RG) GIT:write(([[ commit %s -author %s <%s> %d +0000 -committer %s <%s> %d +0000 +author %s %d +0000 +committer %s %d +0000 data <<END_OF_COMMIT_MESSAGE %s END_OF_COMMIT_MESSAGE ]]):format(branch_ref, - CI.identity_name, CI.identity_email, author_time, - CI.identity_name, CI.identity_email, os.time(), - CI.message or "Changes")) + req.author.rfc822, author_time, + req.author.rfc822, os.time(), + req.message or "Changes")) - if not CI.initial then GIT:write(("from %s^0\n"):format(from_ref)) end + if not req.initial then GIT:write(("from %s^0\n"):format(from_ref)) end GIT:write("deleteall\n") - if RG.track_filemode then + if G.track_filemode then GIT:write(("M %o :%i %s\n"):format(romode, nextmark, '.permissions.txt')) end local path, v @@ -195,8 +168,8 @@ END_OF_COMMIT_MESSAGE return true end -local function generate_diff(repohome, commit, RG) - local DIFF = io.popen(("cd %s; git show %s --"):format(repohome, commit), "r") +local function generate_diff(repodir, commit, G) + local DIFF = io.popen(("git --git-dir='%s' show --patch-with-stat '%s' --"):format(repodir, commit), "r") local visible = true local has_changes, has_visible_changes = false, false local text = {} @@ -204,10 +177,10 @@ local function generate_diff(repohome, commit, RG) local fn = l:match("^diff [^ \t]* a/([^ \t]*)") if fn then has_changes = true - visible = not match_file(fn, RG.no_notify) + visible = not match_file(fn, G.no_notify) if visible then has_visible_changes = true - visible = not match_file(fn, RG.no_diff) + visible = not match_file(fn, G.no_diff) if not visible then table.insert(text, "Private file "..fn.." changed") end @@ -220,48 +193,139 @@ local function generate_diff(repohome, commit, RG) return has_changes, text end -local function send_email(addresses, body, CI, G, R, RG) +local function resolve_email(identities, id) + if identities and identities[id] then id = identities[id] end + local name, email = id:match("^(.-) *<(.*)>$") + if email then return {name=name, email=email, rfc822=("%s <%s>"):format(name, email) } end + return {name="", email=name, rfc822=("<%s>"):format(name)} +end + +local function send_email(body, req, S, R, G) if not body then return end - if not RG.notify_emails then return end + if not G.notify_emails then return end - local EMAIL = io.popen(("sendmail -t -S %s"):format(G.smtp_server), "w") + local to_rfc822 = {} + local to_email = {} + for _,r in ipairs(G.notify_emails) do + local id = resolve_email(S.identities, r) + if not to_email[id.email] then + to_email[id.email] = true + table.insert(to_rfc822, id.rfc822) + table.insert(to_email, id.email) + end + end + to_rfc822 = table.concat(to_rfc822, ", ") + to_email = table.concat(to_email, " ") + + local EMAIL = io.popen(('/bin/busybox sendmail -f "%s" -S "%s" %s') + :format(req.author.email, S.smtp_server, to_email), "w") EMAIL:write(([[ -From: %s <%s> +From: %s To: %s Subject: apkovl changed - %s (%s) Date: %s -]]):format( CI.identity_name, CI.identity_email, - table.concat(RG.notify_emails, ", "), - R.description, R.address, - os.date("%a, %d %b %Y %H:%M:%S"))) +]]):format(req.author.rfc822, to_rfc822, R.description, R.address, os.date("%a, %d %b %Y %H:%M:%S"))) for _, l in ipairs(body) do EMAIL:write(l,'\n') end EMAIL:close() + + return to_email +end + +local function load_repo_configs(repohome) + local S = aac.readconfig(("%s/aaudit-server.json"):format(HOME)) + local R = aac.readconfig(("%s/aaudit-repo.json"):format(repohome)) + -- merge global and per-repository group configs + local G = (S.groups or {}).all or {} + for _, name in pairs(R.groups or {}) do + local g = S.groups[name] or {} + G.notify_emails = merge_array(G.notify_emails, g.notify_emails) + G.track_filemode = merge_bool(G.track_filemode, g.track_filemode) + G.no_track = merge_array(G.no_track, g.no_track) + G.no_notify = merge_array(G.no_notify, g.no_notify) + G.no_diff = merge_array(G.no_diff, g.no_diff) + end + return S, R, G end -function M.import_commit(repohome, CI) - local G, R, RG = load_repo_configs(repohome) +function M.repo_update(req) + local repodir = req.repositorydir + local S, R, G = load_repo_configs(repodir) - CI.identity_name, CI.identity_email = table.unpack(G.identities[CI.identity]) - CI.identity_name = CI.identity_name or "Alpine Auditor" - CI.identity_email = CI.identity_email or "auditor@alpine.local" + req.author = resolve_email(S.identities, req.identity) local TAR = io.popen(("ssh root@%s 'lbu package -' | gunzip"):format(R.address), "r") - local GIT = io.popen(("cd %s; git fast-import --quiet"):format(repohome), "w") - local rc, err = import_tar(TAR, GIT, CI, RG) + local GIT = io.popen(("git --git-dir='%s' fast-import --quiet"):format(repodir), "w") + local rc, err = import_tar(TAR, GIT, req, G) GIT:close() TAR:close() if not rc then return rc, err end - local has_changes, email_body = generate_diff(repohome, "import", RG) + local has_changes, email_body = generate_diff(repodir, "import", G) if has_changes then - if not CI.initial then send_email(CONF, email_body, CI, G, R, RG) end - os.execute(("cd %s; git branch --quiet --force master import; git branch --quiet -D import"):format(repohome)) - else - os.execute(("cd %s; git branch --quiet -D import; git gc --quiet --prune=now"):format(repohome)) + os.execute(("git --git-dir='%s' branch --quiet --force master import;".. + "git --git-dir='%s' branch --quiet -D import") + :format(repodir, repodir)) + local to = nil + if not req.initial then + to = send_email(email_body, req, S, R, G) + end + if to then + return true, "Committed and notified: "..to + else + return true, "Commit successful" + end + end + + os.execute(("git --git-dir='%s' branch --quiet -D import;".. + "git --git-dir='%s' gc --quiet --prune=now") + :format(repodir, repodir)) + return true, "No changes detected" +end + +function M.repo_create(req) + -- Create repository + write config + local repodir = req.repositorydir + os.execute(("mkdir -p '%s'; git init --quiet --bare '%s'") + :format(repodir, repodir)) + aac.writefile( + ("%s (%s)"):format(req.description, req.target_address), + ("%s/description"):format(repodir)) + aac.writeconfig( + { address=req.target_address, + description=req.description, + groups=req.groups }, + ("%s/aaudit-repo.json"):format(repodir)) + + -- Inject ssh identity to known_hosts + if req.ssh_host_key then + local f = io.open(("%s/.ssh/known_hosts"):format(HOME), "a") + f:write(("%s %s\n"):format(req.target_address, req.ssh_host_key)) + f:close() end +end +function M.handle(req) + req.target_address = req.target_address or req.remote_ip + req.repositorydir = ("%s/%s.git"):format(HOME, req.target_address) + req.initial = false + if req.command == "create" then + if posix.access(req.repositorydir, "rwx") then + return false, "Repository exists already" + end + M.repo_create(req) + req.initial = true + req.command = "commit" + end + if req.command == "commit" then + if not posix.access(req.repositorydir, "rwx") then + return false, "No such repository" + end + return M.repo_update(req) + else + return false,"Invalid request command" + end end return M diff --git a/testing/aaudit/aaudit-shell b/testing/aaudit/aaudit-shell index 73ebd2e7eb..e54ac3a977 100755 --- a/testing/aaudit/aaudit-shell +++ b/testing/aaudit/aaudit-shell @@ -1,14 +1,11 @@ -#!/bin/sh +#!/usr/bin/lua5.2 -local ip="${SSH_CLIENT/ */}" -local identity="$1" -[ -z "$ip" -o -z "$identity" ] && exit 1 +local json = require 'cjson' +local aas = require 'aaudit.server' -set -- $SSH_ORIGINAL_COMMAND -cmd="$1" -shift +local req = json.decode(io.read("*all")) +req.remote_ip = (os.getenv("SSH_CLIENT") or ""):match("[^ ]+") +req.identity = arg[1] -case "$cmd" in -create) /usr/libexec/aaudit/aaudit-repo-create -a "$ip" "$@" -i "$identity" ;; -commit) /usr/libexec/aaudit/aaudit-repo-update -a "$ip" "$@" -i "$identity" ;; -esac +local ok, msg = aas.handle(req) +print(json.encode{ok=ok,msg=msg}) diff --git a/testing/aaudit/aaudit-update-keys b/testing/aaudit/aaudit-update-keys new file mode 100755 index 0000000000..3521808cba --- /dev/null +++ b/testing/aaudit/aaudit-update-keys @@ -0,0 +1,18 @@ +#!/usr/bin/lua5.2 + +local posix = require 'posix' +local aac = require 'aaudit.common' + +local home = os.getenv("HOME") +local allkeys = {} +for _, keyfile in ipairs(posix.glob(("%s/keydir/*.pub"):format(home))) do + local identity = keyfile:match("keydir/(.*).pub$") + for sshkey in io.lines(keyfile) do + table.insert(allkeys, + ('command="/usr/libexec/aaudit/aaudit-shell %s"'.. + ',no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s\n') + :format(identity, sshkey)) + end +end + +aac.writefile(table.concat(allkeys), ("%s/.ssh/authorized_keys"):format(home)) diff --git a/testing/aaudit/aaudit.json b/testing/aaudit/aaudit.json new file mode 100644 index 0000000000..958d60fbc6 --- /dev/null +++ b/testing/aaudit/aaudit.json @@ -0,0 +1,5 @@ +{ + "user": "aaudit", + "server": "aaudit.alpine.local", + "rtqueue": "alpine.org" +} |