From 4f768f0cb0a463e1557e29d825a16a67d9bf83de Mon Sep 17 00:00:00 2001 From: Jacob Bachmeyer Date: Tue, 4 Apr 2023 22:31:14 -0500 Subject: [PATCH] Add initial preliminary manual --- doc/gatekeeper.texi | 1017 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1017 insertions(+) create mode 100644 doc/gatekeeper.texi diff --git a/doc/gatekeeper.texi b/doc/gatekeeper.texi new file mode 100644 index 0000000..2003cfc --- /dev/null +++ b/doc/gatekeeper.texi @@ -0,0 +1,1017 @@ +\input texinfo @c -*- Texinfo -*- +@c %**start of header +@setfilename gatekeeper.info +@settitle GNU Secure Software Gatekeeper +@c %**end of header +@copying +This is the reference manual for the GNU Secure Software Gatekeeper, +which manages the distribution of software releases authenticated +using strong cryptographic signatures. + +Copyright @copyright{} 2023 Jacob Bachmeyer. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled +``GNU Free Documentation License''. +@end quotation +@end copying + +@dircategory Software Distribution +@direntry +* gatekeeper: (gatekeeper)Top. The GNU Secure Software Gatekeeper. +@end direntry + +@titlepage +@title GNU Secure Software Gatekeeper +@author Jacob Bachmeyer + +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@ifnottex +@node Top, Introduction, (dir), (dir) +@top GNU Secure Software Gatekeeper + +@insertcopying +@end ifnottex + +@menu +* Introduction:: What this package does. +* Configuration:: How to set up the system. +* Operation:: Using the gatekeeper. +* Copying Conditions:: Your rights with this manual. +* Index:: Index. + +@detailmenu + --- The Detailed Node Listing --- + +Introduction + +* What is the Gatekeeper?:: The upload handler. +* What is the Keymaster?:: The combined administrative tool. +* Security Considerations:: The reasons these tools exist. +* Security Analysis:: The limits of trust in this system. + +Configuration + +* Global Configuration:: Configuring the system as a whole. +* Package Configuration:: Per-directory upload access controls. +* Invoking keymaster.pl:: Using the administrative tool. + +Global Configuration + +* Global Configuration File:: The global configuration file. +* Simple Example:: An example configuration for the simple mode. +* Zone Example:: An example configuration for multiple zones. +* GNU Example:: An example for the GNU Project FTP service. + +Package Configuration + +* Directory Access Control:: Per-directory configuration. +* Global Maintainer List:: Email notifications by package. + +Operation + +* Invoking gatekeeper.pl:: Running the gatekeeper itself. +* Invoking make-ftpindex.sh:: Rebuilding the public file indexes. +* Upload Packets:: @c TODO + +Copying Conditions + +* GNU Free Documentation License:: The full text of the GFDL. + +@end detailmenu +@end menu + +@node Introduction, Configuration, Top, Top +@chapter Introduction + +@menu +* What is the Gatekeeper?:: The upload handler. +* What is the Keymaster?:: The combined administrative tool. +* Security Considerations:: The reasons these tools exist. +* Security Analysis:: The limits of trust in this system. +@end menu + +@node What is the Gatekeeper?, What is the Keymaster?, Introduction, Introduction +@section What is the Gatekeeper? + +The GNU Secure Software Gatekeeper, or simply ``gatekeeper'' for short +(after the name of the main program in the package) is a tool for +operating a software distribution service. It is descended from +scripts that were originally written in 2003 for operating the GNU +Project FTP server at @t{ftp.gnu.org} after an intrusion made +continuing to provide maintainers shell access to update the FTP tree +(the traditional solution to the problem) untenable. + +The gatekeeper validates uploaded files and other directives by +verifying PGP signatures, managing access controls using curated +keyrings on the server and requiring all uploads to the server to be +signed using OpenPGP. The gatekeeper avoids holding any kind of +secrets on the server. + +The gatekeeper performs some additional checks to prevent uploads from +being accepted that contain a few easily detected vulnerabilities +introduced by certain (now long obsolete) versions of GNU Automake. + +For ``security-by-transparency'', the gatekeeper sends email +notifications to holders of PGP keys used to sign uploads, designated +maintainers of packages and supervisors of subdirectories, and a +mailing list for a public archive of all successfully processed +uploads. An additional internal mailing list is supported for +notifications of uploads that entirely fail authentication; this is +separate from the public archive to prevent graffiti attacks on the +archive by outside parties. + +The gatekeeper itself is designed to be run from cron at regular +intervals to process uploaded files. + +@node What is the Keymaster?, Security Considerations, What is the Gatekeeper?, Introduction +@section What is the Keymaster? + +The keymaster is an administrative tool that provides an easy +interface for manipulating the underlying administrative configuration +database and maintaining the consistency of its associated indexes. +The gatekeeper uses the indexes to efficiently route notifications for +some types of rejected uploads. + +@node Security Considerations, Security Analysis, What is the Keymaster?, Introduction +@section Security Considerations + +This system ultimately traces its origins to a security incident, so +security is a critical issue throughout the design. The main +gatekeeper program is written in Perl, a (mostly)@footnote{The Perl +manuals document the @samp{p} and @samp{P} formats to the @code{pack} +and @code{unpack} primitives and warn that unpacking a pointer is an +extremely unsafe operation ``likely to have disastrous consequences''. +The gatekeeper does not @code{pack} or @code{unpack} pointers.} +memory-safe language with a long history in system administration +tasks that has led to a unique ``taint mode''@footnote{The more +cynical reader may note here that there have been some infamously +insecure CGI scripts written in Perl. Perl's taint mode is not a +substitute for careful thought, and CGI scripts have often not been +run with taint mode enabled, even though @cite{perlsec} recommends its +use.} where the interpreter enforces at least some level of care in +handling data obtained from outside the program. + +An extensive testsuite verifies handling of a wide variety of known +valid and invalid inputs and is used during development to ensure that +behavior is never unintentionally changed. + +The system relies on the GNU Privacy Guard implementation of OpenPGP +and the gatekeeper uses the simplified signature verification +available with the @command{gpgv} tool and the @samp{--status-fd} +interface designed for automated use. + +@node Security Analysis, , Security Considerations, Introduction +@section Security Analysis + +The fundamental purpose of the gatekeeper is to pull authorized data +across a security boundary while rejecting unauthorized data, possibly +despite interference from malicious third parties. The security model +considers two possible failures: an unauthorized upload modifying the +published file tree, and the inability to complete processing a +legitimate upload. + +@subsection Unauthorized Uploads + +The compromise of a legitimate maintainer's PGP key allows an attacker +to impersonate that maintainer and produce uploads that will be +accepted. Preventing theft of maintainer private keys is beyond the +scope of this package, as those keys should never be anywhere near +this system. + +The major trusted link in the chain is GPG, specifically the +@command{gpgv} signature verification tool. GPG is used to determine +the validity of signatures, and while extensive validation is applied +to directives prior to checking signatures, GPG is directly exposed to +untrusted input in the form of uploaded files and their detached +signatures. GPG's verdict on a signature is trusted---if GPG can +somehow be subverted to declare a fake signature valid, the system +will accept an attacker's input as legitimate. See the gatekeeper +code, particularly the @code{sub verify_clearsigned_message} for the +precautions taken against the possibility of exploits against GPG. + +The directive format itself is designed to be easily processed +securely and is a simple key-value text format that must be wrapped in +a PGP clearsigned message for authentication. The gatekeeper extracts +the first clearsigned message from a directive file and uses only that +information. All other contents of a directive file, including any +text before or after the first clearsigned PGP message, are ignored. + +The directive is parsed prior to verifying its signature; this is an +unavoidable consequence of our per-directory permissions model, where +the target directory must be extracted from the directive before the +set of keys authorized for signing that directive is known. Risks +here are mitigated by strict use of narrow pattern matches for values +and exact string matches for keys. + +To prevent possible attacks by confusing GPG with multiple signatures +or messages in a directive file, the extracted message and its +signature are presented to @command{gpgv} over a pipe. The text +presented for signature verification is the exact text that was parsed +and its claimed signature. GPG is expected to be robust in the face +of untrusted and malicious input, since no validation of the PGP +packets is performed prior to submitting the signature and message for +verification. + +@subsection Denial of Service + +There are far more ways to disrupt the gatekeeper's operation than to +subvert it. This discussion assumes the historical use of an FTP +``inbox'' directory with overwrites and deletions prevented by the +@command{ftpd} configuration. The contents of the inbox are not +visible to remote users, but no authentication is required for +uploads, which are performed using anonymous FTP. + +The gatekeeper itself is not directly exposed to the network, since an +external @command{ftpd} is handling the uploads, so network attacks +are both out of scope for this discussion and most likely to occur in +practice. Flood mitigation is likely to be the most important defense. + +This discussion therefore focuses on application-level denial of +service attacks and their mitigation solutions within the gatekeeper. + +Uploaded files are packaged in triplets: a signed directive, an +uploaded file, and a PGP detached signature for the uploaded file. +The files in a triplet are linked by sharing a common file name +prefix. An attacker who can predict the name of an uploaded file can +consistently ``stuff the inbox'' with fake files to prevent a +legitimate upload from arriving. There is internal support for +renaming files while installing them into the tree, however making +this available for use will require a new protocol version. + +This attack is only possible because the common prefix for an upload +triplet is the name of the uploaded file. For the GNU Project, that +is almost always the name of a release, such as +@samp{gatekeeper-1.0.tar.gz}. Appending a unique tag to the version +number in the file name would be an immediate solution, and the file +name of a directive creating a symlink from the expected name to the +actual name is arbitrary. At the GNU Project, the server +administrators would be expected to later manually replace the symlink +with the actual file, thus ultimately foiling the attack. + +Past versions had another weakness: the upload handler script would +immediately exit upon finding anything wrong, from a directive syntax +error to an invalid signature, instead of discarding a packet and +moving on to the next pending upload. This allowed a simpler ``stuff +the queue'' attack, where any bogus items could prevent legitimate +uploads from being processed. The gatekeeper now efficiently discards +invalid packets and continues processing. + +Another possible attack is to attempt to disrupt a packet, by causing +one of its files to be mistaken for part of another packet. The +gatekeeper now recognizes such overlapping packets and attempts to +process all of them, with the expectation that only one of them will +actually pass authentication. + +@subsection Detecting Attacks + +The gatekeeper sends out email notifications of all processed packets +if so configured, and configuring these notifications is strongly +recommended. The use of a public archive for all successfully +processed uploads, as is the practice at GNU, is strongly recommended, +for reasons of both user convenience and site security. + +The public notice of an upload is the best way to catch the use of a +quietly stolen maintainer key, although the gatekeeper will also +notify the holder of the key at all email addresses registered on the +PGP public key certificate and the maintainers of the package as +registered on the server. A more aggressive attacker could seek to +impede the actions of the legitimate maintainer, such as by damaging +the legitimate maintainer's computing environment in some way. The +publication of all processed uploads provides a possibility for +someone else to notice something amiss. + +The detached OpenPGP signature required for each file uploaded is +itself published with that file for users to further verify, providing +an end-to-end validation that prevents simple attacks on the server or +its mirrors from planting bogus files for distribution. This +end-to-end validation is very important at GNU, since mirror operators +are not necessarily trusted, even though we hope they are trustworthy. + +@node Configuration, Operation, Introduction, Top +@chapter Configuration + +The GNU Secure Software Gatekeeper is configured at two major levels: +first, a global configuration file provides the details of the +filesystem layout and site parameters, and second, each published file +tree managed by the gatekeeper may have its own set of per-directory +upload permissions. + +@menu +* Global Configuration:: Configuring the system as a whole. +* Package Configuration:: Per-directory upload access controls. +* Invoking keymaster.pl:: Using the administrative tool. +@end menu + +@node Global Configuration, Package Configuration, Configuration, Configuration +@section Global Configuration + +@menu +* Global Configuration File:: The global configuration file. +* Simple Example:: An example configuration for the simple mode. +* Zone Example:: An example configuration for multiple zones. +* GNU Example:: An example for the GNU Project FTP service. +@end menu + +@node Global Configuration File, Simple Example, Global Configuration, Global Configuration +@subsection Global Configuration File + +The global configuration file is sought, by default, as +@file{gatekeeper.conf} in the same directory as the main +@file{gatekeeper.pl} program file. + +The configuration file syntax is very simple: @code{@var{variable} = +@var{value}} for parameters and @code{[@var{name}]} to introduce a +section. A line beginning with @code{#} is a comment and is ignored, +as are blank lines. + +Each collection of files managed by the gatekeeper is a @dfn{zone} in +the configuration. Each zone must have its own inbox +(@code{inboxdir}), scratch (@code{scratchdir}), staging +(@code{stagedir}), and public (@code{publicdir}) directories, although +the configuration (@code{pkgconfdir}), state (@code{pkgstatedir}), and +archive (@code{archivedir}) directories may be shared between zones or +any subset of zones. Note that sharing a state directory between +zones will cause a file uploaded to one zone to be considered part of +the past of all zones sharing that directory. Sharing a configuration +directory allows zones to share the same set of access controls. + +Each zone configuration is introduced with a @code{[zone.@var{name}]} +section heading. All per-zone variables must be declared for each +zone and the @option{--zone} option on the command line must be given +to specify which zone is to be manipulated (by the keymaster) or +processed (by the gatekeeper). + +A simple mode is also available, where only a single nameless zone is +used. The simple mode is selected if the configuration does not +contain a @code{[zone.@var{name}]} section header at all. In the +simple mode, the per-zone variables are simply entered at top-level, +before any section header, and the @option{--zone} option must not be +given on the command-line. + +The per-zone options are: + +@vtable @code +@item tag +Descriptive tag used in email subject lines for notifications. + +If not set, defaults to the zone name or @samp{upload} if the simple +mode is used. + +@item logtag +Descriptive tag used in messages sent to syslog when processing this +zone. + +If not set, defaults to the zone name with the first letter +capitalized, or @samp{Upload} if the simple mode is used. + +@item pkgconfdir +The base directory of the package configuration tree. + +The contents of this tree are entirely managed by the server +administrators; the gatekeeper considers it to be read-only. + +If not set, the gatekeeper will not start and most keymaster +commands will fail. + +@item pkgstatedir +The base directory of the package state tree. + +The contents of this tree are managed by the gatekeeper to track its +own state. As an example, the last-update timestamps are stored in a +@file{serials} file here and used to reject replay attacks. + +If not set, the gatekeeper will not start. + +@item inboxdir +The directory where new upload packets appear. + +If not set, the gatekeeper will not start. + +@item scratchdir +A directory within the reach of @code{rename}(2) from @code{inboxdir}. + +Uploads are moved to this directory prior to any other processing, to +prevent attacks that involve replacing an uploaded file. This +directory should not be remotely accessible. + +If not set, the gatekeeper will not start. + +@item stagedir +A directory within the reach of @code{rename}(2) to @code{publicdir}. + +After passing security checks, uploads are transferred from the +@code{scratchdir} to this directory using the system @command{mv} +command, which allows for the possibility of a non-atomic transfer +between distinct filesystems, to be performed outside of public view +to ensure that a mirror will never see a partial file. + +If not set, the gatekeeper will not start. + +@item publicdir +The base directory of the published file tree managed by the gatekeeper. + +If not set, the gatekeeper will not start. + +@item archivedir +A directory within the reach of @code{rename}(2) from @code{publicdir}. + +The gatekeeper never actually removes files that have been placed into +the published file tree, instead transferring files that should be +removed from public access (according to a directive signed by an +authorized key) to this archival tree. + +If not set, the gatekeeper will not start. + +@item keypubdir +The directory where published keyrings are to be stored. + +All current and old PGP keys are collected into per-project keyrings +and a global keyring that can be provided to users for validating +signatures on files in the published collection. This is performed by +the administrator using the keymaster tool, and the gatekeeper ignores +this directory. + +If not set, the @command{collect-keys} keymaster command will fail. + +@item ftprootdir +The root directory of the public FTP file tree, which may be different +from the published file tree managed by the gatekeeper. + +This is not directly used by the gatekeeper, but is passed to the FTP +index rebuilding tool after upload packets are processed. + +If not set, defaults to the parent directory of @code{publicdir}. +@end vtable + +The email options always appear in an @code{[email]} section. All of +the email options are optional in that the gatekeeper will run if they +are not set, but using the email notification features is strongly +recommended. + +The email options are: + +@vtable @code +@item sourcebox +The email address the gatekeeper will use as its own ``From'' address. +If not set, sending email is silently disabled. + +@item returnbox +The email address that should receive replies to mail sent by the +gatekeeper. If not set, defaults to the @code{sourcebox} address. +For some messages, this address entirely replaces the @code{sourcebox} +address, due to past experience at the GNU Project. + +@item archivebox +The email address of a public archive mailing list. All processing +reports are sent to this address if the directive is signed with a +valid signature from any known key. If not set, no public archive +is used. + +@item internalbox +The email address of an internal archive. All processing reports not +sent to the @code{archivebox} address are sent to this address, along +with raw copies of all directives processed. If not set, these +features are disabled. In particular, directives lacking a signature +from any known key will be silently discarded if this is not set. + +@item blacklist +The absolute name of a file containing email addresses, one per line, +that are not to receive mail from the gatekeeper. This feature exists +to accommodate PGP keys that carry no-longer-valid email addresses but +are themselves still valid and authorized to sign upload packets. + +If not set, the @command{blacklist-email} keymaster command and the +@option{--blacklist} option to the @command{remove-email} keymaster +command will fail, but the gatekeeper will consider the list to be +empty and otherwise operate normally. + +@item maintainerlist +The absolute name of a file listing additional email addresses for +each package in the system. This file is traditionally named +@file{maintainers.bypkg} at the GNU Project. @xref{Global Maintainer +List}, for details on its format. + +If not set, this feature is silently disabled. +@end vtable + +@need 3000 +@node Simple Example, Zone Example, Global Configuration File, Global Configuration +@subsection Simple Example + +@cartouche +@example +pkgconfdir = /srv/gatekeeper/etc/packages +pkgstatedir = /srv/gatekeeper/etc/package_state + +inboxdir = /srv/vsftpd/incoming +scratchdir = /srv/vsftpd/gatekeeper-scratchpad + +stagedir = /net/ftp/stage +publicdir = /net/ftp/root/pub +archivedir = /net/ftp/archive + +# minimal configuration above + +keypubdir = /net/ftp/root/pub/pgprings + +[email] +sourcebox = ftp-upload@@example.org +@end example +@end cartouche + +This simple example is almost minimal and contains a minimal example, +indicated by the comment. This also suggests a recommended +configuration where the gatekeeper and actual FTP server are on two +separate machines, with @file{/net/ftp} assumed to be the mountpoint +for a network filesystem shared with the actual FTP server (or perhaps +exported read-write from the FTP server). The @file{/net/ftp/root} +directory is presumed to be root of the file tree exported to the +world via FTP, while @file{/srv/vsftpd/incoming} is the directory +where uploads arrive. Obviously, the security of the network +filesystem export is important, so the two machines should be on the +same physical, wired, LAN segment. + +Beyond the minimal configuration, the @code{keypubdir} option enables +the use of the @command{collect-keys} keymaster command to directly +update a set of keyrings published on the FTP server, and the +@code{sourcebox} option in the @code{[email]} section enables the +gatekeeper to send email notifications. + +This example also uses the simple mode, with only a single nameless +zone, so the @option{--zone} option must not be used with this +configuration. + +@node Zone Example, GNU Example, Simple Example, Global Configuration +@subsection Zone Example + +This is a more complex example using the zone feature. Two of the +three zones use the same configuration tree and the @code{[email]} +section is presented first, since the use of zone section headers +eliminates the need to place any settings before the first header. + +@cartouche +@example +[email] +sourcebox = ftp-upload@@example.org +returnbox = ftp-upload-admin@@example.org +blacklist = /srv/gatekeeper/etc/email_blacklist +@end example +@end cartouche + +In this example, two more features of the email notification subsystem +are shown. The @code{returnbox} option selects a return address +different from the tool's ``From'' address, which in this case, is +implied to go to a queue watched by the server administrators. Also, +the @code{blacklist} option allows to prevent mail from being sent to +known no-longer-valid addresses. + +@cartouche +@example +[zone.foo] +pkgconfdir = /srv/gatekeeper/etc/packages +pkgstatedir = /srv/gatekeeper/etc/foo-package-state + +inboxdir = /srv/vsftpd/incoming/foo +scratchdir = /srv/vsftpd/gatekeeper-scratchpad/foo + +stagedir = /net/ftp/foo-stage +publicdir = /net/ftp/root/pub +archivedir = /net/ftp/foo-archive + +keypubdir = /net/ftp/root/pgprings +@end example +@end cartouche + +Next, we configure the @samp{foo} zone, which is straightforwardly +related to the earlier simple example. The @samp{foo} zone is the +``main'' zone for a central public FTP server, configured similarly to +the simple example. + +A notable difference is that files are sorted into zones by uploaders, +so @file{/srv/vsftpd/incoming} now has a subdirectory for each zone, +as does the scratchpad. Note that each zone @emph{must} have its own +scratchpad if there is any possibility of processing zones concurrently. + +@cartouche +@example +[zone.bar] +pkgconfdir = /srv/gatekeeper/etc/packages +pkgstatedir = /srv/gatekeeper/etc/bar-package-state + +inboxdir = /srv/vsftpd/incoming/bar +scratchdir = /srv/vsftpd/gatekeeper-scratchpad/bar + +stagedir = /net/ftp-bar/stage +publicdir = /net/ftp-bar/root/pub +archivedir = /net/ftp-bar/archive +@end example +@end cartouche + +Here, we configure the @samp{bar} zone, which shares permissions with +the @samp{foo} zone, but is published on a separate, parallel FTP server. + +There is no @code{keypubdir} option set for the @samp{bar} zone +because they would be the same keyrings as published for the +@samp{foo} zone, although they could differ if the +@command{collect-keys} keymaster command has been run for one zone but +not the other. While using a @code{keypubdir} option for the +@samp{bar} zone would be possible, it is not recommended because it +would increase administrative burden for no real benefit in this +scenario. + +@cartouche +@example +[zone.baz] +pkgconfdir = /srv/gatekeeper/etc/baz-packages +pkgstatedir = /srv/gatekeeper/etc/baz-package-state + +inboxdir = /srv/vsftpd/incoming/baz +scratchdir = /srv/vsftpd/gatekeeper-scratchpad/baz + +stagedir = /net/ftp/baz-stage +publicdir = /net/ftp/root/baz +archivedir = /net/ftp/baz-archive + +keypubdir = /net/ftp/root/baz-pgprings +@end example +@end cartouche + +Lastly, we configure the @samp{baz} zone, which has its own +permissions, but is a separate tree also published on the main FTP +server. + +The @samp{baz} zone also has a separate @code{keypubdir}, since +uploads to it are authorized using different keys than the @samp{foo} +and @samp{bar} zones. + +@node GNU Example, , Zone Example, Global Configuration +@subsection GNU Example + +[TODO] + +@node Package Configuration, Invoking keymaster.pl, Global Configuration, Configuration +@section Package Configuration + +Each zone managed by the gatekeeper can have its own package +configuration, or package configurations can be shared between zones. +The package configuration establishes what packages are distributed at +the site and which keys may be used to sign uploads, on a per-package +and per-subtree basis. The associations between zones and package +configurations are established in the global configuration file. + +The gatekeeper treats package configuration trees as read-only. + +@menu +* Directory Access Control:: Per-directory configuration. +* Global Maintainer List:: Email notifications by package. +@end menu + +@node Directory Access Control, Global Maintainer List, Package Configuration, Package Configuration +@subsection Directory Access Control + +A first-level subdirectory within the package configuration tree +corresponds to a @dfn{package}. Its associated directory within the +published file tree will be automatically created when the first file +for a package is uploaded. + +The package configuration tree mirrors the published file tree in +directory structure, except that a directory that would be empty in +the package configuration tree need not actually exist. Each +directory in the package configuration tree may contain two keyrings, +@file{pubring.gpg} and @file{oldring.gpg}, and a list of email +addresses, stored one per line in a file named @file{email}, to be +notified of all uploads to that directory and its subtree. Future +expansions may define additional per-directory files and further +indexes; currently, an index of all known public keys is also +maintained at the root of the package configuration tree by the +keymaster for use by the gatekeeper. + +The gatekeeper uses a simple access control model, where all keys +authorized for a directory are also authorized for all subdirectories +of that directory, including the creation of new subdirectories. + +The @file{pubring.gpg} keyring contains active keys permitted to +upload to the directory and its subtree. The @file{oldring.gpg} is an +archival keyring, storing older keys that have been used in the past +but are no longer permitted to sign new uploads or directives. Both +keyrings are combined to produce the published keyrings for users to +use to validate signatures, while the gatekeeper examines only the +active @file{pubring.gpg} keyring. + +The @file{email} file is a simple list of email addresses, one per +line, which are to be notified of any directive processed for the +directory and its subtree. + +The minimal requirements for an active package are an @file{email} +file (which can be empty) in the package's base directory, and at +least one @file{pubring.gpg} file somewhere in the subtree for the +package. If these requirements are not met, uploads for the package +will be rejected. Ordinarily, there will be an active keyring in the +package's base directory, with keys on that keyring having permission +for all directories in the package. + +Note that the @file{email} file in the base directory for a package's +configuration is required even if email notifications are not +configured in the gatekeeper. In this case, its contents will be +effectively ignored. + +@node Global Maintainer List, , Directory Access Control, Package Configuration +@subsection Global Maintainer List + +The gatekeeper can be configured to read additional email addresses +for notification from a central maintainer list, stored in a flat text +file with very long lines. At the GNU Project, this file is +traditionally named @file{maintainers.bypkg}. + +Lines beginning with @samp{#} are comments and are ignored. + +Package lines begin with the name of the package, the exact sequence +@samp{ - } (that is, a space, followed by a hyphen, followed by +another space), and a list of maintainers for the package. The +recommended format for this list is @samp{@var{Full Name} +@code{<}@var{email@@address}@code{>}} with commas and whitespace +separating entries, however, the gatekeeper only searches for email +addresses inside @code{<>} and collects whatever strings match the +expected pattern. + +@node Invoking keymaster.pl, , Package Configuration, Configuration +@section Invoking keymaster.pl + +The keymaster is a unified administration tool for the gatekeeper +keyrings and other package configuration tasks. + +@quotation +@t{keymaster.pl --version} +@end quotation + +The keymaster will report its version and the standard GNU boilerplate +if asked. + +@quotation +@t{keymaster.pl --help [@var{command}]} +@end quotation + +The keymaster has extensive embedded programmer's documentation, also +available in an online help facility. If a @var{command} is given, +output the specific help for that command, otherwise output a general +overview. + +@quotation +@t{keymaster.pl [-c @var{file}] [-z @var{zone}] @var{command} +[@var{options}]} +@end quotation + +@quotation +@t{keymaster.pl [--conf @var{file}] [--zone @var{zone}] @var{command} +[@var{options}]} +@end quotation + +The keymaster accepts some global options: + +@table @code +@item --conf +Select an alternate configuration file. For future compatibility, +@var{file} should be an absolute file name or explicitly begin with +the current directory. + +@item --zone +Select the zone to manipulate. @xref{Global Configuration File}, for an +explanation of zones. + +@item --with-gpg +Specify an alternate location for GPG. + +The default is @file{/usr/bin/gpg}. +@end table + +@subsection Email Notification Management + +These commands manage the @file{email} files in the package +configuration tree and the global email blacklist. + +@quotation +@t{keymaster.pl notify-email @var{directory} @var{address}...} +@end quotation + +Add the provided email addresses to the @file{email} file for +@var{directory}. + +@quotation +@t{keymaster.pl blacklist-email @var{address}...} +@end quotation + +Add the provided email addresses to the global email blacklist. + +@quotation +@t{keymaster.pl remove-email @var{directory} @var{address}...} +@end quotation + +Remove the provided email addresses from the @file{email} file for +@var{directory}. + +@quotation +@t{keymaster.pl remove-email --blacklist @var{address}...} +@end quotation + +Remove the provided email addresses from the global email blacklist. + +@subsection Keyring Management + +These commands both manage the @file{pubring.gpg} and +@file{oldring.gpg} files in the package configuration tree and also +maintain the key index used by the gatekeeper. + +@quotation +@t{keymaster.pl register-key @var{directory} @var{key_file}...} +@end quotation + +Add keys from the provided key files to the @file{pubring.gpg} keyring +for @var{directory}. + +@quotation +@t{keymaster.pl update-key @var{key_file}} +@end quotation + +Locate all @file{pubring.gpg} keyrings that currently contain a copy +of the key in the provided file and re-import the key from the +provided file to each of those keyrings. + +To prevent accidentally expanding permissions, the key file must +contain exactly one key, although it may have any number of subkeys. + +@quotation +@t{keymaster.pl withdraw-key @var{directory} @var{fingerprint}} +@end quotation + +Remove the key with the given @var{fingerprint} from the +@file{pubring.gpg} keyring in @var{directory}. A copy will be +transferred to @file{oldring.gpg} to ensure that users can still +validate existing signatures. + +This effectively revokes access previously granted to the indicated +key. + +@quotation +@t{keymaster.pl find-keys @var{fragment}...} +@end quotation + +Search the key index for keys matching the provided fingerprint +fragment, with may be a prefix, suffix, or exact match for a key +fingerprint. + +@quotation +@t{keymaster.pl cleanup-keys} +@end quotation + +Search all @file{pubring.gpg} keyrings and transfer all expired and/or +revoked keys found to the corresponding @file{oldring.gpg} keyrings. + +@quotation +@t{keymaster.pl collect-keys} +@end quotation + +Collect all known keys (from both @file{pubring.gpg} and +@file{oldring.gpg} keyrings) into per-package keyrings and all +per-package keyrings into a master published keyring. + +Note that the keymaster currently does @emph{not} invoke the +@command{make-ftpindex.sh} tool, so that will need to be run +separately if the published keyring directory is in the public FTP +tree. + +@quotation +@t{keymaster.pl rebuild-key-index [--progress]} +@end quotation + +Generate a new key index. This command is particularly useful after +performing some operation directly on the keyrings to realign the key +index with the keyrings. + +@node Operation, Copying Conditions, Configuration, Top +@chapter Operation + +@menu +* Invoking gatekeeper.pl:: Running the gatekeeper itself. +* Invoking make-ftpindex.sh:: Rebuilding the public file indexes. +* Upload Packets:: @c TODO +@end menu + +@node Invoking gatekeeper.pl, Invoking make-ftpindex.sh, Operation, Operation +@section Invoking gatekeeper.pl + +The gatekeeper is intended to be periodically run by cron or a similar +facility but can also be run manually. + +@quotation +@t{gatekeeper.pl --version} +@end quotation + +The gatekeeper will report its version and the standard GNU +boilerplate if asked. + +@quotation +@t{gatekeeper.pl --help} +@end quotation + +The gatekeeper will emit a usage summary if asked. There is extensive +programmer's documentation embedded in the source. + +@quotation +@t{gatekeeper.pl [@i{options}]} +@end quotation + +If not given @option{--help} or @option{--version}, the gatekeeper +will run normally. A few options are available: + +@table @code +@item --conf +Select an alternate configuration file. For future compatibility, +@var{file} should be an absolute file name or explicitly begin with +the current directory. + +@item --zone +Select the zone to process. @xref{Global Configuration File}, for an +explanation of zones. + +@item --with-gpgv +Specify alternate location for GPG signature verification tool. + +The default is @file{/usr/bin/gpgv}. + +@item --with-lsof +Specify alternate location for @command{lsof}. + +The default is +@file{/usr/bin/lsof}. +@end table + +@node Invoking make-ftpindex.sh, Upload Packets, Invoking gatekeeper.pl, Operation +@section Invoking make-ftpindex.sh + +The @command{make-ftpindex.sh} shell script packages the commands used +to rebuild the conventional top-level indexes for an FTP file tree. +This tool is automatically invoked by the gatekeeper at the end of any +run that actually updates the file tree, but can also be run manually. + +@quotation +@t{make-ftpindex.sh @var{ftprootdir} [@var{stagedir}]} +@end quotation + +A few options are available: + +@table @code +@item -n +@itemx --dry-run +The files will be left in the staging directory, instead of being +moved to the published tree. + +@item --help +Emit a usage message and exit. + +@item --version +Report the version of @command{make-ftpindex.sh} and exit. +@end table + +@node Upload Packets, , Invoking make-ftpindex.sh, Operation +@section Upload Packets + +[TODO] + +@node Copying Conditions, Index, Operation, Top +@appendix Copying Conditions + +@menu +* GNU Free Documentation License:: The full text of the GFDL. +@end menu + +@node GNU Free Documentation License, , Copying Conditions, Copying Conditions +@appendixsection GNU Free Documentation License + +@include fdl-1.3.texi + +@node Index, , Copying Conditions, Top +@unnumbered Index + +@printindex vr + +@bye + +@c LocalWords: texinfo fdl texi PGP keyrings OpenPGP subdirectories automake +@c LocalWords: keymaster GFDL cron CGI testsuite gpgv clearsigned fd gpg ftpd +@c LocalWords: perlsec GPG's unlistable inbox symlink gz conf vr pkgconfdir +@c LocalWords: pkgstatedir inboxdir scratchdir publicdir archivedir stagedir +@c LocalWords: keypubdir sourcebox returnbox archivebox internalbox bypkg mv +@c LocalWords: maintainerlist timestamp filesystems logtag syslog subtree usr +@c LocalWords: pubring oldring subdirectory subkeys lsof ftpindex ftprootdir +@c LocalWords: mountpoint uploaders pgprings cartouche -- 2.25.1