!3 修改gpg验证方式解决编译失败
From: @wk333 Reviewed-by: @caodongxia Signed-off-by: @caodongxia
This commit is contained in:
commit
d16189c90d
111
gpgverify
Executable file
111
gpgverify
Executable file
@ -0,0 +1,111 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# Copyright 2018 B. Persson, Bjorn@Rombobeorn.se
|
||||
#
|
||||
# This material is provided as is, with absolutely no warranty expressed
|
||||
# or implied. Any use is at your own risk.
|
||||
#
|
||||
# Permission is hereby granted to use or copy this shellscript
|
||||
# for any purpose, provided the above notices are retained on all copies.
|
||||
# Permission to modify the code and to distribute modified code is granted,
|
||||
# provided the above notices are retained, and a notice that the code was
|
||||
# modified is included with the above copyright notice.
|
||||
|
||||
|
||||
function print_help {
|
||||
cat <<'EOF'
|
||||
Usage: gpgverify --keyring=<pathname> --signature=<pathname> --data=<pathname>
|
||||
|
||||
gpgverify is a wrapper around gpgv designed for easy and safe scripting. It
|
||||
verifies a file against a detached OpenPGP signature and a keyring. The keyring
|
||||
shall contain all the keys that are trusted to certify the authenticity of the
|
||||
file, and must not contain any untrusted keys.
|
||||
|
||||
The differences, compared to invoking gpgv directly, are that gpgverify accepts
|
||||
the keyring in either ASCII-armored or unarmored form, and that it will not
|
||||
accidentally use a default keyring in addition to the specified one.
|
||||
|
||||
Parameters:
|
||||
--keyring=<pathname> keyring with all the trusted keys and no others
|
||||
--signature=<pathname> detached signature to verify
|
||||
--data=<pathname> file to verify against the signature
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
fatal_error() {
|
||||
message="$1" # an error message
|
||||
status=$2 # a number to use as the exit code
|
||||
echo "gpgverify: $message" >&2
|
||||
exit $status
|
||||
}
|
||||
|
||||
|
||||
require_parameter() {
|
||||
term="$1" # a term for a required parameter
|
||||
value="$2" # Complain and terminate if this value is empty.
|
||||
if test -z "${value}" ; then
|
||||
fatal_error "No ${term} was provided." 2
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
check_status() {
|
||||
action="$1" # a string that describes the action that was attempted
|
||||
status=$2 # the exit code of the command
|
||||
if test $status -ne 0 ; then
|
||||
fatal_error "$action failed." $status
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Parse the command line.
|
||||
keyring=
|
||||
signature=
|
||||
data=
|
||||
for parameter in "$@" ; do
|
||||
case "${parameter}" in
|
||||
(--help)
|
||||
print_help
|
||||
exit
|
||||
;;
|
||||
(--keyring=*)
|
||||
keyring="${parameter#*=}"
|
||||
;;
|
||||
(--signature=*)
|
||||
signature="${parameter#*=}"
|
||||
;;
|
||||
(--data=*)
|
||||
data="${parameter#*=}"
|
||||
;;
|
||||
(*)
|
||||
fatal_error "Unknown parameter: \"${parameter}\"" 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
require_parameter 'keyring' "${keyring}"
|
||||
require_parameter 'signature' "${signature}"
|
||||
require_parameter 'data file' "${data}"
|
||||
|
||||
# Make a temporary working directory.
|
||||
workdir="$(mktemp --directory)"
|
||||
check_status 'Making a temporary directory' $?
|
||||
workring="${workdir}/keyring.gpg"
|
||||
|
||||
# Decode any ASCII armor on the keyring. This is harmless if the keyring isn't
|
||||
# ASCII-armored.
|
||||
gpg2 --homedir="${workdir}" --yes --output="${workring}" --dearmor "${keyring}"
|
||||
check_status 'Decoding the keyring' $?
|
||||
|
||||
# Verify the signature using the decoded keyring.
|
||||
gpgv2 --homedir="${workdir}" --keyring="${workring}" "${signature}" "${data}"
|
||||
check_status 'Signature verification' $?
|
||||
|
||||
# (--homedir isn't actually necessary. --dearmor processes only the input file,
|
||||
# and if --keyring is used and contains a slash, then gpgv2 uses only that
|
||||
# keyring. Thus neither command will look for a default keyring, but --homedir
|
||||
# makes extra double sure that no default keyring will be touched in case
|
||||
# another version of GPG works differently.)
|
||||
|
||||
# Clean up. (This is not done in case of an error that may need inspection.)
|
||||
rm --recursive --force ${workdir}
|
||||
316
macros.gpg
316
macros.gpg
@ -1,316 +0,0 @@
|
||||
# The gpg_verify macro is defined further down in this document.
|
||||
|
||||
# gpg_verify takes one option and a list of 2- or 3-tuples.
|
||||
#
|
||||
# With no arguments, attempts to figure everything out. Finds one keyring and
|
||||
# tries to pair each signature file with a source. If there is no source found
|
||||
# which matches a signature, the build is aborted.
|
||||
#
|
||||
# -k gives a common keyring to verify all signatures against, except when an
|
||||
# argument specifies its own keyring.
|
||||
#
|
||||
# Each argument must be of the form "F,S,K" or "F,S", where each of F, S and K
|
||||
# is either the number or the filename of one of the source files in the
|
||||
# package. A pathname including directories is not allowed.
|
||||
# F is a source file to check.
|
||||
# S is a signature.
|
||||
# K is a keyring.
|
||||
#
|
||||
# When an argument specifies a keyring, that signature will be verified against
|
||||
# the keys in that keyring. For arguments that don't specify a keyring, the one
|
||||
# specified with -k will be used, if any. If no keyring is specified either
|
||||
# way, the macro will default to the first one it finds in the source list.
|
||||
#
|
||||
# It is assumed that all the keys in all keyrings, whether automatically found
|
||||
# or explicitly specified, are trusted to authenticate the source files. There
|
||||
# must not be any untrusted keys included.
|
||||
|
||||
# Some utility functions to the global namespace
|
||||
# Most of these should come from the utility macros in the other repo.
|
||||
%define gpg_macros_init %{lua:
|
||||
function db(str)
|
||||
io.stderr:write(tostring(str) .. '\\n')
|
||||
end
|
||||
\
|
||||
-- Simple basename clone
|
||||
function basename(str)
|
||||
local name = string.gsub(str, "(.*/)(.*)", "%2")
|
||||
return name
|
||||
end
|
||||
\
|
||||
-- Get the numbered or source file.
|
||||
-- The spec writer can use any numbering scheme. The sources table
|
||||
-- always counts from 1 and has no gaps, so we have to go back to the
|
||||
-- SOURCEN macros.
|
||||
function get_numbered_source(num)
|
||||
local macro = "%SOURCE" .. num
|
||||
local val = rpm.expand(macro)
|
||||
if val == macro then
|
||||
return nil
|
||||
end
|
||||
return val
|
||||
end
|
||||
-- Get the named source file. This returns the full path to a source file,
|
||||
-- or nil if no such source exists.
|
||||
function get_named_source(name)
|
||||
local path
|
||||
for _,path in ipairs(sources) do
|
||||
if name == basename(path) then
|
||||
return path
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
\
|
||||
-- Determine whether the supplied filename contains a signature
|
||||
-- Assumes the file will be closed when the handle goes out of scope
|
||||
function is_signature(fname)
|
||||
-- I don't really like this, but you can have completely binary sigs
|
||||
if string.find(fname, '%.sig$') then
|
||||
return true
|
||||
end
|
||||
local file = io.open(fname, 'r')
|
||||
if file == nil then return false end
|
||||
\
|
||||
local c = 1
|
||||
while true do
|
||||
local line = file:read('*line')
|
||||
if (line == nil or c > 10) then break end
|
||||
if string.find(line, "BEGIN PGP SIGNATURE") then
|
||||
return true
|
||||
end
|
||||
c = c+1
|
||||
end
|
||||
return false
|
||||
end
|
||||
\
|
||||
-- Determine whether the supplied filename looks like a keyring
|
||||
-- Ends in .gpg (might be binary data)? Contains "BEGIN PGP PUBLIC KEY BLOCK"
|
||||
function is_keyring(fname)
|
||||
-- XXX Have to hack this now to make it not find macros.gpg while we're testing.
|
||||
if string.find(fname, '%.gpg$') and not string.find(fname, 'macros.gpg$') then
|
||||
return true
|
||||
end
|
||||
\
|
||||
local file = io.open(fname, 'r')
|
||||
if file == nil then return false end
|
||||
io.input(file)
|
||||
local c = 1
|
||||
while true do
|
||||
local line = io.read('*line')
|
||||
if (line == nil or c > 10) then break end
|
||||
if string.find(line, "BEGIN PGP PUBLIC KEY BLOCK") then
|
||||
return true
|
||||
end
|
||||
c = c+1
|
||||
end
|
||||
return false
|
||||
end
|
||||
\
|
||||
-- Output code to have the current scriptlet echo something
|
||||
function echo(str)
|
||||
print("echo " .. str .. "\\n")
|
||||
end
|
||||
\
|
||||
-- Output an exit statement with nonzero return to the current scriptlet
|
||||
function exit()
|
||||
print("exit 1\\n")
|
||||
end
|
||||
\
|
||||
-- Call the RPM %error macro
|
||||
function rpmerror(str)
|
||||
echo("gpg_verify: " .. str)
|
||||
rpm.expand("%{error:gpg_verify: " .. str .. "}")
|
||||
exit(1)
|
||||
end
|
||||
\
|
||||
-- XXX How to we get just a flag and no option?
|
||||
function getflag(flag)
|
||||
return nil
|
||||
end
|
||||
\
|
||||
-- Extract the value of a passed option
|
||||
function getoption(opt)
|
||||
out = rpm.expand("%{-" .. opt .. "*}")
|
||||
-- if string.len(out) == 0 then
|
||||
if #out == 0 then
|
||||
return nil
|
||||
end
|
||||
return out
|
||||
end
|
||||
\
|
||||
function unknownarg(a)
|
||||
rpmerror("Unknown argument to %%gpg_verify: " .. a)
|
||||
end
|
||||
\
|
||||
function rprint(s, l, i) -- recursive Print (structure, limit, indent)
|
||||
l = (l) or 100; i = i or ""; -- default item limit, indent string
|
||||
if (l<1) then db("ERROR: Item limit reached."); return l-1 end;
|
||||
local ts = type(s);
|
||||
if (ts ~= "table") then db(i,ts,s); return l-1 end
|
||||
db(i,ts); -- print "table"
|
||||
for k,v in pairs(s) do -- db("[KEY] VALUE")
|
||||
l = rprint(v, l, i.."\t["..tostring(k).."]");
|
||||
if (l < 0) then break end
|
||||
end
|
||||
return l
|
||||
end
|
||||
\
|
||||
-- Given a list of source file numbers or file names, validate them and
|
||||
-- convert them to a list of full filenames.
|
||||
function check_sources_list(arr)
|
||||
local files = {}
|
||||
local src,fpath
|
||||
for _, src in ipairs(arr) do
|
||||
if tonumber(src) then
|
||||
-- We have a number; turn it to a full path to the corresponding source file
|
||||
fpath = get_numbered_source(src)
|
||||
else
|
||||
fpath = get_named_source(src)
|
||||
end
|
||||
if not src then
|
||||
err = 'Not a valid source: ' .. src
|
||||
if src == '1' then
|
||||
err = err .. '. Note that "Source:" is the 0th source file, not the 1st.'
|
||||
end
|
||||
rpmerror(err)
|
||||
end
|
||||
table.insert(files, fpath)
|
||||
end
|
||||
return files
|
||||
end
|
||||
rpm.define("gpg_macros_init %{nil}")
|
||||
}#
|
||||
|
||||
# The actual macro
|
||||
%define gpg_verify(k:) %gpg_macros_init%{lua:
|
||||
-- RPM will ignore the first thing we output unless we give it a newline.
|
||||
print('\\n')
|
||||
\
|
||||
local defkeyspec = getoption("k")
|
||||
local args = rpm.expand("%*")
|
||||
local sourcefiles = {}
|
||||
local signature_table = {}
|
||||
local signatures = {}
|
||||
local keyrings = {}
|
||||
local defkey, match, captures, s
|
||||
\
|
||||
local function storematch(m, c)
|
||||
match = m; captures = c
|
||||
end
|
||||
\
|
||||
-- Scan all of the sources and try to categorize them.
|
||||
-- Move to a function
|
||||
for i,s in pairs(sources) do
|
||||
sourcefiles[s] = true
|
||||
-- db('File: ' .. i .. ", " .. s)
|
||||
if is_signature(s) then
|
||||
table.insert(signatures, s)
|
||||
signature_table[s] = true
|
||||
db('Found signature: ' .. s)
|
||||
elseif is_keyring(s) then
|
||||
table.insert(keyrings, s)
|
||||
db('Found keyring: ' .. s)
|
||||
else
|
||||
-- Must be a source
|
||||
db('Found source: ' .. s)
|
||||
end
|
||||
end
|
||||
\
|
||||
if defkeyspec then
|
||||
defkey = check_sources_list({defkeyspec})[1]
|
||||
if not defkey then
|
||||
rpmerror('The provided keyring ' .. defkeyspec .. ' is not a valid source number or filename.')
|
||||
end
|
||||
end
|
||||
\
|
||||
if defkey then
|
||||
db('Defkey: ' .. defkey)
|
||||
else
|
||||
db('No common key yet')
|
||||
if keyrings[1] then
|
||||
defkey = keyrings[1]
|
||||
db('Using first found keyring file: '..defkey)
|
||||
end
|
||||
end
|
||||
\
|
||||
-- Check over any given args to make sure they're valid, and to see if a
|
||||
-- common key is required.
|
||||
local needdefkey = false
|
||||
local double = rex.newPOSIX('^([^,]+),([^,]+)$')
|
||||
local triple = rex.newPOSIX('^([^,]+),([^,]+),([^,]+)$')
|
||||
local arglist = {}
|
||||
\
|
||||
-- RPM gives us the arguments in a single string.
|
||||
-- Split on spaces and iterate
|
||||
for arg in args:gmatch('%S+') do
|
||||
db('Checking ' .. arg)
|
||||
if triple:gmatch(arg, storematch) > 0 then
|
||||
db('Looks OK')
|
||||
local parsed = {srcnum=captures[1], signum=captures[2], keynum=captures[3]}
|
||||
s = check_sources_list({captures[1], captures[2], captures[3]})
|
||||
parsed.srcfile = s[1]
|
||||
parsed.sigfile = s[2]
|
||||
parsed.keyfile = s[3]
|
||||
table.insert(arglist, parsed)
|
||||
elseif double:gmatch(arg, storematch) > 0 then
|
||||
db('Looks OK; needs common key')
|
||||
needdefkey = true
|
||||
local parsed = {srcnum=captures[1], signum=captures[2], keynum=defkeyspec, keyfile=defkey}
|
||||
s = check_sources_list({captures[1], captures[2]})
|
||||
parsed.srcfile = s[1]
|
||||
parsed.sigfile = s[2]
|
||||
table.insert(arglist, parsed)
|
||||
else
|
||||
rpmerror('Provided argument '..arg..' is not valid.')
|
||||
end
|
||||
end
|
||||
\
|
||||
-- So we now know if one of those args needs a common key
|
||||
if needdefkey and not defkey then
|
||||
rpmerror('No common key was specified or found, yet the arguments require one.')
|
||||
end
|
||||
\
|
||||
-- And if we have no arguments at all and no common key was found,
|
||||
-- then we can't do an automatic check
|
||||
if not defkey and args == '' then
|
||||
rpmerror('No keyring specified and none found; cannot auto-check.')
|
||||
end
|
||||
\
|
||||
-- Nothing to check means automatic mode
|
||||
if #arglist == 0 then
|
||||
local noext
|
||||
for i,_ in pairs(signature_table) do
|
||||
-- Find the name without the extension
|
||||
noext = string.gsub(i, '%.[^.]+$', '')
|
||||
if sourcefiles[noext] then
|
||||
table.insert(arglist, {srcfile=noext, sigfile=i, keyfile=defkey})
|
||||
else
|
||||
rpmerror('Found signature ' .. i .. ' with no matching source file.')
|
||||
end
|
||||
end
|
||||
end
|
||||
\
|
||||
-- Now actually check things
|
||||
for _,arg in ipairs(arglist) do
|
||||
local gpgfile = '$GPGHOME/' .. basename(arg.keyfile) .. '.gpg'
|
||||
echo('Checking signature: file ' .. arg.srcfile .. ' sig ' .. arg.sigfile .. ' key ' .. arg.keyfile)
|
||||
\
|
||||
-- We need a secure temp directorry
|
||||
print('GPGHOME=$(mktemp -qd)\\n')
|
||||
\
|
||||
-- Call gpg2 to generate the dearmored key
|
||||
print('gpg2 --homedir $GPGHOME --no-default-keyring --quiet --yes ')
|
||||
print('--output '.. gpgfile .. ' --dearmor ' .. arg.keyfile .. "\\n")
|
||||
\
|
||||
-- Call gpgv2 to verify the signature against the source file with the dearmored key
|
||||
print('gpgv2 --homedir $GPGHOME --keyring ' .. gpgfile .. ' ' .. arg.sigfile .. ' ' .. arg.srcfile .. '\\n')
|
||||
\
|
||||
print('rm -rf $GPGHOME\\n')
|
||||
echo('')
|
||||
end
|
||||
\
|
||||
db('------------')
|
||||
}#
|
||||
|
||||
# vim: set filetype=spec:
|
||||
@ -15,7 +15,7 @@
|
||||
%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}}
|
||||
Name: openconnect
|
||||
Version: 8.10
|
||||
Release: 1
|
||||
Release: 2
|
||||
Summary: Open client for Cisco AnyConnect VPN, Juniper Network Connect/Pulse, PAN GlobalProtect
|
||||
License: LGPLv2+
|
||||
URL: http://www.infradead.org/openconnect.html
|
||||
@ -24,7 +24,7 @@ Source0: ftp://ftp.infradead.org/pub/openconnect/openconnect-%{versi
|
||||
Source1: ftp://ftp.infradead.org/pub/openconnect/openconnect-%{version}%{?gitsuffix}.tar.gz.asc
|
||||
%endif
|
||||
Source2: gpgkey-BE07D9FD54809AB2C4B0FF5F63762CDA67E2F359.asc
|
||||
Source3: macros.gpg
|
||||
Source3: gpgverify
|
||||
BuildRequires: pkgconfig(libxml-2.0) pkgconfig(libpcsclite) krb5-devel gnupg2
|
||||
BuildRequires: autoconf automake libtool gettext pkgconfig(liblz4)
|
||||
BuildRequires: pkgconfig(uid_wrapper) pkgconfig(socket_wrapper)
|
||||
@ -60,11 +60,11 @@ Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||
This package provides the core HTTP and authentication support from
|
||||
the OpenConnect VPN client, to be used by GUI authentication dialogs
|
||||
for NetworkManager etc.
|
||||
%include %SOURCE3
|
||||
|
||||
%prep
|
||||
%if 0%{?gitcount} == 0
|
||||
%gpg_verify
|
||||
cp %{SOURCE3} .
|
||||
sh gpgverify --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
|
||||
%endif
|
||||
%autosetup -n openconnect-%{version}%{?gitsuffix} -p1
|
||||
|
||||
@ -103,5 +103,8 @@ make VERBOSE=1 check
|
||||
%{_libdir}/pkgconfig/openconnect.pc
|
||||
|
||||
%changelog
|
||||
* Tue Feb 07 2023 wangkai <wangkai385@h-partners.com> - 8.10-2
|
||||
- modify the gpg verification method
|
||||
|
||||
* Mon Sep 6 2021 wulei <wulei80@huawei.com> - 8.10-1
|
||||
- package init
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user