#!/usr/bin/make -rRf # Usage: pacman-make-keyring V=$(date -u +%Y%m%d) # Copyright 2014, 2016 Luke Shumaker . # # This is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This software is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public # License along with this manual; if not, see # . ifeq ($(origin V),undefined) $(info Usage: pacman-make-keyring V=$$(date -u +%Y%m%d)) $(error You must set V= on the command line) endif bin := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) yamldir := $(shell ruby -e "load '$(bin)/common.rb'; print cfg['yamldir']") cachedir := $(shell ruby -e "load '$(bin)/common.rb'; print cfg['keyring_cachedir']") outputdir = $(cachedir)/$(KEYRING_NAME)-keyring-$(V) KEYRING_NAME = parabola all: $(KEYRING_NAME)-keyring-$(V).tar.gz .PHONY: all export SHELL = /bin/bash -o pipefail .PHONY: FORCE .SECONDARY: .DELETE_ON_ERROR: dirs = \ $(outputdir) \ $(cachedir) \ $(cachedir)/gpghome \ $(cachedir)/keys/trusted \ $(cachedir)/keys/secondary \ $(cachedir)/keys/revoked $(dirs): mkdir -p $@ $(cachedir)/var.%: FORCE | $(cachedir) @$(file >$(@D)/tmp.$(@F),$($*)) @sed -i 's|^|#|' $(@D)/tmp.$(@F) @if cmp -s $(@D)/tmp.$(@F) $@; then \ rm -f $(@D)/tmp.$(@F) || :; \ else \ mv -f $(@D)/tmp.$(@F) $@; \ fi -include $(wildcard $(cachedir)/var.*) $(cachedir)/txt.%: $(cachedir)/var.% sed 's|^#||' < $< > $@ var=$(cachedir)/var. keyring-files = \ $(outputdir)/Makefile \ $(outputdir)/${KEYRING_NAME}.gpg \ $(outputdir)/${KEYRING_NAME}-trusted \ $(outputdir)/${KEYRING_NAME}-revoked $(KEYRING_NAME)-keyring-$(V).tar.gz: %.tar.gz: $(keyring-files) bsdtar --format=ustar -cf - -C $(cachedir) $(addprefix $*/,$(notdir $^)) | gzip -9 > $@ define Makefile.in V=@V@ prefix = /usr/local PREFIX = $$(prefix) install: install -dm755 $$(DESTDIR)$$(PREFIX)/share/pacman/keyrings/ install -m0644 @KEYRING_NAME@{.gpg,-trusted,-revoked} $$(DESTDIR)$$(PREFIX)/share/pacman/keyrings/ uninstall: rm -f $$(DESTDIR)$$(PREFIX)/share/pacman/keyrings/@KEYRING_NAME@{.gpg,-trusted,-revoked} rmdir -p --ignore-fail-on-non-empty $$(DESTDIR)$$(PREFIX)/share/pacman/keyrings/ .PHONY: install uninstall endef $(outputdir)/Makefile: $(cachedir)/txt.Makefile.in $(var)V $(var)KEYRING_NAME | $(outputdir) sed $(foreach v,$(patsubst $(var)%,%,$(filter $(var)%,$^)), -e 's|@$v@|$($v)|' ) < $< > $@ users := $(sort $(shell find $(yamldir))) $(var)users # Assemble the list of .asc files needed to generate the keyring $(cachedir)/deps.mk: ${users} $(var)outputdir $(var)cachedir $(var)KEYRING_NAME| $(cachedir) { \ echo $(outputdir)/${KEYRING_NAME}.gpg: $$($(bin)/pgp-list-keyids | sed -r 's|(\S+) .*|$$(cachedir)/keys/\1.asc|') && \ echo $(cachedir)/stamp.ownertrust: $$($(bin)/pgp-list-keyids | sed -rn 's|^(trusted/\S+) .*|$$(cachedir)/keys/\1.asc|p') && \ $(bin)/pgp-list-keyids | sed -rn 's|^trusted/(\S+) (.*)|keyid.\1 = \2|p' && \ $(bin)/uid-map | sed 's|.*|trusted:&\nsecondary:&\nrevoked:&|' | sed -r 's|(.*):(.*):(.*)|$$(cachedir)/keys/\1/\3.asc: $$(yamldir)/\2.yml|' && \ :; }> $@ -include $(cachedir)/deps.mk # The remainder of file is mostly just a translation of the shell # script `update-keys`. # # https://git.archlinux.org/archlinux-keyring.git/tree/update-keys export LANG=C KEYSERVER = hkp://pool.sks-keyservers.net GPG = gpg --quiet --batch --no-tty --no-permission-warning --keyserver ${KEYSERVER} --homedir $(cachedir)/gpghome define gpg-init %echo Generating Parabola Keyring keychain master key... Key-Type: RSA Key-Length: 1024 Key-Usage: sign Name-Real: Parabola Keyring Keychain Master Key Name-Email: parabola-keyring@localhost Expire-Date: 0 %no-protection %commit %echo Done endef $(cachedir)/stamp.gpg-init: $(cachedir)/txt.gpg-init $(var)GPG | $(cachedir)/gpghome ${GPG} --gen-key < $< touch $@ # The appropriate ${uid}.yml file is added as a dependency to # ${username}.yml by deps.mk keyid=$(keyid.$(patsubst %.asc,%,$(notdir $@))) # In 'update-keys', this is the 'master-keyids' loop $(outputdir)/${KEYRING_NAME}-trusted: ${users} | $(outputdir) $(bin)/pgp-list-keyids | sed -rn 's|^trusted/\S+ (\S+)|\1:4:|p' > $@ $(cachedir)/keys/trusted/%.asc : $(cachedir)/stamp.gpg-init | $(cachedir)/keys/trusted ${GPG} --recv-keys ${keyid} &>/dev/null printf 'minimize\nquit\ny\n' | ${GPG} --command-fd 0 --edit-key ${keyid} printf 'y\ny\n' | ${GPG} --command-fd 0 --lsign-key ${keyid} &>/dev/null ${GPG} --armor --no-emit-version --export ${keyid} > $@ $(cachedir)/stamp.ownertrust: $(outputdir)/${KEYRING_NAME}-trusted $(cachedir)/deps.mk ${GPG} --import-ownertrust < $< 2>/dev/null touch $@ # In 'update-keys', this is the 'packager-keyids' loop $(cachedir)/keys/secondary/%.asc: $(cachedir)/stamp.ownertrust | $(cachedir)/keys/secondary ${GPG} --recv-keys ${keyid} &>/dev/null printf 'clean\nquit\ny\n' | ${GPG} --command-fd 0 --edit-key ${keyid} ${GPG} --list-keys --with-colons ${keyid} 2>/dev/null | grep -q '^pub:f:' # make sure it is trusted ${GPG} --armor --no-emit-version --export ${keyid} > $@ # In 'update-keys', this is the 'packager-revoked-keyids' loop $(outputdir)/${KEYRING_NAME}-revoked: ${users} | $(outputdir) $(bin)/pgp-list-keyids | sed -rn 's|^revoked/\S+ ||p' > $@ $(cachedir)/keys/revoked/%.asc : $(cachedir)/stamp.ownertrust | $(cachedir)/keys/revoked ${GPG} --recv-keys ${keyid} &>/dev/null printf 'clean\nquit\ny\n' | ${GPG} --command-fd 0 --edit-key ${keyid} ! ${GPG} --list-keys --with-colons ${keyid} 2>/dev/null | grep -q '^pub:f:' # make sure it isn't trusted ${GPG} --armor --no-emit-version --export ${keyid} > $@ $(outputdir)/${KEYRING_NAME}.gpg: $(cachedir)/deps.mk | $(outputdir) cat $(filter %.asc,$^) > $@