JFIF   ( %!1!%)+...383,7(-.+  ++-+++++-++-++--+--+-+-------+-++-+--+---+++--+7+-+"F!1AQaq"2BRb#3Sr$CDsT&!Q1Aa"2Rbq ?򉄘ǷLR HR,nNb .&W)fJbMOYxj-\bT2(4CQ"qiC/ " %0Jl"e2V  0SDd2@TV^{cW&F͉x9#l,.XɳvRZ C8S 6ml!@!E! `FS!M #(d)Q lml1ml Ų&x(ʨ2NFmj@D<dN5UN˄uTB emLAy#` ` ` I!I 6āHBxL & J#7BQ.$hv h q+tC"EJ) 8R e2U2Y@j%6PF^4LnNBp"8)4JI-ֲvK ^؊)hz[T5˗",Rҥf8ڤS4ʘ!`D ` X+ L,(hl)*S##`6[`0*L T H*HA@I&&r1kr*r*)N$#L  1#ZFSl `[( ("((he`4 Ch [="A R / 0I`twCDcWh"i) cLad\BcLKHZ"ZEW$Ƚ@A~i^`S *A&h:+c Y6vϕGClRPs.`H`(@<$qDe pL@DpLX, E2MP A  `II m& AQ "AT rbg# g2!SiLj*3L \ G;TFL`K BMy 2S`YLh1 d >-"ZfD^Q DH" RAbEV#Lfq,(rETp64-IJ!*p4F$q;G8DQ/TKP2$jp3KW]FtLtƉ1ol]VBgػJH6 )h61GJR7Nj.Z4piJRDd]t]0dP]:N.b'⹙SvDSz]L,_#ugT&[~?cS^"{Bh{/=ۑxOk̳O59o dar793`)SeYM@\ "$E(Tm&)N2Ih)F5EDed(FS,Pa @!@#@lea HCD$11jCLJqcod S3yd*,lL+QEfsgW1nw)cT#dS HXkFJB"6(ʝH)H"#EZh:Y`khݳh%Sc<mlAko2]gDqQtro=3OƸU9_-t8UvW3sGəg*#:c)><"wc\ASmT|6Ę>9~#1Ƈ~ڒE1vVi# I MM#u$8W 5ǍfƬΜg*Qpi1ȩFOf۔S,/⎯(Lrմ`(Z LsbA \6 6dm[I=!r:REI.wgzG)ԇSbӑxuׇTyyL^e'x^ty4Z&eB]I|v59Jjhm;Ng񷫳n<ϞҼѝjk;׹DlY^ҍ\+x9V!j([cmS.NO6jxNζrm&oײizT$N>?~ Sl-:iڥk\at#E!CL`.O0a*w/WV7/r)DŽt7'Nĵ#7O1 ]{[/-2bA<$&Gm_4t)_>)mjG;V^'k59o>ɌM,ؾf9z6 4v_3T.5V/RD-5 %T5XTޫ4TaZ`U *ƱUƲ UG"5+sJJ2E9#܎kr2G3Bb,XM6H: ?@p!'\4V02aԙ) hbZ]:` ev3ʘ'}!ohȒ*TJjr[RFyQ*#{h{R]J]Lr-.D-.җfo$D ?X0%~1P.Og{cWϫ22&Ϭ_V.W3nmiOl}+!˫#`kR33aUb0-g:qmsέ+0HO|&nhOn+}n5QF_"gvLm/z'+r'n_oC语i|1}Gi|}_D~9JZ_%DVQp\koۅjAs~/c0ksUJi^W9W5!>?O:q|ˣSIB/&K<(lg(%Wg$|LW7vߤW߇q|jef3D H\S6(eJb*@&sTKTW/*@v:.N- @ITʓ1Zg&-eꓝM r]EMס{q$b]'7Z7N:O~lNlP7iͲk)$O^퉢<YSD*hr'Z#5e6t[Fdh AJǔP9P 1\R).Il+jI*,(ܢ22N*OwKFX gc?\mB7iA+εe8 "ġ/p5pW-$މ-[a 5ViAW/V{/&UsF./՞ҕ*)rZg.^_+gt_z-oAbqQn*WlHyZ*\TaEewlLR3ԹȭN}MM}aih"5ܕRT$:~'TcT|*)xGC>n+r{XU xuF"<~67у'fxlf`r3D*#Z1ђfH`2dIWo/qB| 63xxW6^m%Kvg>\>x>!H5Nr8J/FJ9Wx(Hou" S'kWاC\9ְ#^OaҮ+~gnkuЉ,aWU*1 읍jnb|e= :2.UL`Q}YS&gI.c=a`%j:C%2@^>])25/ܙ<lzwɛ)ݣS4h3=J tyϬ.E7 8ڞGZu\_JHsݢϑ}IZ"ӳ=X<Ɖ2{a:{7L+>V}c)*lo Yv&+|L;>+/Sj26K+澡*;>-s"}M2] Ig5aCL*r"&\} #^R.7_Mgf}.ߌy(}Z\gP&ʠHj%</{.]rߙQ`>;5g;u6dԛ %xb|oՋTJ5Ϥ(]XqP>f{Jk2,8'~ZU6tMQsg XKg^2ϓ3},[wo۴I|ܷ%[Ol\Pkr]Y//cg6U⧻/VПi8ys_n<\~cze!!H~x;QJZKȮ^ȧG|cS~8ji,Fo+,y~?pk)u /in3JmkX(Mj1N 4c Epc>BO *LfQO&` c;LjcYf 1ɻ)CLsY^Y5" lP/wuEln&dav,(;'W9ej ku`-KHI՟%ԁʁ 1\}?OjsF^Xn$Ё.օC>D:?I @aGE.ĩ1 $ et~T`߸Ir'RX.Zwc%~U=r>-UaFbǺ?R=Z?i'[ASS;siJrzy>nxu$[_B\4}:r'ҵj1_v-[;y?ֹ0I16 . M%4^!S&t ! h !zQð.bBT ?@]?CHq(rd!.$>/x+bnʎNN#w)` )*f!-ɂ\(طYLHzc`Uq7BfCcE0ԉ4Fم쏠ce5T r͸GVlФ?ѣ} mhrkly.Ts㷖)Mө S^%'g>wk%bP[}j~ǾV#K -Fgv켼ǨgɼeSz/6{M=BPZFu\Q75n3Iݤ.W9QfF{vJwF't[@iVj4G~KOnH߿_Do=.c.One?E+GfGN⧭H?4;u`ua|V-+j4?48n ɦ=-]puv&Jc}K>b%U x8pz6L8AXFsW]N55ҦbIWZQ7ï Ԗ3cjz匩ӺOTɖƴ%a'MI}cdR$ݚIζ̝ LIu>J3{^෠㜦˯xܿe\b"2y'x{ RDW b+o2KFhR0:U늞En>լRӉt Iڹ\ wշQEv"v;EJ)yl[5:F0=b4,\PqKtv4{bQz:>C7"8W#Zjdd| cjz%K %Z 9dD{=NFʳAƩtI)kS*s$`:A\ʬ*ֹ9{Nl|eJ١rQnM%z_#x_•TO><)kyD %GN<~y>vfǧB)F)c\lې(#\ h`fgfjTBdhhHL2Y0^ Y0^-"D!QaI15 m~ gՒd|;#gMn(P$l H.R2^PU")pN` N8󫅂OJ;^jz\uumJMF|ηq[]$Vrrt:Q^;QPkHՠ{]HwˆMuIr7!r&- j%"9LtUb56+^TWBqdhHAD7 HwKH^F3LIq #hK`]IWKiH?کǴeԥQ>g{^q^>HKoOB||8aݏS}{S_]ϸ/X~ܵw'OSPAf֩ܟ[>7 @[ֵ;G߇QU*Cթ *OKU^zz[fRnpcJX9u<iq8B]u8 ]I,;[G#2W.¸D8rPG Y%PBJ= wo;PJgx6;yB`3zZGPAͫy{5Nb_re*ONHR]Ji)U{Ӓ:qqɏ[mB4࢒I$ 2vpBADY`DIVAn"Bh$&&cMbdB 鮆wHR'E(ѸZA*H~{B M҅n\@N{7ISCp Vd( r+bg|ns:qg:|J|ɪV.UVaAS͓FyRuLѦT騬 `3􏳕{eo/Tz8DkW?,cl~TqLne֠[B*D +t 6˦S;5KjV3e WBrT.XSHm sl5F%NGM`Y )": J!W4]HTrPX2 QYɕ\m2VLd+`,^ѺiPztUGY6+cӧ6] U%u/ˈFOiB*nFF#ұJ Z/c')?Q͟5.8E~G6e<\?}GkhMFUظOqhEA - "`dQ#(4Ԧf VLmc@q5J8K; M^JZnn)9Zm\ qIJqS: i[9~Oaƒ]Z4F&+666( N]쁼LM(oyvUI/Χ[ھ]hTˉG".SeYgu;hRDtڬv=5 ׁqMS\Ȭi5D]1$*0UL1QY`QdLb[+z9";'yi`OT/4{@EZ'Y0>4I*d nM#5hі.vrM[]Ä;]\ʦS,叕DQZq0fӌI͋]TNK"#;?F;aURx_4WDm+F*0XJE@){ 1R-E2(@Qh l D rT.Q;[J;[`30`ɀ 2#=JeSsxRjG=`H rLJ@ Y$JaB2/x( "Id'6O0CI$:Ol+}I>[L|iK+]ZrH*2Aʶ uHRd)OrrbSx=5dmue1neܬ"e>Lw94勲u ҏ_4GuоJw]QtgSk(qW(6h|v= 1=P/\YZ|R>"*5W/ίR'o %R$5= .!VIRMf4*aR5nv% Usj:V Lj]Bn/TZ&.2„ܒBP)aYRʌW!#ErGf';tW$czI*\KI,c7Zc-ўj|p+-ђ{eg 2;R_{VLM]7sؒFmԻy853gҾqJG!E̤ӏqzs༿? U#R)ŧU(,>,&,-^e^۔.b EW^n<)\9.QeJuFiSh2"EL8yeCKQD\5R,D5.P]c1STt*ZFJ.T:N #%]M}khOe(͓iEMsɆ3( YF<"Ly^*[ry6.ɸm k݊iT%nM8 $Q#F# q 1*?% iS^4oܗ wWPS,aNޖxOxڽqp#F6&o,7LJuMΤK(Td{U Ƹf|q5U{3[FLNK6ӵQY5+'>Q3FSk).&:5z yZq/*q$d+Ge+$lO@Nڤy5eBvˌ䖥shS:JksgksF ꧸oi-FYxy9[Vȼĝ'_.[y2U*c?E+:TsWՀgOS> z75>ncߏ-Kz8ԋ,Ϧ70Z9_1h$Xiu10)0$+$! qsE4wRkh2*T.s%DH:`:=k.'WB{ ȮRGҷ7чVg)CHS}1ݍԳۂ<8g_4y*-Ml\]mZT)mJ~|k<6zWjf4'*u%RNRȉZA) .VLtp 4 V&mtJ#l˅;&{]8>TmhoLXOeD^_J>]jsSej﫦iOM SK([!Vc5zn-A@p]Ӄ \3kmK>#-sܧ?NLar@Js?…Xldny]݌E5•9.8hh69#7js׳R,'pqt:kgPhRԄ+ՕG9}="ֲ\kǁm R73pg$t3+o |o\]'ee5ɐ.7ѐ|ZعSF{qkx5-$Q h5*1yM$ 7)hJ2Kg`-hn*>)EYDIkBpȩAzfǪ>7O K#lߤg]:u~huُ۵u}(mjGIj܏6ES~/5CiRy|kVKGBޭ3;w /jꏈUu>iƪi:WRo'yr4C/?c:w!?\'?#Q:>u/?uEeuG*xY2)?־CAr*23_ץ}գk1%(_ _6aԗ _4 $ϗ+ϫɆzǾIgu?Y<#_xS>i\uɇ۽r}[ͫyRoWCC!H,iD։"Cj5 4] cTk2YZRBvRY~FqQt^RO-g"QP]Ih/t:ljs YӹqI] wqXp KV+8j} uu8PGP&zF:;8+ Sx9(. Q}:ƻWr,Ũ*'shfƧ-6__5,DH{* qp묘G MA}QRe{dyMucǨɾ7߈Avϩe͜jmUi p3\5,ާbf:o+7#ܾ~iU#up=}˄k{NV8m!ҌiptޜBvKi}!ש3UK)`igӞVMR'J[ky~g&6vǍ7ķ>uXd(3瓓[]QTTqnͮz1~_͓k俸0~Z1գ =18cL 5^lf^k^<ҲJɬcC-[^;J8j_q=WpeA_6 4.Ntc>Sv2Jf;G8. 5[,;ArSTˬmpmzjGe EoǩOgDWaGhz<|kT\$Q=u/ci˜S mN&Ok~'0,a} s + NC-G'(*>vw~&*wYG Ŷ K-L/$߮l/A/^:Z@X- Q-D2`@M2+w$Q"胊"47&+Dh'9Y* L7VhT+ -?K]Ik \Ϣgy) s v z)Z ˦2&ލ OjmG9@8F_u䊜r>3K%Yg-FFI]e+Kxkzװy"\Q4Ri'0+P=V&Sw3N/U|UEt*uS c M*tsBE 2ʃ@Kir(˫LRr璜Zy@].%NbXvz덟 hӰNMe#|g͒po9^licxB[e' {U? mlt%?霋ǒxZc X]ϗ15SeE{-Ӕi~DƯO|ë5a@G=%<ƧAs*+tzo, IpȔ|:X6J3Z5JXd]2 3%v*GvE@(S&SX7D0^{5t Z{ﮄsh- ]ɑqEV=^Ki9äBtI@&pEg*O<`F-}ǎ51H,<~qibQѓɳx#l$G9td1U+Sq%B[jOq+^ޏ7K >YY  $KK{*˝e"|$g"6v,,9.DaA,qэI~ܨ|kdv; hz2]x5{M5M~yלqTzUl9Mӏ.WVnkun !jzKO!v|& ;gۇ2BrI閵C tqHe[Zkގ=Q;OԶiᵞBcIU eN cOGz S__>.hNgG6).J$_Taѯ5^LqeB]O?A]H;ò{^0ٺuޚxB|:q'xu4"9Ο7k^eZ_fQOmzm̗{c3ٵKO|m*ek(8"yO(ٵ{LJb2Ǩkgg1_/qrDՆ[_l\ I~Bsc/x ),,̿@PFޞ>O)<<=5m=^x6}~6qoYGޣiY{uN+<,CǚwVxe~c!,5R4u/9In=G•^PF6ɼM򿶤$"\|78ؖYU cXFOKc4s-=6O<;.ϴ޶$q>e? qY}StirX?e/&R'ʑ[ѯMi{?8\g^>\!-VZCf.ȾzRWMh_{^H)mz}V%չM.EJUz7z>ZW6\BW~:W3!S_4~m ǚ! ;VeGKFڵ858Buj:ZZ(/H׭eav!$gpLV)țAJO~YBꤞ厅XJdjg{hR9~_f '5U+}W5%ZjzgTtozYD @%JK\qymeЪKIIp"xoz\B1$G)8Ԅ Jeyc".yyVBR-%BEA-k^Luj cYwԄ%X!e-4ZRḡlJvYsB԰˗0?RM\TlaߏVu4BmY!UyYylgd!m2$i=[hN,6)_~7͖CDF2zÕ{?l;Hܲk׋!/XAłrCXEI{]P[e! ?%Ktqܱ5! jַĞ*TvAG)fuxTҖV7~ 4=r! ob%jTwU$Bnqed䤿@0P&V]HJ)^YrޯĿbsY8=1! n}UD*7uƫi~!s[W{V9J;~Ӯ|[3s۷dڔIj?qJ'O,IkE]G(5\ۖ7)-g,ŶǗ=~e>k쐁%(g˦o[fxN_baGBm:܆VGЗ,G_D!/og,ҢVܤ_iS_~@ SkidSec Webshell

SkidSec WebShell

Server Address : 172.31.38.4

Web Server : Apache/2.4.58 (Ubuntu)

Uname : Linux ip-172-31-38-4 6.14.0-1017-aws #17~24.04.1-Ubuntu SMP Wed Nov 5 10:48:17 UTC 2025 x86_64

PHP Version : 7.4.33



Current Path : /proc/thread-self/root/bin/



Current File : //proc/thread-self/root/bin/apt-key
#!/bin/sh

set -e
unset GREP_OPTIONS GPGHOMEDIR CURRENTTRAP
export IFS="$(printf "\n\b")"

MASTER_KEYRING='/usr/share/keyrings/ubuntu-master-keyring.gpg'
eval "$(apt-config shell MASTER_KEYRING APT::Key::MasterKeyring)"
ARCHIVE_KEYRING='/usr/share/keyrings/ubuntu-archive-keyring.gpg'
eval "$(apt-config shell ARCHIVE_KEYRING APT::Key::ArchiveKeyring)"
REMOVED_KEYS='/usr/share/keyrings/ubuntu-archive-removed-keys.gpg'
eval "$(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys)"
ARCHIVE_KEYRING_URI='http://archive.ubuntu.com/ubuntu/project/ubuntu-archive-keyring.gpg'
eval "$(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI)"

aptkey_echo() { echo "$@"; }

find_gpgv_status_fd() {
   while [ -n "$1" ]; do
	if [ "$1" = '--status-fd' ]; then
		shift
		echo "$1"
		break
	fi
	shift
   done
}
GPGSTATUSFD="$(find_gpgv_status_fd "$@")"

apt_warn() {
    if [ -z "$GPGHOMEDIR" ]; then
	echo >&2 'W:' "$@"
    else
	echo 'W:' "$@" > "${GPGHOMEDIR}/aptwarnings.log"
    fi
    if [ -n "$GPGSTATUSFD" ]; then
	echo >&${GPGSTATUSFD} '[APTKEY:] WARNING' "$@"
    fi
}
apt_error() {
    if [ -z "$GPGHOMEDIR" ]; then
	echo >&2 'E:' "$@"
    else
	echo 'E:' "$@" > "${GPGHOMEDIR}/aptwarnings.log"
    fi
    if [ -n "$GPGSTATUSFD" ]; then
	echo >&${GPGSTATUSFD} '[APTKEY:] ERROR' "$@"
    fi
}

cleanup_gpg_home() {
    if [ -z "$GPGHOMEDIR" ]; then return; fi
    if [ -s "$GPGHOMEDIR/aptwarnings.log" ]; then
	cat >&2 "$GPGHOMEDIR/aptwarnings.log"
    fi
    if command_available 'gpgconf'; then
	GNUPGHOME="${GPGHOMEDIR}" gpgconf --kill all >/dev/null 2>&1 || true
    fi
    rm -rf "$GPGHOMEDIR"
}

# gpg needs (in different versions more or less) files to function correctly,
# so we give it its own homedir and generate some valid content for it later on
create_gpg_home() {
    # for cases in which we want to cache a homedir due to expensive setup
    if [ -n "$GPGHOMEDIR" ]; then
	return
    fi
    if [ -n "$TMPDIR" ]; then
	# tmpdir is a directory and current user has rwx access to it
	# same tests as in apt-pkg/contrib/fileutl.cc GetTempDir()
	if [ ! -d "$TMPDIR" ] || [ ! -r "$TMPDIR" ] || [ ! -w "$TMPDIR" ] || [ ! -x "$TMPDIR" ]; then
	    unset TMPDIR
	fi
    fi
    GPGHOMEDIR="$(mktemp --directory --tmpdir 'apt-key-gpghome.XXXXXXXXXX')"
    CURRENTTRAP="${CURRENTTRAP} cleanup_gpg_home;"
    trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
    if [ -z "$GPGHOMEDIR" ]; then
	apt_error "Could not create temporary gpg home directory in $TMPDIR (wrong permissions?)"
	exit 28
    fi
    chmod 700 "$GPGHOMEDIR"
}

requires_root() {
	if [ "$(id -u)" -ne 0 ]; then
		apt_error "This command can only be used by root."
		exit 1
	fi
}

command_available() {
    if [ -x "$1" ]; then return 0; fi
    command -v "$1" >/dev/null # required by policy, see #747320
}

escape_shell() {
    echo "$@" | sed -e "s#'#'\"'\"'#g"
}

get_fingerprints_of_keyring() {
    aptkey_execute "$GPG_SH" --keyring "$1" --with-colons --fingerprint | while read publine; do
	# search for a public key
	if [ "${publine%%:*}" != 'pub' ]; then continue; fi
	# search for the associated fingerprint (should be the very next line)
	while read fprline; do
	   if [ "${fprline%%:*}" = 'sub' ]; then break; # should never happen
	   elif [ "${fprline%%:*}" != 'fpr' ]; then continue; fi
	   echo "$fprline" | cut -d':' -f 10
	done
	# order in the keyring shouldn't be important
    done | sort
}

add_keys_with_verify_against_master_keyring() {
    ADD_KEYRING="$1"
    MASTER="$2"

    if [ ! -f "$ADD_KEYRING" ]; then
	apt_error "Keyring '$ADD_KEYRING' to be added not found"
	return
    fi
    if [ ! -f "$MASTER" ]; then
	apt_error "Master-Keyring '$MASTER' not found"
	return
    fi

    # when adding new keys, make sure that the archive-master-keyring
    # is honored. so:
    #   all keys that are exported must have a valid signature
    #   from a key in the $distro-master-keyring
    add_keys="$(get_fingerprints_of_keyring "$ADD_KEYRING")"
    all_add_keys="$(aptkey_execute "$GPG_SH" --keyring "$ADD_KEYRING" --with-colons --list-keys | grep ^[ps]ub | cut -d: -f5)"
    master_keys="$(aptkey_execute "$GPG_SH" --keyring "$MASTER" --with-colons --list-keys | grep ^pub | cut -d: -f5)"

    # ensure there are no colisions LP: #857472
    for all_add_key in $all_add_keys; do
	for master_key in $master_keys; do
            if [ "$all_add_key" = "$master_key" ]; then
                echo >&2 "Keyid collision for '$all_add_key' detected, operation aborted"
                return 1
            fi
        done
    done

    for add_key in $add_keys; do
        # export the add keyring one-by-one
	local TMP_KEYRING="${GPGHOMEDIR}/tmp-keyring.gpg"
	aptkey_execute "$GPG_SH" --batch --yes --keyring "$ADD_KEYRING" --output "$TMP_KEYRING" --export "$add_key"
	if ! aptkey_execute "$GPG_SH" --batch --yes --keyring "$TMP_KEYRING" --import "$MASTER" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then
	    cat >&2 "${GPGHOMEDIR}/gpgoutput.log"
	    false
	fi
	# check if signed with the master key and only add in this case
	ADDED=0
	for master_key in $master_keys; do
	    if aptkey_execute "$GPG_SH" --keyring "$TMP_KEYRING" --check-sigs --with-colons "$add_key" \
	       | grep '^sig:!:' | cut -d: -f5 | grep -q "$master_key"; then
		aptkey_execute "$GPG_SH" --batch --yes --keyring "$ADD_KEYRING" --export "$add_key" \
		   | aptkey_execute "$GPG" --batch --yes --import
		ADDED=1
	    fi
	done
	if [ $ADDED = 0 ]; then
	    echo >&2 "Key '$add_key' not added. It is not signed with a master key"
	fi
	rm -f "${TMP_KEYRING}"
    done
}

# update the current archive signing keyring from a network URI
# the archive-keyring keys needs to be signed with the master key
# (otherwise it does not make sense from a security POV)
net_update() {
    local APT_DIR='/'
    eval $(apt-config shell APT_DIR Dir)

    # Disabled for now as code is insecure (LP: #1013639 (and 857472, 1013128))
    APT_KEY_NET_UPDATE_ENABLED=""
    eval $(apt-config shell APT_KEY_NET_UPDATE_ENABLED APT::Key::Net-Update-Enabled)
    if [ -z "$APT_KEY_NET_UPDATE_ENABLED" ]; then
        exit 1
    fi

    if [ -z "$ARCHIVE_KEYRING_URI" ]; then
	apt_error 'Your distribution is not supported in net-update as no uri for the archive-keyring is set'
	exit 1
    fi
    # in theory we would need to depend on wget for this, but this feature
    # isn't usable in debian anyway as we have no keyring uri nor a master key
    if ! command_available 'wget'; then
	apt_error 'wget is required for a network-based update, but it is not installed'
	exit 1
    fi
    if [ ! -d "${APT_DIR}/var/lib/apt/keyrings" ]; then
	mkdir -p "${APT_DIR}/var/lib/apt/keyrings"
    fi
    keyring="${APT_DIR}/var/lib/apt/keyrings/$(basename "$ARCHIVE_KEYRING_URI")"
    old_mtime=0
    if [ -e $keyring ]; then
	old_mtime=$(stat -c %Y "$keyring")
    fi
    (cd  "${APT_DIR}/var/lib/apt/keyrings"; wget --timeout=90 -q -N "$ARCHIVE_KEYRING_URI")
    if [ ! -e "$keyring" ]; then
	return
    fi
    new_mtime=$(stat -c %Y "$keyring")
    if [ $new_mtime -ne $old_mtime ]; then
	aptkey_echo "Checking for new archive signing keys now"
	add_keys_with_verify_against_master_keyring "$keyring" "$MASTER_KEYRING"
    fi
}

update() {
    if [ -z "$APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE" ]; then
	echo >&2 "Warning: 'apt-key update' is deprecated and should not be used anymore!"
	if [ -z "$ARCHIVE_KEYRING" ]; then
	    echo >&2 "Note: In your distribution this command is a no-op and can therefore be removed safely."
	    exit 0
	fi
    fi
    if [ ! -f "$ARCHIVE_KEYRING" ]; then
	apt_error "Can't find the archive-keyring (Is the ubuntu-keyring package installed?)"
	exit 1
    fi

    # add new keys from the package;

    # we do not use add_keys_with_verify_against_master_keyring here,
    # because "update" is run on regular package updates.  A
    # attacker might as well replace the master-archive-keyring file
    # in the package and add his own keys. so this check wouldn't
    # add any security. we *need* this check on net-update though
    import_keyring_into_keyring "$ARCHIVE_KEYRING" '' && cat "${GPGHOMEDIR}/gpgoutput.log"

    if [ -r "$REMOVED_KEYS" ]; then
	# remove no-longer supported/used keys
	get_fingerprints_of_keyring "$(dearmor_filename "$REMOVED_KEYS")" | while read key; do
	    foreach_keyring_do 'remove_key_from_keyring' "$key"
	done
    else
	apt_warn "Removed keys keyring '$REMOVED_KEYS' missing or not readable"
    fi
}

remove_key_from_keyring() {
    local KEYRINGFILE="$1"
    shift
    # non-existent keyrings have by definition no keys
    if [ ! -e "$KEYRINGFILE" ]; then
       return
    fi

    local FINGERPRINTS="${GPGHOMEDIR}/keyringfile.keylst"
    local DEARMOR="$(dearmor_filename "$KEYRINGFILE")"
    get_fingerprints_of_keyring "$DEARMOR" > "$FINGERPRINTS"

    for KEY in "$@"; do
	# strip leading 0x, if present:
	KEY="$(echo "${KEY#0x}" | tr -d ' ')"

	# check if the key is in this keyring
	if ! grep -iq "^[0-9A-F]*${KEY}$" "$FINGERPRINTS"; then
	    continue
	fi
	if [ ! -w "$KEYRINGFILE" ]; then
	    apt_warn "Key ${KEY} is in keyring ${KEYRINGFILE}, but can't be removed as it is read only."
	    continue
	fi
	# check if it is the only key in the keyring and if so remove the keyring altogether
	if [ '1' = "$(uniq "$FINGERPRINTS" | wc -l)" ]; then
	    mv -f "$KEYRINGFILE" "${KEYRINGFILE}~" # behave like gpg
	    return
	fi
	# we can't just modify pointed to files as these might be in /usr or something
	local REALTARGET
	if [ -L "$DEARMOR" ]; then
	    REALTARGET="$(readlink -f "$DEARMOR")"
	    mv -f "$DEARMOR" "${DEARMOR}.dpkg-tmp"
	    cp -a "$REALTARGET" "$DEARMOR"
	fi
	# delete the key from the keyring
	aptkey_execute "$GPG_SH" --keyring "$DEARMOR" --batch --delete-keys --yes "$KEY"
	if [ -n "$REALTARGET" ]; then
	    # the real backup is the old link, not the copy we made
	    mv -f "${DEARMOR}.dpkg-tmp" "${DEARMOR}~"
	fi
	if [ "$DEARMOR" != "$KEYRINGFILE" ]; then
	    mv -f "$KEYRINGFILE" "${KEYRINGFILE}~"
	    create_new_keyring "$KEYRINGFILE"
	    aptkey_execute "$GPG_SH" --keyring "$DEARMOR" --armor --export > "$KEYRINGFILE"
	fi
	get_fingerprints_of_keyring "$DEARMOR" > "$FINGERPRINTS"
    done
}

accessible_file_exists() {
   if ! test -s "$1"; then
      return 1
   fi
   if test -r "$1"; then
      return 0
   fi
   apt_warn "The key(s) in the keyring $1 are ignored as the file is not readable by user '$USER' executing apt-key."
   return 1
}

is_supported_keyring() {
    # empty files are always supported
    if ! test -s "$1"; then
	return 0
    fi
    local FILEEXT="${1##*.}"
    if [ "$FILEEXT" = 'gpg' ]; then
	# 0x98, 0x99 and 0xC6 via octal as hex isn't supported by dashs printf
	if printf '\231' | cmp -s -n 1 - "$1"; then
	    true
	elif printf '\230' | cmp -s -n 1 - "$1"; then
	    true
	elif printf '\306' | cmp -s -n 1 - "$1"; then
	    true
	else
	    apt_warn "The key(s) in the keyring $1 are ignored as the file has an unsupported filetype."
	    return 1
	fi
    elif [ "$FILEEXT" = 'asc' ]; then
	true #dearmor_filename will deal with them
    else
	# most callers ignore unsupported extensions silently
	apt_warn "The key(s) in the keyring $1 are ignored as the file has an unsupported filename extension."
	return 1
    fi
    return 0
}

foreach_keyring_do() {
   local ACTION="$1"
   shift
   # if a --keyring was given, just work on this one
   if [ -n "$FORCED_KEYRING" ]; then
	$ACTION "$FORCED_KEYRING" "$@"
   else
	# otherwise all known keyrings are up for inspection
	if accessible_file_exists "$TRUSTEDFILE" && is_supported_keyring "$TRUSTEDFILE"; then
	    $ACTION "$TRUSTEDFILE" "$@"
	fi
	local TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
	eval "$(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)"
	if [ -d "$TRUSTEDPARTS" ]; then
	    TRUSTEDPARTS="$(readlink -f "$TRUSTEDPARTS")"
	    local TRUSTEDPARTSLIST="$(cd /; find "$TRUSTEDPARTS" -mindepth 1 -maxdepth 1 \( -name '*.gpg' -o -name '*.asc' \))"
	    for trusted in $(echo "$TRUSTEDPARTSLIST" | sort); do
		if accessible_file_exists "$trusted" && is_supported_keyring "$trusted"; then
		    $ACTION "$trusted" "$@"
		fi
	    done
	fi
   fi
}

list_keys_in_keyring() {
    local KEYRINGFILE="$1"
    shift
    # fingerprint and co will fail if key isn't in this keyring
    aptkey_execute "$GPG_SH" --keyring "$(dearmor_filename "$KEYRINGFILE")" "$@" > "${GPGHOMEDIR}/gpgoutput.log" 2> "${GPGHOMEDIR}/gpgoutput.err" || true
    if [ ! -s "${GPGHOMEDIR}/gpgoutput.log" ]; then
	return
    fi
    # we fake gpg header here to refer to the real asc file rather than a temp file
    if [ "${KEYRINGFILE##*.}" = 'asc' ]; then
	if expr match "$(sed -n '2p' "${GPGHOMEDIR}/gpgoutput.log")" '^-\+$' >/dev/null 2>&1; then
	    echo "$KEYRINGFILE"
	    echo "$KEYRINGFILE" | sed 's#[^-]#-#g'
	    sed '1,2d' "${GPGHOMEDIR}/gpgoutput.log" || true
	else
	    cat "${GPGHOMEDIR}/gpgoutput.log"
	fi
    else
	cat "${GPGHOMEDIR}/gpgoutput.log"
    fi
    if [ -s "${GPGHOMEDIR}/gpgoutput.err" ]; then
	cat >&2 "${GPGHOMEDIR}/gpgoutput.err"
    fi
}

export_key_from_to() {
    local FROM="$1"
    local TO="$2"
    shift 2
    if ! aptkey_execute "$GPG_SH" --keyring "$(dearmor_filename "$FROM")" --export "$@" > "$TO" 2> "${GPGHOMEDIR}/gpgoutput.log"; then
	cat >&2 "${GPGHOMEDIR}/gpgoutput.log"
	false
    else
	chmod 0644 -- "$TO"
    fi
}

import_keyring_into_keyring() {
    local FROM="${1:-${GPGHOMEDIR}/pubring.gpg}"
    local TO="${2:-${GPGHOMEDIR}/pubring.gpg}"
    shift 2
    rm -f "${GPGHOMEDIR}/gpgoutput.log"
    # the idea is simple: We take keys from one keyring and copy it to another
    # we do this with so many checks in between to ensure that WE control the
    # creation, so we know that the (potentially) created $TO keyring is a
    # simple keyring rather than a keybox as gpg2 would create it which in turn
    # can't be read by gpgv.
    # BEWARE: This is designed more in the way to work with the current
    # callers, than to have a well defined it would be easy to add new callers to.
    if [ ! -s "$TO" ]; then
	if [ -s "$FROM" ]; then
	    if [ -z "$2" ]; then
		local OPTS
		if [ "${TO##*.}" = 'asc' ]; then
		    OPTS='--armor'
		fi
		export_key_from_to "$(dearmor_filename "$FROM")" "$TO" $OPTS ${1:+"$1"}
	    else
		create_new_keyring "$TO"
	    fi
	else
	    create_new_keyring "$TO"
	fi
    elif [ -s "$FROM" ]; then
	local EXPORTLIMIT="$1"
	if [ -n "$1$2" ]; then shift; fi
	local DEARMORTO="$(dearmor_filename "$TO")"
	if ! aptkey_execute "$GPG_SH" --keyring "$(dearmor_filename "$FROM")" --export ${EXPORTLIMIT:+"$EXPORTLIMIT"} \
	   | aptkey_execute "$GPG_SH" --keyring "$DEARMORTO" --batch --import "$@" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then
	    cat >&2 "${GPGHOMEDIR}/gpgoutput.log"
	    false
	fi
	if [ "$DEARMORTO" != "$TO" ]; then
	    export_key_from_to "$DEARMORTO" "${DEARMORTO}.asc" --armor
	    if ! cmp -s "$TO" "${DEARMORTO}.asc" 2>/dev/null; then
		cp -a "$TO" "${TO}~"
		mv -f "${DEARMORTO}.asc" "$TO"
	    fi
	fi
    fi
}

dearmor_keyring() {
    # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=831409#67
    # The awk script is more complex through to skip surrounding garbage and
    # to support multiple keys in one file (old gpgs generate version headers
    # which get printed with the original and hence result in garbage input for base64
    awk '{ gsub(/\r/,"") }
/^-----BEGIN/{ x = 1; }
/^$/{ if (x == 1) { x = 2; }; }
/^[^=-]/{ if (x == 2) { print $0; }; }
/^-----END/{ x = 0; }' | base64 -d
}
dearmor_filename() {
    if [ "${1##*.}" = 'asc' ]; then
	local trusted="${GPGHOMEDIR}/${1##*/}.gpg"
	if [ -s "$1" ]; then
	    dearmor_keyring < "$1" > "$trusted"
	fi
	echo "$trusted"
    elif [ "${1##*.}" = 'gpg' ]; then
	echo "$1"
    elif [ "$(head -n 1 "$1" 2>/dev/null)" = '-----BEGIN PGP PUBLIC KEY BLOCK-----' ]; then
	local trusted="${GPGHOMEDIR}/${1##*/}.gpg"
	dearmor_keyring < "$1" > "$trusted"
	echo "$trusted"
    else
	echo "$1"
    fi
}
catfile() {
    cat "$(dearmor_filename "$1")" >> "$2"
}

merge_all_trusted_keyrings_into_pubring() {
    # does the same as:
    # foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg"
    # but without using gpg, just cat and find
    local PUBRING="$(readlink -f "${GPGHOMEDIR}")/pubring.gpg"
    rm -f "$PUBRING"
    touch "$PUBRING"
    foreach_keyring_do 'catfile' "$PUBRING"
}

import_keys_from_keyring() {
    import_keyring_into_keyring "$1" "$2"
}

merge_keys_into_keyrings() {
    import_keyring_into_keyring "$2" "$1" '' --import-options 'merge-only'
}

merge_back_changes() {
    if [ -n "$FORCED_KEYRING" ]; then
	# if the keyring was forced merge is already done
	if [ "$FORCED_KEYRING" != "$TRUSTEDFILE" ]; then
	    mv -f "$FORCED_KEYRING" "${FORCED_KEYRING}~"
	    export_key_from_to "$TRUSTEDFILE" "$FORCED_KEYRING" --armor
	fi
	return
    fi
    if [ -s "${GPGHOMEDIR}/pubring.gpg" ]; then
	# merge all updated keys
	foreach_keyring_do 'merge_keys_into_keyrings' "${GPGHOMEDIR}/pubring.gpg"
    fi
    # look for keys which were added or removed
    get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.orig.gpg" > "${GPGHOMEDIR}/pubring.orig.keylst"
    get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.gpg" > "${GPGHOMEDIR}/pubring.keylst"
    comm -3 "${GPGHOMEDIR}/pubring.keylst" "${GPGHOMEDIR}/pubring.orig.keylst" > "${GPGHOMEDIR}/pubring.diff"
    # key isn't part of new keyring, so remove
    cut -f 2 "${GPGHOMEDIR}/pubring.diff" | while read key; do
	if [ -z "$key" ]; then continue; fi
	foreach_keyring_do 'remove_key_from_keyring' "$key"
    done
    # key is only part of new keyring, so we need to import it
    cut -f 1 "${GPGHOMEDIR}/pubring.diff" | while read key; do
	if [ -z "$key" ]; then continue; fi
	import_keyring_into_keyring '' "$TRUSTEDFILE" "$key"
    done
}

setup_merged_keyring() {
    if [ -n "$FORCED_KEYID" ]; then
	merge_all_trusted_keyrings_into_pubring
	FORCED_KEYRING="${GPGHOMEDIR}/forcedkeyid.gpg"
	TRUSTEDFILE="${FORCED_KEYRING}"
	echo "#!/bin/sh
exec sh '($(escape_shell "${GPG}")' --keyring '$(escape_shell "${TRUSTEDFILE}")' \"\$@\"" > "${GPGHOMEDIR}/gpg.1.sh"
	GPG="${GPGHOMEDIR}/gpg.1.sh"
	# ignore error as this "just" means we haven't found the forced keyid and the keyring will be empty
	import_keyring_into_keyring '' "$TRUSTEDFILE" "$FORCED_KEYID" || true
    elif [ -z "$FORCED_KEYRING" ]; then
	merge_all_trusted_keyrings_into_pubring
	if [ -r "${GPGHOMEDIR}/pubring.gpg" ]; then
	    cp -a "${GPGHOMEDIR}/pubring.gpg" "${GPGHOMEDIR}/pubring.orig.gpg"
	else
	   touch "${GPGHOMEDIR}/pubring.gpg" "${GPGHOMEDIR}/pubring.orig.gpg"
	fi
	echo "#!/bin/sh
exec sh '$(escape_shell "${GPG}")' --keyring '$(escape_shell "${GPGHOMEDIR}/pubring.gpg")' \"\$@\"" > "${GPGHOMEDIR}/gpg.1.sh"
	GPG="${GPGHOMEDIR}/gpg.1.sh"
    else
	TRUSTEDFILE="$(dearmor_filename "$FORCED_KEYRING")"
	create_new_keyring "$TRUSTEDFILE"
	echo "#!/bin/sh
exec sh '$(escape_shell "${GPG}")' --keyring '$(escape_shell "${TRUSTEDFILE}")' \"\$@\"" > "${GPGHOMEDIR}/gpg.1.sh"
	GPG="${GPGHOMEDIR}/gpg.1.sh"
    fi
}

create_new_keyring() {
    # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead.
    if ! [ -e "$1" ]; then
	if [ -w "$(dirname "$1")" ]; then
	    touch -- "$1"
	    chmod 0644 -- "$1"
	fi
    fi
}

aptkey_execute() { sh "$@"; }

usage() {
    echo "Usage: apt-key [--keyring file] [command] [arguments]"
    echo
    echo "Manage apt's list of trusted keys"
    echo
    echo "  apt-key add <file>          - add the key contained in <file> ('-' for stdin)"
    echo "  apt-key del <keyid>         - remove the key <keyid>"
    echo "  apt-key export <keyid>      - output the key <keyid>"
    echo "  apt-key exportall           - output all trusted keys"
    echo "  apt-key update              - update keys using the keyring package"
    echo "  apt-key net-update          - update keys using the network"
    echo "  apt-key list                - list keys"
    echo "  apt-key finger              - list fingerprints"
    echo "  apt-key adv                 - pass advanced options to gpg (download key)"
    echo
    echo "If no specific keyring file is given the command applies to all keyring files."
}

while [ -n "$1" ]; do
   case "$1" in
      --keyring)
	 shift
	 if [ -z "$FORCED_KEYRING" -o "$FORCED_KEYRING" = '/dev/null' ]; then
	     TRUSTEDFILE="$1"
	     FORCED_KEYRING="$1"
	 elif [ "$TRUSTEDFILE" = "$FORCED_KEYRING" ]; then
	     create_gpg_home
	     FORCED_KEYRING="${GPGHOMEDIR}/mergedkeyrings.gpg"
	     echo -n '' > "$FORCED_KEYRING"
	     chmod 0644 -- "$FORCED_KEYRING"
	     catfile "$TRUSTEDFILE" "$FORCED_KEYRING"
	     catfile "$1" "$FORCED_KEYRING"
	 else
	     catfile "$1" "$FORCED_KEYRING"
	 fi
	 ;;
      --keyid)
	 shift
	 if [ -n "$FORCED_KEYID" ]; then
	     apt_error 'Specifying --keyid multiple times is not supported'
	     exit 1
	 fi
	 FORCED_KEYID="$1"
	 ;;
      --secret-keyring)
	 shift
	 FORCED_SECRET_KEYRING="$1"
	 ;;
      --readonly)
	 merge_back_changes() { true; }
	 create_new_keyring() { if [ ! -r "$FORCED_KEYRING" ]; then TRUSTEDFILE='/dev/null'; FORCED_KEYRING="$TRUSTEDFILE"; fi; }
	 ;;
      --fakeroot)
	 requires_root() { true; }
	 ;;
      --quiet)
	 aptkey_echo() { true; }
	 ;;
      --debug1)
	 # some cmds like finger redirect stderr to /dev/null …
	aptkey_execute() { echo 'EXEC:' "$@"; sh "$@"; }
	;;
      --debug2)
	 # … other more complicated ones pipe gpg into gpg.
	aptkey_execute() { echo >&2 'EXEC:' "$@"; sh "$@"; }
	;;
      --homedir)
	 # force usage of a specific homedir instead of creating a temporary
	 shift
	 GPGHOMEDIR="$1"
	;;
      --*)
	 echo >&2 "Unknown option: $1"
	 usage
	 exit 1;;
      *)
	 break;;
   esac
   shift
done

if [ -z "$TRUSTEDFILE" ]; then
   TRUSTEDFILE="/etc/apt/trusted.gpg"
   eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
   eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
   if [ "$APT_KEY_NO_LEGACY_KEYRING" ]; then
        TRUSTEDFILE="/dev/null"
   fi
fi

command="$1"
if [ -z "$command" ]; then
    usage
    exit 1
fi
shift

prepare_gpg_home() {
    # crude detection if we are called from a maintainerscript where the
    # package depends on gnupg or not. We accept recommends here as
    # well as the script hopefully uses apt-key optionally then like e.g.
    # debian-archive-keyring for (upgrade) cleanup did
    if [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] && [ -z "$APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE" ]; then
	if ! dpkg-query --show --showformat '${Pre-Depends}${Depends}${Recommends}\n' "$DPKG_MAINTSCRIPT_PACKAGE" 2>/dev/null | grep -E -q 'gpg|gnupg'; then
	    cat >&2 <<EOF
Warning: The $DPKG_MAINTSCRIPT_NAME maintainerscript of the package $DPKG_MAINTSCRIPT_PACKAGE
Warning: seems to use apt-key (provided by apt) without depending on gpg, gnupg, or gnupg2.
Warning: This will BREAK in the future and should be fixed by the package maintainer(s).
Note: Check first if apt-key functionality is needed at all - it probably isn't!
EOF
	fi
    fi
    eval "$(apt-config shell GPG_EXE Apt::Key::gpgcommand)"
    if [ -n "$GPG_EXE" ] && command_available "$GPG_EXE"; then
	true
    elif command_available 'gpg'; then
	GPG_EXE="gpg"
    elif command_available 'gpg2'; then
	GPG_EXE="gpg2"
    elif command_available 'gpg1'; then
	GPG_EXE="gpg1"
    else
	apt_error 'gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation'
	exit 255
    fi

    create_gpg_home

    # now tell gpg that it shouldn't try to maintain this trustdb file
    echo "#!/bin/sh
exec '$(escape_shell "${GPG_EXE}")' --ignore-time-conflict --no-options --no-default-keyring \\
--homedir '$(escape_shell "${GPGHOMEDIR}")' --no-auto-check-trustdb --trust-model always \"\$@\"" > "${GPGHOMEDIR}/gpg.0.sh"
    GPG_SH="${GPGHOMEDIR}/gpg.0.sh"
    GPG="$GPG_SH"

    # create the trustdb with an (empty) dummy keyring
    # older gpgs required it, newer gpgs even warn that it isn't needed,
    # but require it nonetheless for some commands, so we just play safe
    # here for the foreseeable future and create a dummy one
    touch "${GPGHOMEDIR}/empty.gpg"
    if ! "$GPG_EXE" --ignore-time-conflict --no-options --no-default-keyring \
       --homedir "$GPGHOMEDIR" --quiet --check-trustdb --keyring "${GPGHOMEDIR}/empty.gpg" >"${GPGHOMEDIR}/gpgoutput.log" 2>&1; then
       cat >&2 "${GPGHOMEDIR}/gpgoutput.log"
       false
    fi

    # We don't usually need a secret keyring, of course, but
    # for advanced operations, we might really need a secret keyring after all
    if [ -n "$FORCED_SECRET_KEYRING" ] && [ -r "$FORCED_SECRET_KEYRING" ]; then
	if ! aptkey_execute "$GPG" -v --batch --import "$FORCED_SECRET_KEYRING" >"${GPGHOMEDIR}/gpgoutput.log" 2>&1; then
	    # already imported keys cause gpg1 to fail for some reason… ignore this error
	    if ! grep -q 'already in secret keyring' "${GPGHOMEDIR}/gpgoutput.log"; then
		cat >&2 "${GPGHOMEDIR}/gpgoutput.log"
		false
	    fi
	fi
    else
       # and then, there are older versions of gpg which panic and implode
       # if there isn't one available - and writeable for imports
       # and even if not output is littered with the creation of a secring,
       # so lets call import once to have it create what it wants in silence
       echo -n | aptkey_execute "$GPG" --batch --import >/dev/null 2>&1 || true
    fi
}

warn_on_script_usage() {
    if [ -n "$APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE" ]; then
	return
    fi
    # (Maintainer) scripts should not be using apt-key
    if [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ]; then
	echo >&2 "Warning: apt-key should not be used in scripts (called from $DPKG_MAINTSCRIPT_NAME maintainerscript of the package ${DPKG_MAINTSCRIPT_PACKAGE})"
    fi

    echo >&2 "Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8))."
}

warn_outside_maintscript() {
    # In del, we want to warn in interactive use, but not inside maintainer
    # scripts, so as to give people a chance to migrate keyrings.
    #
    # FIXME: We should always warn starting in 2022.
    if [ -z "$DPKG_MAINTSCRIPT_PACKAGE" ]; then
	echo >&2 "Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8))."
    fi
}

if [ "$command" != 'help' ] && [ "$command" != 'verify' ]; then
    prepare_gpg_home
fi

case "$command" in
    add)
	warn_on_script_usage
	requires_root
	setup_merged_keyring
	aptkey_execute "$GPG" --quiet --batch --import "$@"
	merge_back_changes
	aptkey_echo "OK"
        ;;
    del|rm|remove)
	# no script warning here as removing 'add' usage needs 'del' for cleanup
	warn_outside_maintscript
	requires_root
	foreach_keyring_do 'remove_key_from_keyring' "$@"
	aptkey_echo "OK"
        ;;
    update)
	warn_on_script_usage
	requires_root
	setup_merged_keyring
	update
	merge_back_changes
	;;
    net-update)
	warn_on_script_usage
	requires_root
	setup_merged_keyring
	net_update
	merge_back_changes
	;;
    list|finger*)
	warn_on_script_usage
	foreach_keyring_do 'list_keys_in_keyring' --fingerprint "$@"
	;;
    export|exportall)
	warn_on_script_usage
	merge_all_trusted_keyrings_into_pubring
	aptkey_execute "$GPG_SH" --keyring "${GPGHOMEDIR}/pubring.gpg" --armor --export "$@"
	;;
    adv*)
	warn_on_script_usage
	setup_merged_keyring
	aptkey_echo "Executing: $GPG" "$@"
	aptkey_execute "$GPG" "$@"
	merge_back_changes
	;;
    verify)
	GPGV=''
	ASSERT_PUBKEY_ALGO=''
	eval $(apt-config shell GPGV Apt::Key::gpgvcommand ASSERT_PUBKEY_ALGO Apt::Key::assert-pubkey-algo)
	if [ -n "$GPGV" ] && command_available "$GPGV"; then true;
	elif command_available 'gpgv'; then GPGV='gpgv';
	elif command_available 'gpgv2'; then GPGV='gpgv2';
	elif command_available 'gpgv1'; then GPGV='gpgv1';
	else
	   apt_error 'gpgv, gpgv2 or gpgv1 required for verification, but neither seems installed'
	   exit 29
	fi
	GPGV_ARGS=""
	if [ "$ASSERT_PUBKEY_ALGO" ]; then
		test="$(LC_ALL=C.UTF-8 "$GPGV" --assert-pubkey-algo 2>&1 || :)"
		case "$test" in
			*"missing argument"*)
				GPGV_ARGS="--assert-pubkey-algo=$ASSERT_PUBKEY_ALGO"
				;;
			*[Ii]"nvalid option"*"assert-pubkey-algo"*)
				;;
			*)
				apt_warn "Unknown response from gpgv to --assert-pubkey-algo check: $test"
				;;
		esac
	fi
	# for a forced keyid we need gpg --export, so full wrapping required
	if [ -n "$FORCED_KEYID" ]; then
	    prepare_gpg_home
	else
	    create_gpg_home
	fi
	setup_merged_keyring
	if [ -n "$FORCED_KEYRING" ]; then
	    "$GPGV" $GPGV_ARGS --homedir "${GPGHOMEDIR}" --keyring "$(dearmor_filename "${FORCED_KEYRING}")" --ignore-time-conflict "$@"
	else
	    "$GPGV" $GPGV_ARGS --homedir "${GPGHOMEDIR}" --keyring "${GPGHOMEDIR}/pubring.gpg" --ignore-time-conflict "$@"
	fi
	;;
    help)
        usage
        ;;
    *)
        usage
        exit 1
        ;;
esac