grim/containers/msys2-cross
Clone
Summary
Browse
Changes
Graph
Call xvfb-run with `-a`
2019-08-26, Gary Kramlich
c92805254e8a
file is
Executable
Call xvfb-run with `-a`
#!/usr/bin/env bash
#
# pacman-key - manages pacman's keyring
# Based on apt-key, from Debian
# Generated from pacman-key.sh.in; do not edit by hand.
#
# Copyright (c) 2010-2016 Pacman Development Team <pacman-dev@archlinux.org>
#
# This program 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 program 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 program. If not, see <http://www.gnu.org/licenses/>.
#
# gettext initialization
export
TEXTDOMAIN
=
'pacman-scripts'
export
TEXTDOMAINDIR
=
'/usr/share/locale'
declare
-r
myver
=
"5.0.1"
# Options
ADD
=
0
DELETE
=
0
EDITKEY
=
0
EXPORT
=
0
FINGER
=
0
IMPORT
=
0
IMPORT_TRUSTDB
=
0
INIT
=
0
KEYSERVER
=
''
LISTKEYS
=
0
LISTSIGS
=
0
LSIGNKEY
=
0
POPULATE
=
0
RECEIVE
=
0
REFRESH
=
0
UPDATEDB
=
0
USE_COLOR
=
'y'
VERIFY
=
0
DEFAULT_KEYSERVER
=
'hkp://pool.sks-keyservers.net'
plain
()
{
((
QUIET
))
&&
return
local
mesg
=
$1
;
shift
printf
"
${
BOLD
}
${
mesg
}${
ALL_OFF
}
\n"
"
$@
"
>
&
1
}
msg
()
{
((
QUIET
))
&&
return
local
mesg
=
$1
;
shift
printf
"
${
GREEN
}
==>
${
ALL_OFF
}${
BOLD
}
${
mesg
}${
ALL_OFF
}
\n"
"
$@
"
>
&
1
}
msg2
()
{
((
QUIET
))
&&
return
local
mesg
=
$1
;
shift
printf
"
${
BLUE
}
->
${
ALL_OFF
}${
BOLD
}
${
mesg
}${
ALL_OFF
}
\n"
"
$@
"
>
&
1
}
ask
()
{
local
mesg
=
$1
;
shift
printf
"
${
BLUE
}
::
${
ALL_OFF
}${
BOLD
}
${
mesg
}${
ALL_OFF
}
"
"
$@
"
>
&
1
}
warning
()
{
local
mesg
=
$1
;
shift
printf
"
${
YELLOW
}
==>
$(
gettext
"WARNING:"
)
${
ALL_OFF
}${
BOLD
}
${
mesg
}${
ALL_OFF
}
\n"
"
$@
"
>
&
2
}
error
()
{
local
mesg
=
$1
;
shift
printf
"
${
RED
}
==>
$(
gettext
"ERROR:"
)
${
ALL_OFF
}${
BOLD
}
${
mesg
}${
ALL_OFF
}
\n"
"
$@
"
>
&
2
}
# getopt-like parser
parseopts
()
{
local
opt
=
optarg
=
i
=
shortopts
=
$1
local
-a
longopts
=()
unused_argv
=()
shift
while
[[
$1
&&
$1
!
=
'--'
]]
;
do
longopts
+=(
"
$1
"
)
shift
done
shift
longoptmatch
()
{
local
o
longmatch
=()
for
o
in
"
${
longopts
[@]
}
"
;
do
if
[[
${
o
%:
}
=
"
$1
"
]]
;
then
longmatch
=(
"
$o
"
)
break
fi
[[
${
o
%:
}
=
"
$1
"
*
]]
&&
longmatch
+=(
"
$o
"
)
done
case
${#
longmatch
[*]
}
in
1
)
# success, override with opt and return arg req (0 == none, 1 == required)
opt
=
${
longmatch
%:
}
if
[[
$longmatch
=
*:
]]
;
then
return
1
else
return
0
fi
;;
0
)
# fail, no match found
return
255
;;
*
)
# fail, ambiguous match
printf
"pacman-key:
$(
gettext
"option '%s' is ambiguous; possibilities:"
)
"
"--
$1
"
printf
" '%s'"
"
${
longmatch
[@]%:
}
"
printf
'\n'
return
254
;;
esac
>
&
2
}
while
((
$#
))
;
do
case
$1
in
--
)
# explicit end of options
shift
break
;;
-
[
!-
]
*
)
# short option
for
((
i
=
1
;
i
<
${#
1
}
;
i++
))
;
do
opt
=
${
1
:
i
:
1
}
# option doesn't exist
if
[[
$shortopts
!
=
*
$opt
*
]]
;
then
printf
"pacman-key:
$(
gettext
"invalid option"
)
-- '%s'\n"
"
$opt
"
>
&
2
OPTRET
=(
--
)
return
1
fi
OPTRET
+=(
"-
$opt
"
)
# option requires optarg
if
[[
$shortopts
=
*
$opt
:*
]]
;
then
# if we're not at the end of the option chunk, the rest is the optarg
if
((
i
<
${#
1
}
-
1
))
;
then
OPTRET
+=(
"
${
1
:
i
+1
}
"
)
break
# if we're at the end, grab the the next positional, if it exists
elif
((
i
==
${#
1
}
-
1
))
&&
[[
$2
]]
;
then
OPTRET
+=(
"
$2
"
)
shift
break
# parse failure
else
printf
"pacman-key:
$(
gettext
"option requires an argument"
)
-- '%s'\n"
"
$opt
"
>
&
2
OPTRET
=(
--
)
return
1
fi
fi
done
;;
--?*
=
*
|
--?*
)
# long option
IFS
=
'='
read
-r
opt
optarg
<<<
"
${
1
#--
}
"
longoptmatch
"
$opt
"
case
$?
in
0
)
# parse failure
if
[[
$optarg
]]
;
then
printf
"pacman-key:
$(
gettext
"option '%s' does not allow an argument"
)
\n"
"--
$opt
"
>
&
2
OPTRET
=(
--
)
return
1
# --longopt
else
OPTRET
+=(
"--
$opt
"
)
fi
;;
1
)
# --longopt=optarg
if
[[
$optarg
]]
;
then
OPTRET
+=(
"--
$opt
"
"
$optarg
"
)
# --longopt optarg
elif
[[
$2
]]
;
then
OPTRET
+=(
"--
$opt
"
"
$2
"
)
shift
# parse failure
else
printf
"pacman-key:
$(
gettext
"option '%s' requires an argument"
)
\n"
"--
$opt
"
>
&
2
OPTRET
=(
--
)
return
1
fi
;;
254
)
# ambiguous option -- error was reported for us by longoptmatch()
OPTRET
=(
--
)
return
1
;;
255
)
# parse failure
printf
"pacman-key:
$(
gettext
"invalid option"
)
'--%s'\n"
"
$opt
"
>
&
2
OPTRET
=(
--
)
return
1
;;
esac
;;
*
)
# non-option arg encountered, add it as a parameter
unused_argv
+=(
"
$1
"
)
;;
esac
shift
done
# add end-of-opt terminator and any leftover positional parameters
OPTRET
+=(
'--'
"
${
unused_argv
[@]
}
"
"
$@
"
)
unset
longoptmatch
return
0
}
if
[[
-n
"
$MSYSTEM
"
]]
;
then
readonly
-a
UTILS_NAME
=(
'bsdtar'
'bzip2'
'bzr'
'cat'
'ccache'
'distcc'
'git'
'gpg'
'gzip'
'hg'
'lzip'
'lzop'
'openssl'
'svn'
'tput'
'uncompress'
'upx'
'xargs'
'xz'
)
for
wrapper
in
${
UTILS_NAME
[@]
}
;
do
eval
"
${
wrapper
}
"
'() {
local UTILS_PATH="/usr/bin/"
if ! type -p ${UTILS_PATH}${FUNCNAME[0]} >/dev/null; then
error "$(gettext "Cannot find the %s binary required for makepkg.")" "${UTILS_PATH}${FUNCNAME[0]}"
exit 1
fi
${UTILS_PATH}${FUNCNAME[0]} "$@"
}'
done
fi
usage
()
{
printf
"pacman-key (pacman) %s\n"
${
myver
}
echo
printf
--
"
$(
gettext
"Usage: %s [options] operation [targets]"
)
\n"
$(
basename
$0
)
echo
printf
--
"
$(
gettext
"Manage pacman's list of trusted keys"
)
\n"
echo
printf
--
"
$(
gettext
"Operations:"
)
\n"
printf
--
"
$(
gettext
" -a, --add Add the specified keys (empty for stdin)"
)
\n"
printf
--
"
$(
gettext
" -d, --delete Remove the specified keyids"
)
\n"
printf
--
"
$(
gettext
" -e, --export Export the specified or all keyids"
)
\n"
printf
--
"
$(
gettext
" -f, --finger List fingerprint for specified or all keyids"
)
\n"
printf
--
"
$(
gettext
" -l, --list-keys List the specified or all keys"
)
\n"
printf
--
"
$(
gettext
" -r, --recv-keys Fetch the specified keyids"
)
\n"
printf
--
"
$(
gettext
" -u, --updatedb Update the trustdb of pacman"
)
\n"
printf
--
"
$(
gettext
" -v, --verify Verify the file(s) specified by the signature(s)"
)
\n"
printf
--
"
$(
gettext
" --edit-key Present a menu for key management task on keyids"
)
\n"
printf
--
"
$(
gettext
" --import Imports pubring.gpg from dir(s)"
)
\n"
printf
--
"
$(
gettext
" --import-trustdb Imports ownertrust values from trustdb.gpg in dir(s)"
)
\n"
printf
--
"
$(
gettext
" --init Ensure the keyring is properly initialized"
)
\n"
printf
--
"
$(
gettext
" --list-sigs List keys and their signatures"
)
\n"
printf
--
"
$(
gettext
" --lsign-key Locally sign the specified keyid"
)
\n"
printf
--
"
$(
gettext
" --populate Reload the default keys from the (given) keyrings\n\
in '%s'"
)
\n"
"/usr/share/pacman/keyrings"
printf
--
"
$(
gettext
" --refresh-keys Update specified or all keys from a keyserver"
)
\n"
echo
printf
--
"
$(
gettext
"Options:"
)
\n"
printf
--
"
$(
gettext
" --config <file> Use an alternate config file (instead of\n\
'%s')"
)
\n"
"/etc/pacman.conf"
printf
--
"
$(
gettext
" --gpgdir <dir> Set an alternate directory for GnuPG (instead\n\
of '%s')"
)
\n"
"/etc/pacman.d/gnupg"
printf
--
"
$(
gettext
" --keyserver <server-url> Specify a keyserver to use if necessary"
)
\n"
echo
printf
--
"
$(
gettext
" -h, --help Show this help message and exit"
)
\n"
printf
--
"
$(
gettext
" -V, --version Show program version"
)
\n"
}
version
()
{
printf
"pacman-key (pacman) %s\n"
"
${
myver
}
"
printf
--
"
$(
gettext
"\
Copyright (c) 2010-2016 Pacman Development Team <pacman-dev@archlinux.org>.\n\
This is free software; see the source for copying conditions.\n\
There is NO WARRANTY, to the extent permitted by law.\n"
)
"
}
# read the config file "$1" which has key=value pairs, and return the key which
# matches "$2". the equals sign between pairs may be surrounded by any amount
# of whitespace. Optionally, "$3" can be specified which is the default value
# when no key is found.
get_from
()
{
while
IFS
=
'='
read
-r
key
value
;
do
[[
-z
$key
||
${
key
:
0
:
1
}
=
'#'
]]
&&
continue
if
[[
${
key
%% *
}
=
"
$2
"
&&
-n
${
value
##*
}
]]
;
then
echo
"
${
value
##*
}
"
return
0
fi
done
<
"
$1
"
if
[[
-n
"
$3
"
]]
;
then
printf
'%s\n'
"
$3
"
return
0
fi
return
1
}
key_lookup_from_name
()
{
local
ids
mapfile
-t
ids
<
\
<
(
"
${
GPG_PACMAN
[@]
}
"
--search-keys
--batch
--with-colons
"
$1
"
2
>/dev/null
|
awk
-F:
'$1 == "pub" { print $2 }'
)
# only return success on non-ambiguous lookup
case
${#
ids
[*]
}
in
0
)
error
"
$(
gettext
"Failed to lookup key by name:"
)
%s"
"
$name
"
return
1
;;
1
)
printf
'%s'
"
${
ids
[0]
}
"
return
0
;;
*
)
error
"
$(
gettext
"Key name is ambiguous:"
)
%s"
"
$name
"
return
1
;;
esac
}
generate_master_key
()
{
# Generate the master key, which will be in both pubring and secring
"
${
GPG_PACMAN
[@]
}
"
--gen-key
--batch
<<EOF
%echo Generating pacman keyring master key...
Key-Type: RSA
Key-Length: 2048
Key-Usage: sign
Name-Real: Pacman Keyring Master Key
Name-Email: pacman@localhost
Expire-Date: 0
%no-protection
%commit
%echo Done
EOF
}
secret_keys_available
()
{
"
${
GPG_PACMAN
[@]
}
"
-K
--with-colons
|
wc
-l
}
# Adds the given gpg.conf option if it is not present in the file.
# Note that if we find it commented out, we won't add the option.
# args: $1 conffile, $2 option-name, $3 (optional) option-value
add_gpg_conf_option
()
{
local
conffile
=
$1
;
shift
# looking for the option 'bare', only leading spaces or # chars allowed,
# followed by at least one space and any other text or the end of line.
if
!
grep
-q
"^[[:space:]#]*
$1
\([[:space:]].*\)*
$
"
"
$conffile
"
&
>/dev/null
;
then
printf
'%s\n'
"
$*
"
>>
"
$conffile
"
fi
}
check_keyids_exist
()
{
local
ret
=
0
for
key
in
"
$@
"
;
do
# Verify if the key exists in pacman's keyring
if
!
"
${
GPG_PACMAN
[@]
}
"
--list-keys
"
$key
"
&
>/dev/null
;
then
error
"
$(
gettext
"The key identified by %s could not be found locally."
)
"
"
$key
"
ret
=
1
fi
done
if
((
ret
))
;
then
exit
1
fi
}
initialize
()
{
local
conffile
keyserv
# Check for simple existence rather than for a directory as someone
# may want to use a symlink here
[[
-e
${
PACMAN_KEYRING_DIR
}
]]
||
mkdir
-p
-m
755
"
${
PACMAN_KEYRING_DIR
}
"
# keyring files
[[
-f
${
PACMAN_KEYRING_DIR
}
/pubring.gpg
]]
||
touch
${
PACMAN_KEYRING_DIR
}
/pubring.gpg
[[
-f
${
PACMAN_KEYRING_DIR
}
/secring.gpg
]]
||
touch
${
PACMAN_KEYRING_DIR
}
/secring.gpg
[[
-f
${
PACMAN_KEYRING_DIR
}
/trustdb.gpg
]]
||
"
${
GPG_PACMAN
[@]
}
"
--update-trustdb
chmod
644
${
PACMAN_KEYRING_DIR
}
/
{
pubring,trustdb
}
.gpg
chmod
600
${
PACMAN_KEYRING_DIR
}
/secring.gpg
# gpg.conf
conffile
=
"
${
PACMAN_KEYRING_DIR
}
/gpg.conf"
[[
-f
$conffile
]]
||
touch
"
$conffile
"
chmod
644
"
$conffile
"
add_gpg_conf_option
"
$conffile
"
'no-greeting'
add_gpg_conf_option
"
$conffile
"
'no-permission-warning'
add_gpg_conf_option
"
$conffile
"
'lock-never'
keyserv
=
${
KEYSERVER
:-
$DEFAULT_KEYSERVER
}
add_gpg_conf_option
"
$conffile
"
'keyserver'
"
$keyserv
"
add_gpg_conf_option
"
$conffile
"
'keyserver-options'
'timeout=10'
# set up a private signing key (if none available)
if
[[
$(
secret_keys_available
)
-lt
1
]]
;
then
generate_master_key
UPDATEDB
=
1
fi
}
check_keyring
()
{
if
[[
!
-r
${
PACMAN_KEYRING_DIR
}
/pubring.gpg
||
\
!
-r
${
PACMAN_KEYRING_DIR
}
/trustdb.gpg
]]
;
then
error
"
$(
gettext
"You do not have sufficient permissions to read the %s keyring."
)
"
"pacman"
msg
"
$(
gettext
"Use '%s' to correct the keyring permissions."
)
"
"pacman-key --init"
exit
1
fi
if
((
EXPORT
||
FINGER
||
LIST
||
VERIFY
))
;
then
if
!
grep
-q
"^[[:space:]]*lock-never[[:space:]]*
$
"
${
PACMAN_KEYRING_DIR
}
/gpg.conf
&
>/dev/null
;
then
error
"
$(
gettext
"You do not have sufficient permissions to run this command."
)
"
msg
"
$(
gettext
"Use '%s' to correct the keyring permissions."
)
"
"pacman-key --init"
exit
1
fi
fi
if
((
LSIGNKEY
))
;
then
if
[[
$(
secret_keys_available
)
-lt
1
]]
;
then
error
"
$(
gettext
"There is no secret key available to sign with."
)
"
msg
"
$(
gettext
"Use '%s' to generate a default secret key."
)
"
"pacman-key --init"
exit
1
fi
fi
}
populate_keyring
()
{
local
KEYRING_IMPORT_DIR
=
'/usr/share/pacman/keyrings'
local
keyring
KEYRINGIDS
=(
"
$@
"
)
local
ret
=
0
if
((
${#
KEYRINGIDS
[*]
}
==
0
))
;
then
# get list of all available keyrings
shopt
-s
nullglob
KEYRINGIDS
=(
"
$KEYRING_IMPORT_DIR
"
/*.gpg
)
shopt
-u
nullglob
KEYRINGIDS
=(
"
${
KEYRINGIDS
[@]##*/
}
"
)
KEYRINGIDS
=(
"
${
KEYRINGIDS
[@]%.gpg
}
"
)
if
((
${#
KEYRINGIDS
[*]
}
==
0
))
;
then
error
"
$(
gettext
"No keyring files exist in %s."
)
"
"
$KEYRING_IMPORT_DIR
"
ret
=
1
fi
else
# verify listed keyrings exist
for
keyring
in
"
${
KEYRINGIDS
[@]
}
"
;
do
if
[[
!
-f
"
$KEYRING_IMPORT_DIR
/
$keyring
.gpg"
]]
;
then
error
"
$(
gettext
"The keyring file %s does not exist."
)
"
"
$KEYRING_IMPORT_DIR
/
$keyring
.gpg"
ret
=
1
fi
done
fi
if
((
ret
))
;
then
exit
1
fi
# Variable used for iterating on keyrings
local
keys
key_id
# Add keys from requested keyrings
for
keyring
in
"
${
KEYRINGIDS
[@]
}
"
;
do
msg
"
$(
gettext
"Appending keys from %s.gpg..."
)
"
"
$keyring
"
"
${
GPG_PACMAN
[@]
}
"
--quiet
--import
"
${
KEYRING_IMPORT_DIR
}
/
${
keyring
}
.gpg"
done
# Read the trusted key IDs to an array. Because this is an ownertrust
# file, we know we have the full 40 hex digit fingerprint values.
# Format of ownertrust dump file:
# 40CHARFINGERPRINTXXXXXXXXXXXXXXXXXXXXXXX:6:
# 40CHARFINGERPRINTXXXXXXXXXXXXXXXXXXXXXXX:5:
local
-A
trusted_ids
for
keyring
in
"
${
KEYRINGIDS
[@]
}
"
;
do
if
[[
-s
"
${
KEYRING_IMPORT_DIR
}
/
${
keyring
}
-trusted"
]]
;
then
while
IFS
=
:
read
key_id
_
;
do
# skip blank lines, comments; these are valid in this file
[[
-z
$key_id
||
${
key_id
:
0
:
1
}
=
\#
]]
&&
continue
# Mark this key to be lsigned
trusted_ids
[
$key_id
]=
$keyring
done
<
"
${
KEYRING_IMPORT_DIR
}
/
${
keyring
}
-trusted"
fi
done
if
((
${#
trusted_ids
[@]
}
>
0
))
;
then
msg
"
$(
gettext
"Locally signing trusted keys in keyring..."
)
"
lsign_keys
"
${
!trusted_ids[@]
}
"
msg
"
$(
gettext
"Importing owner trust values..."
)
"
for
keyring
in
"
${
KEYRINGIDS
[@]
}
"
;
do
if
[[
-s
"
${
KEYRING_IMPORT_DIR
}
/
${
keyring
}
-trusted"
]]
;
then
"
${
GPG_PACMAN
[@]
}
"
--import-ownertrust
"
${
KEYRING_IMPORT_DIR
}
/
${
keyring
}
-trusted"
fi
done
fi
local
-A
revoked_ids
for
keyring
in
"
${
KEYRINGIDS
[@]
}
"
;
do
if
[[
-s
$KEYRING_IMPORT_DIR
/
$keyring
-revoked
]]
;
then
while
read
-r
key_id
;
do
revoked_ids
[
"
$key_id
"
]=
1
done
<
"
$KEYRING_IMPORT_DIR
/
$keyring
-revoked"
fi
done
if
((
${#
revoked_ids
[@]
}
>
0
))
;
then
msg
"
$(
gettext
"Disabling revoked keys in keyring..."
)
"
for
key_id
in
"
${
!revoked_ids[@]
}
"
;
do
msg2
"
$(
gettext
"Disabling key %s..."
)
"
"
${
key_id
}
"
printf
'disable\nquit\n'
|
LANG
=
C
"
${
GPG_PACMAN
[@]
}
"
--command-fd
0
--quiet
--batch
--edit-key
"
${
key_id
}
"
2
>/dev/null
done
fi
}
add_keys
()
{
if
!
"
${
GPG_PACMAN
[@]
}
"
--quiet
--batch
--import
"
$@
"
;
then
error
"
$(
gettext
"A specified keyfile could not be added to the keyring."
)
"
exit
1
fi
}
delete_keys
()
{
check_keyids_exist
"
$@
"
if
!
"
${
GPG_PACMAN
[@]
}
"
--quiet
--batch
--delete-key
--yes
"
$@
"
;
then
error
"
$(
gettext
"A specified key could not be removed from the keyring."
)
"
exit
1
fi
}
edit_keys
()
{
check_keyids_exist
"
$@
"
local
ret
=
0
for
key
in
"
$@
"
;
do
if
!
"
${
GPG_PACMAN
[@]
}
"
--edit-key
"
$key
"
;
then
error
"
$(
gettext
"The key identified by %s could not be edited."
)
"
"
$key
"
ret
=
1
fi
done
if
((
ret
))
;
then
exit
1
fi
}
export_keys
()
{
check_keyids_exist
"
$@
"
if
!
"
${
GPG_PACMAN
[@]
}
"
--armor
--export
"
$@
"
;
then
error
"
$(
gettext
"A specified key could not be exported from the keyring."
)
"
exit
1
fi
}
finger_keys
()
{
check_keyids_exist
if
!
"
${
GPG_PACMAN
[@]
}
"
--batch
--fingerprint
"
$@
"
;
then
error
"
$(
gettext
"The fingerprint of a specified key could not be determined."
)
"
exit
1
fi
}
import_trustdb
()
{
local
importdir
local
ret
=
0
for
importdir
in
"
$@
"
;
do
if
[[
-f
"
${
importdir
}
/trustdb.gpg"
]]
;
then
/bin/gpg
--homedir
"
${
importdir
}
"
--export-ownertrust
|
\
"
${
GPG_PACMAN
[@]
}
"
--import-ownertrust
-
if
((
PIPESTATUS
))
;
then
error
"
$(
gettext
"%s could not be imported."
)
"
"
${
importdir
}
/trustdb.gpg"
ret
=
1
fi
else
error
"
$(
gettext
"File %s does not exist and could not be imported."
)
"
"
${
importdir
}
/trustdb.gpg"
ret
=
1
fi
done
if
((
ret
))
;
then
exit
1
fi
}
import
()
{
local
importdir
local
ret
=
0
for
importdir
in
"
$@
"
;
do
if
[[
-f
"
${
importdir
}
/pubring.gpg"
]]
;
then
if
!
"
${
GPG_PACMAN
[@]
}
"
--quiet
--batch
--import
"
${
importdir
}
/pubring.gpg"
;
then
error
"
$(
gettext
"%s could not be imported."
)
"
"
${
importdir
}
/pubring.gpg"
ret
=
1
fi
else
error
"
$(
gettext
"File %s does not exist and could not be imported."
)
"
"
${
importdir
}
/pubring.gpg"
ret
=
1
fi
done
if
((
ret
))
;
then
exit
1
fi
}
list_keys
()
{
check_keyids_exist
if
!
"
${
GPG_PACMAN
[@]
}
"
--batch
--list-keys
"
$@
"
;
then
error
"
$(
gettext
"A specified key could not be listed."
)
"
exit
1
fi
}
list_sigs
()
{
check_keyids_exist
if
!
"
${
GPG_PACMAN
[@]
}
"
--batch
--list-sigs
"
$@
"
;
then
error
"
$(
gettext
"A specified signature could not be listed."
)
"
exit
1
fi
}
lsign_keys
()
{
check_keyids_exist
local
ret
=
0
for
key_id
in
"
$@
"
;
do
msg2
"
$(
gettext
"Locally signing key %s..."
)
"
"
${
key_id
}
"
# we cannot use --yes here as gpg would still ask for confirmation if a key has more than one uid
printf
'y\ny\n'
|
LANG
=
C
"
${
GPG_PACMAN
[@]
}
"
--command-fd
0
--quiet
--batch
--lsign-key
"
${
key_id
}
"
2
>/dev/null
if
((
PIPESTATUS
[
1
]
))
;
then
error
"
$(
gettext
"%s could not be locally signed."
)
"
"
${
key_id
}
"
ret
=
1
fi
done
if
((
ret
))
;
then
exit
1
fi
}
receive_keys
()
{
local
name
id
keyids
# if the key is not a hex ID, do a lookup
for
name
;
do
if
[[
$name
=
?
(
0x
)
+
([
0
-9a-fA-F
])
]]
;
then
keyids
+=(
"
$name
"
)
else
if
id
=
$(
key_lookup_from_name
"
$name
"
)
;
then
keyids
+=(
"
$id
"
)
fi
fi
done
((
${#
keyids
[*]
}
>
0
))
||
exit
1
if
!
"
${
GPG_PACMAN
[@]
}
"
--recv-keys
"
${
keyids
[@]
}
"
;
then
error
"
$(
gettext
"Remote key not fetched correctly from keyserver."
)
"
exit
1
fi
}
refresh_keys
()
{
check_keyids_exist
"
$@
"
if
!
"
${
GPG_PACMAN
[@]
}
"
--refresh-keys
"
$@
"
;
then
error
"
$(
gettext
"A specified local key could not be updated from a keyserver."
)
"
exit
1
fi
}
verify_sig
()
{
local
ret
=
0
for
sig
;
do
msg
"Checking %s..."
"
$sig
"
if
!
"
${
GPG_PACMAN
[@]
}
"
--status-fd
1
--verify
"
$sig
"
|
grep
-qE
'^\[GNUPG:\] TRUST_(FULLY|ULTIMATE)$'
;
then
error
"
$(
gettext
"The signature identified by %s could not be verified."
)
"
"
$sig
"
ret
=
1
fi
done
exit
$ret
}
updatedb
()
{
msg
"
$(
gettext
"Updating trust database..."
)
"
if
!
"
${
GPG_PACMAN
[@]
}
"
--batch
--check-trustdb
;
then
error
"
$(
gettext
"Trust database could not be updated."
)
"
exit
1
fi
}
# determine whether we have gettext; make it a no-op if we do not
if
!
type
-p
gettext
>/dev/null
;
then
gettext
()
{
printf
"%s\n"
"
$@
"
}
else
gettext
()
{
/usr/bin/gettext
"
$@
"
}
fi
OPT_SHORT
=
"adefhlruvV"
OPT_LONG
=(
'add'
'config:'
'delete'
'edit-key'
'export'
'finger'
'gpgdir:'
'help'
'import'
'import-trustdb'
'init'
'keyserver:'
'list-keys'
'list-sigs'
'lsign-key'
'nocolor'
'populate'
'recv-keys'
'refresh-keys'
'updatedb'
'verify'
'version'
)
if
!
parseopts
"
$OPT_SHORT
"
"
${
OPT_LONG
[@]
}
"
--
"
$@
"
;
then
exit
1
# E_INVALID_OPTION;
fi
set
--
"
${
OPTRET
[@]
}
"
unset
OPT_SHORT
OPT_LONG
OPTRET
if
[[
$1
==
"--"
]]
;
then
usage
;
exit
0
;
fi
while
((
$#
))
;
do
case
$1
in
-a
|
--add
)
ADD
=
1
UPDATEDB
=
1
;;
--config
)
shift
;
CONFIG
=
$1
;;
-d
|
--delete
)
DELETE
=
1
UPDATEDB
=
1
;;
--edit-key
)
EDITKEY
=
1
UPDATEDB
=
1
;;
-e
|
--export
)
EXPORT
=
1
;;
-f
|
--finger
)
FINGER
=
1
;;
--gpgdir
)
shift
;
PACMAN_KEYRING_DIR
=
$1
;;
--import
)
IMPORT
=
1
UPDATEDB
=
1
;;
--import-trustdb
)
IMPORT_TRUSTDB
=
1
UPDATEDB
=
1
;;
--init
)
INIT
=
1
;;
--keyserver
)
shift
;
KEYSERVER
=
$1
;;
-l
|
--list-keys
)
LISTKEYS
=
1
;;
--list-sigs
)
LISTSIGS
=
1
;;
--lsign-key
)
LSIGNKEY
=
1
UPDATEDB
=
1
;;
--nocolor
)
USE_COLOR
=
'n'
;;
--populate
)
POPULATE
=
1
UPDATEDB
=
1
;;
-r
|
--recv-keys
)
RECEIVE
=
1
UPDATEDB
=
1
;;
--refresh-keys
)
REFRESH
=
1
;;
-u
|
--updatedb
)
UPDATEDB
=
1
;;
-v
|
--verify
)
VERIFY
=
1
;;
-h
|
--help
)
usage
;
exit
0
;;
-V
|
--version
)
version
;
exit
0
;;
--
)
shift
;
break
2
;;
esac
shift
done
# check if messages are to be printed using color
unset
ALL_OFF
BOLD
BLUE
GREEN
RED
YELLOW
if
[[
-t
2
&&
!
$USE_COLOR
=
"n"
]]
;
then
# prefer terminal safe colored and bold text when tput is supported
if
tput
setaf
0
&
>/dev/null
;
then
ALL_OFF
=
"
$(
tput
sgr0
)
"
BOLD
=
"
$(
tput
bold
)
"
BLUE
=
"
${
BOLD
}
$(
tput
setaf
4
)
"
GREEN
=
"
${
BOLD
}
$(
tput
setaf
2
)
"
RED
=
"
${
BOLD
}
$(
tput
setaf
1
)
"
YELLOW
=
"
${
BOLD
}
$(
tput
setaf
3
)
"
else
ALL_OFF
=
"\e[1;0m"
BOLD
=
"\e[1;1m"
BLUE
=
"
${
BOLD
}
\e[1;34m"
GREEN
=
"
${
BOLD
}
\e[1;32m"
RED
=
"
${
BOLD
}
\e[1;31m"
YELLOW
=
"
${
BOLD
}
\e[1;33m"
fi
fi
readonly
ALL_OFF
BOLD
BLUE
GREEN
RED
YELLOW
if
!
type
-p
gpg
>/dev/null
;
then
error
"
$(
gettext
"Cannot find the %s binary required for all %s operations."
)
"
"gpg"
"pacman-key"
exit
1
fi
CONFIG
=
${
CONFIG
:-
/etc/pacman.conf
}
if
[[
!
-r
"
${
CONFIG
}
"
]]
;
then
error
"
$(
gettext
"%s configuration file '%s' not found."
)
"
"pacman"
"
$CONFIG
"
exit
1
fi
# if PACMAN_KEYRING_DIR isn't assigned, try to get it from the config
# file, falling back on a hard default
PACMAN_KEYRING_DIR
=
${
PACMAN_KEYRING_DIR
:-$(
get_from
"
$CONFIG
"
"GPGDir"
"/etc/pacman.d/gnupg"
)
}
GPG_PACMAN
=(
gpg
--homedir
"
${
PACMAN_KEYRING_DIR
}
"
--no-permission-warning
)
if
[[
-n
${
KEYSERVER
}
]]
;
then
GPG_PACMAN
+=(
--keyserver
"
${
KEYSERVER
}
"
)
fi
# check only a single operation has been given
# don't include UPDATEDB in here as other opts can induce it
numopt
=
$((
ADD
+
DELETE
+
EDITKEY
+
EXPORT
+
FINGER
+
IMPORT
+
IMPORT_TRUSTDB
+
INIT
+
LISTKEYS
+
LISTSIGS
+
LSIGNKEY
+
POPULATE
+
RECEIVE
+
REFRESH
+
VERIFY
))
case
$numopt
in
0
)
if
((
!
UPDATEDB
))
;
then
error
"
$(
gettext
"no operation specified (use -h for help)"
)
"
exit
1
fi
;;
[
!1
])
error
"
$(
gettext
"Multiple operations specified."
)
"
msg
"
$(
gettext
"Please run %s with each operation separately."
)
"
"pacman-key"
exit
1
;;
esac
# check for targets where needed
if
((
(
ADD
||
DELETE
||
EDIT
||
IMPORT
||
IMPORT_TRUSTDB
||
LSIGNKEY
||
RECEIVE
||
VERIFY
)
&&
$#
==
0
))
;
then
error
"
$(
gettext
"No targets specified"
)
"
exit
1
fi
((
!
INIT
))
&&
check_keyring
((
ADD
))
&&
add_keys
"
$@
"
((
DELETE
))
&&
delete_keys
"
$@
"
((
EDITKEY
))
&&
edit_keys
"
$@
"
((
EXPORT
))
&&
export_keys
"
$@
"
((
FINGER
))
&&
finger_keys
"
$@
"
((
IMPORT
))
&&
import
"
$@
"
((
IMPORT_TRUSTDB
))
&&
import_trustdb
"
$@
"
((
INIT
))
&&
initialize
((
LISTKEYS
))
&&
list_keys
"
$@
"
((
LISTSIGS
))
&&
list_sigs
"
$@
"
((
LSIGNKEY
))
&&
lsign_keys
"
$@
"
((
POPULATE
))
&&
populate_keyring
"
$@
"
((
RECEIVE
))
&&
receive_keys
"
$@
"
((
REFRESH
))
&&
refresh_keys
"
$@
"
((
VERIFY
))
&&
verify_sig
"
$@
"
((
UPDATEDB
))
&&
updatedb
exit
0
# vim: set noet: