Skip to content

Commit 719930e

Browse files
committed
added git hooks and refactored some internals
1 parent 7a9c4de commit 719930e

File tree

2 files changed

+53
-57
lines changed

2 files changed

+53
-57
lines changed

git-skm/cli.janet

+39-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/bin/env janet
2+
(import spork/sh)
23
(use ./init)
34

45
(def zero-commit "0000000000000000000000000000000000000000")
@@ -19,30 +20,52 @@
1920
(verify-commit (first args))
2021
(verify-commit "HEAD")))
2122

22-
(defn cli/hooks/pre-receive [args]
23+
(defn cli/hooks/update [refname oldrev newrev]
2324
(def excludeExisting ["--not" "--all"])
25+
(printf "%s %s %s" oldrev newrev refname)
26+
(when (not= newrev zero-commit)
27+
(def span
28+
(if (= oldrev zero-commit)
29+
(string/split "\n" (sh/exec-slurp "git" "rev-list" newrev ;excludeExisting))
30+
(string/split "\n" (sh/exec-slurp "git" "rev-list" (string oldrev ".." newrev) ;excludeExisting))))
31+
(setdyn :repo-path (os/cwd))
32+
(verify-commit newrev)
33+
(each commit span
34+
(try
35+
(os/execute ["git" "verify-commit" commit] :px) # TODO this does not update allowed_signers yet
36+
([err] (error (string "could not verify signature of commit "
37+
commit " due to: " err
38+
"\nrejecting push")))))))
39+
40+
(defn cli/hooks/update-simple [refname oldrev newrev]
41+
(def excludeExisting ["--not" "--all"])
42+
(printf "%s %s %s" oldrev newrev refname)
43+
(when (not= newrev zero-commit)
44+
(setdyn :repo-path (os/cwd))
45+
(verify-commit newrev)))
46+
47+
(defn cli/hooks/pre-receive []
2448
(forever
25-
(def input (string/trimr (file/read :line stdin)))
49+
(def input (string/trimr (file/read stdin :line)))
2650
(if (= input "") (break))
2751
(def [oldrev newrev refname] (string/split " " input))
2852
(printf "%s %s %s" oldrev newrev refname)
29-
(when (not= newrev zero-commit)
30-
(def span "")
31-
(if (= oldrev zero-commit)
32-
(set span (string/split "\n" (sh/exec-slurp "git" "rev-list" newrev ;excludeExisting)))
33-
(set span (string/split "\n" (sh/exec-slurp "git" "rev-list" (string oldrev ".." newrev) ;excludeExisting))))
34-
(each commit span
35-
(try
36-
(os/execute ["git" "verify-commit" commit] :px) # TODO this does not update allowed_signers yet
37-
([err] (error (string "could not verify signature of commit "
38-
commit " due to: " err
39-
"\nrejecting push"))))))))
53+
(cli/hooks/update refname oldrev newrev)))
54+
55+
(def cli/hooks/help-message
56+
`Available hooks:
57+
- update - check each commit of each pushed rev against a newly generated allowed_signers file
58+
- update-simple - like update but only check the last commit
59+
- pre-receive - simple hook that works like the update hook but checks all ref at the same time`)
4060

4161
(defn cli/hooks [args]
4262
(def hook-type (first args))
4363
(case hook-type
44-
"pre-receive" (cli/hooks/pre-receive (slice args 1 -1))
45-
(error "unknown hook-type")))
64+
"help" (print cli/hooks/help-message)
65+
"pre-receive" (cli/hooks/pre-receive)
66+
"update" (cli/hooks/update ;(slice args 1 -1))
67+
"update-simple" (cli/hooks/update-simple ;(slice args 1 -1))
68+
(do (print "unknown hook-type, showing help:\n" cli/hooks/help-message))))
4669

4770
(defn cli/help []
4871
(print `simple key management
@@ -58,6 +81,6 @@
5881
"help" (cli/help)
5982
"verify-commit" (cli/verify-commit (slice args 1 -1))
6083
"generate" (cli/generate-allowed-signers (slice args 1 -1))
61-
"hook" (cli/hook (slice args 1 -1))
84+
"hook" (cli/hooks (slice args 1 -1))
6285
"trust" (cli/trust (slice args 1 -1))
6386
(cli/help)))

git-skm/init.janet

+14-41
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
(defn git/slurp [& args] (sh/exec-slurp "git" "-C" (dyn :repo-path) ;args))
88
(defn git/slurp-all [& args] (sh/exec-slurp-all "git" "-C" (dyn :repo-path) ;args))
99

10-
# TODO
11-
# pre-receive hook
12-
1310
(defn is-in-dir [child parent]
1411
(not (deep= (first (path/parts (path/relpath parent child))) "..")))
1512

@@ -41,46 +38,22 @@
4138

4239
(defn git-dir [&opt repo]
4340
(default repo (dyn :repo-path))
44-
(def opts @[])
45-
(if repo (array/concat opts ["-C" repo]))
4641
(if (dyn :git-dir)
4742
(dyn :git-dir)
48-
(let [git-dir (path/join repo (sh/exec-slurp "git" ;opts "rev-parse" "--git-dir"))]
43+
(let [git-dir (path/join repo (sh/exec-slurp "git" "-C" repo "rev-parse" "--git-dir"))]
4944
(setdyn :git-dir git-dir)
5045
git-dir)))
5146

52-
(defn repo-top-level [&opt repo]
53-
(default repo (dyn :repo-path))
54-
(def opts @[])
55-
(if repo (array/concat opts ["-C" repo]))
56-
(if (dyn :repo-top-level)
57-
(dyn :repo-top-level)
58-
(let [repo-top-level (sh/exec-slurp "git" ;opts "rev-parse" "--show-toplevel")]
59-
(setdyn :repo-top-level repo-top-level)
60-
repo-top-level)))
61-
62-
(defn allowed-signers-absolute-path [&opt repo]
63-
(default repo (dyn :repo-path))
64-
(def opts @[])
65-
(if repo (array/concat opts ["-C" repo]))
66-
(if (dyn :allowed-signers-absolute-path)
67-
(dyn :allowed-signers-absolute-path)
68-
(try
69-
(let [allowed-signers-absolute-path (sh/exec-slurp "git" ;opts "config" "--local" "skm.allowedSignersFile")]
70-
(let [stat (os/stat allowed-signers-absolute-path)]
71-
(if (or (not stat) (not= (stat :mode) :file))
72-
(error "allowedSignersFile does not exist or is not a file")))
73-
(setdyn :allowed-signers-absolute-path allowed-signers-absolute-path))
74-
([err]
75-
(do
76-
(setdyn :allowed-signers-absolute-path (path/join (repo-top-level) ".allowed_signers"))
77-
(sh/exec-slurp "git" ;opts "config" "--local" "skm.allowedSignersFile" (dyn :allowed-signers-absolute-path)))))))
78-
7947
(defn allowed-signers-relative-path [&opt repo]
8048
(default repo (dyn :repo-path))
8149
(if (dyn :allowed-signers-relative-path)
8250
(dyn :allowed-signers-relative-path)
83-
(path/relpath (repo-top-level repo) (allowed-signers-absolute-path repo))))
51+
(let [result (sh/exec-slurp-all "git" "-C" repo "config" "--local" "skm.allowedSignersFile")]
52+
(if (and (= (result :status) 0)
53+
(result :out)
54+
(not= (result :out) ""))
55+
(setdyn :allowed-signers-relative-path (result :out))
56+
(setdyn :allowed-signers-relative-path ".allowed_signers")))))
8457

8558
(defn trust
8659
"set trust anchor"
@@ -141,10 +114,12 @@
141114
"generate the allowed_signers file using a previously set trust anchor"
142115
[commit]
143116
(check-allowed-signers)
144-
(def allowed-signers-absolute-path (allowed-signers-absolute-path))
145-
(var last-verified-commit (git/slurp "config" "skm.last-verified-commit"))
117+
(var last-verified-commit "")
118+
(try
119+
(set last-verified-commit (git/slurp "config" "skm.last-verified-commit"))
120+
([err] (error (string "could not get trust anchor: " err))))
146121
(if (or (not last-verified-commit) (= last-verified-commit "")) (error "No last verified commit set"))
147-
(def all_commits (string/split "\n" (git/slurp "log" "--pretty=format:%H" (allowed-signers-relative-path))))
122+
(def all_commits (string/split "\n" (git/slurp "rev-list" commit "--" (allowed-signers-relative-path))))
148123
(def commits-to-verify @[])
149124
(var found_commit false)
150125
(each commit all_commits
@@ -158,13 +133,11 @@
158133
(set last-verified-commit commit))
159134
(trust last-verified-commit)
160135
(def allowed-signers-cache-file (path/join (git-dir) "allowed_signers"))
161-
(sh/copy-file allowed-signers-absolute-path allowed-signers-cache-file)
136+
(spit allowed-signers-cache-file (git/slurp "show" (string commit ":" (allowed-signers-relative-path))))
162137
(git/fail "config" "gpg.ssh.allowedSignersFile" allowed-signers-cache-file)
163138
(print "allowed_signers was verified and copied into git_dir"))
164139

165140
(defn verify-commit
166141
[commit]
167-
(def allowed-signers-cache-file (path/join (git-dir) "allowed_signers"))
168-
(unless (deep= (slurp allowed-signers-cache-file) (slurp (allowed-signers-absolute-path)))
169-
(generate-allowed-signers (git/slurp "rev-parse" commit)))
142+
(generate-allowed-signers (git/slurp "rev-parse" commit))
170143
(git/loud "verify-commit" commit))

0 commit comments

Comments
 (0)