krb5: Update MIT KRB5 from 1.21 to 1.22

Merge commit 'd82a140dad3a571d66abb2da24acbba90191f168'
This commit is contained in:
Cy Schubert committed 2025-08-09 22:29:02 -07:00
commit f1c4c3dacc
1985 files changed
+52291 -89644

No files matched your search

+19 -24
View File
@@ -26,6 +26,7 @@ jobs:
- name: linux-gcc
os: ubuntu-latest
compiler: gcc
makevars: CPPFLAGS=-D_FORTIFY_SOURCE=3
steps:
- name: Checkout repository
uses: actions/checkout@v1
@@ -33,7 +34,7 @@ jobs:
if: startsWith(matrix.os, 'ubuntu')
run: |
sudo apt-get update -qq
sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh
sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh yasm softhsm2 opensc
pip3 install pyrad
- name: Build
env:
@@ -41,12 +42,17 @@ jobs:
MAKEVARS: ${{ matrix.makevars }}
CONFIGURE_OPTS: ${{ matrix.configureopts }}
run: |
# For the ksu tests, allow homedir access from other users.
umask 022
chmod a+rx $HOME
chmod -R a+rX src
cd src
autoreconf
./configure --enable-maintainer-mode --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst
make $MAKEVARS
make check
make install
(cd clients/ksu && make check-ksu)
- name: Display skipped tests
run: cat src/skiptests
- name: Check for files unexpectedly not removed by make distclean
@@ -64,6 +70,8 @@ jobs:
runs-on: windows-latest
env:
KRB_INSTALL_DIR: C:\kfw
OPENSSL_DIR: C:\Program Files\OpenSSL
OPENSSL_VERSION: 1_1
steps:
- name: Checkout repository
uses: actions/checkout@v1
@@ -73,32 +81,19 @@ jobs:
mkdir %KRB_INSTALL_DIR%
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: x86
- name: Build 32-bit
shell: cmd
arch: x64
- name: Build
working-directory: src
run: |
cd src
set
set PATH=%PATH%;%wix%bin
$env:Path += ';' + $env:WindowsSdkVerBinPath + '\\x86'
nmake -f Makefile.in prep-windows
nmake
nmake install
cd windows\installer\wix
nmake
rename kfw.msi kfw32.msi
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Build 64-bit
shell: cmd
- name: Populate install dir
working-directory: src
run: |
cd src
set
set PATH=%PATH%;%wix%bin;"%WindowsSdkVerBinPath%"\x86
nmake clean
nmake
nmake install
cd windows\installer\wix
nmake clean
- name: Build installer
working-directory: src\windows\installer\wix
run: |
$env:Path += ';' + $env:wix + 'bin'
nmake
rename kfw.msi kfw64.msi
+38
View File
@@ -0,0 +1,38 @@
name: CIFuzz
on:
pull_request: {paths: [src/**, .github/workflows/cifuzz.yml]}
permissions: {}
jobs:
Fuzzing:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'krb5'
language: c
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'krb5'
language: c
fuzz-seconds: 300
output-sarif: true
- name: Upload Crash
uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts
- name: Upload Sarif
if: always() && steps.build.outcome == 'success'
uses: github/codeql-action/upload-sarif@v3
with:
# Path to SARIF file relative to the root of the repository
sarif_file: cifuzz-sarif/results.sarif
checkout_path: cifuzz-sarif
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
cd src/doc
make -f Makefile.in SPHINX_ARGS=-W htmlsrc
- name: Upload HTML
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: html
path: doc/html
+82 -106
View File
@@ -1,4 +1,4 @@
Copyright (C) 1985-2024 by the Massachusetts Institute of Technology.
Copyright (C) 1985-2025 by the Massachusetts Institute of Technology.
All rights reserved.
@@ -172,10 +172,10 @@ following copyright:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Red Hat, Inc., nor the names of its
contributors may be used to endorse or promote products derived
@@ -345,9 +345,8 @@ notice:
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
@@ -386,10 +385,10 @@ backend, are subject to the following license:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* The copyright holder's name is not used to endorse or promote
products derived from this software without specific prior
@@ -497,16 +496,15 @@ permission notice:
documentation ("Software"), with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions in source form must retain copyright
statements and notices,
1. Redistributions in source form must retain copyright statements
and notices,
2. Redistributions in binary form must reproduce applicable
copyright statements and notices, this list of conditions, and
the following disclaimer in the documentation and/or other
materials provided with the distribution, and
3. Redistributions must contain a verbatim copy of this
document.
3. Redistributions must contain a verbatim copy of this document.
The OpenLDAP Foundation may revise this license from time to time.
Each revision is distinguished by a version number. You may use
@@ -552,18 +550,17 @@ Marked test programs in src/lib/krb5/krb have the following copyright:
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. Neither the name of KTH nor the names of its contributors may
be used to endorse or promote products derived from this
software without specific prior written permission.
3. Neither the name of KTH nor the names of its contributors may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
@@ -593,9 +590,8 @@ copyright:
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
@@ -632,17 +628,16 @@ src/include/gssrpc have the following copyright and permission notice:
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. Neither the name of the "Oracle America, Inc." nor the names
of its contributors may be used to endorse or promote products
3. Neither the name of the "Oracle America, Inc." nor the names of
its contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
@@ -668,9 +663,9 @@ src/include/gssrpc have the following copyright and permission notice:
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer as the first lines of this file unmodified.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer as
the first lines of this file unmodified.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
@@ -739,10 +734,10 @@ src/include/gssrpc have the following copyright and permission notice:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -796,38 +791,6 @@ src/include/gssrpc have the following copyright and permission notice:
======================================================================
Portions of the implementation of the Fortuna-like PRNG are subject to
the following notice:
Copyright (C) 2005 Marko Kreen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Copyright (C) 1994 by the University of Southern California
EXPORT OF THIS SOFTWARE from the United States of America may
@@ -863,9 +826,8 @@ the following notice:
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
@@ -932,9 +894,8 @@ The following notice applies to "src/lib/krb5/krb/strptime.c" and
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
@@ -947,10 +908,9 @@ The following notice applies to "src/lib/krb5/krb/strptime.c" and
This product includes software developed by the NetBSD
Foundation, Inc. and its contributors.
4. Neither the name of The NetBSD Foundation nor the names of
its contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
4. Neither the name of The NetBSD Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
@@ -1037,16 +997,6 @@ The following notice applies to "src/util/profile/argv_parse.c" and
======================================================================
The following notice applies to SWIG-generated code in
"src/util/profile/profile_tcl.c":
Copyright (C) 1999-2000, The University of Chicago
This file may be freely redistributed without license or fee
provided this copyright message remains intact.
======================================================================
The following notice applies to portiions of "src/lib/rpc" and
"src/include/gssrpc":
@@ -1060,9 +1010,8 @@ The following notice applies to portiions of "src/lib/rpc" and
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
@@ -1192,9 +1141,8 @@ license:
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
@@ -1232,10 +1180,10 @@ The bundled libev source code is subject to the following license:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -1273,9 +1221,8 @@ following license:
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
@@ -1314,10 +1261,10 @@ The following notice applies to
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -1382,3 +1329,32 @@ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
======================================================================
The following notice applies to files in "src/tests/fuzzing":
Copyright (C) 2024 by Arjun. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+120 -105
View File
@@ -1,4 +1,4 @@
Kerberos Version 5, Release 1.21
Kerberos Version 5, Release 1.22
Release Notes
The MIT Kerberos Team
@@ -6,7 +6,7 @@
Copyright and Other Notices
---------------------------
Copyright (C) 1985-2024 by the Massachusetts Institute of Technology
Copyright (C) 1985-2025 by the Massachusetts Institute of Technology
and its contributors. All rights reserved.
Please see the file named NOTICE for additional notices.
@@ -97,130 +97,133 @@ removed.
Beginning with the krb5-1.18 release, all support for single-DES
encryption types has been removed.
Major changes in 1.21.3 (2024-06-26)
------------------------------------
This is a bug fix release.
* Fix vulnerabilities in GSS message token handling [CVE-2024-37370,
CVE-2024-37371].
* Fix a potential bad pointer free in krb5_cccol_have_contents().
* Fix a memory leak in the macOS ccache type.
krb5-1.21.2 changes by ticket ID
--------------------------------
9102 Eliminate sim_client include of getopt.h
9103 segfault trying to free a garbage pointer
9104 Work around Doxygen 1.9.7 change
9107 In PKINIT, check for null PKCS7 enveloped fields
9109 memory leak on macos
9115 Fix leak in KDC NDR encoding
9125 Formatting error in realm_config.rst
9128 Fix vulnerabilities in GSS message token handling
Major changes in 1.21.2 (2023-08-14)
------------------------------------
This is a bug fix release.
* Fix double-free in KDC TGS processing [CVE-2023-39975].
krb5-1.21.2 changes by ticket ID
--------------------------------
9101 Fix double-free in KDC TGS processing
Major changes in 1.21.1 (2023-07-10)
------------------------------------
This is a bug fix release.
* Fix potential uninitialized pointer free in kadm5 XDR parsing
[CVE-2023-36054].
krb5-1.21.1 changes by ticket ID
--------------------------------
9099 Ensure array count consistency in kadm5 RPC
Major changes in 1.21 (2023-06-05)
Major changes in 1.22 (2025-08-05)
----------------------------------
User experience:
* Added a credential cache type providing compatibility with the macOS
11 native credential cache.
* The libdefaults configuration variable "request_timeout" can be set
to limit the total timeout for KDC requests. When making a KDC
request, the client will now wait indefinitely (or until the request
timeout has elapsed) on a KDC which accepts a TCP connection,
without contacting any additional KDCs. Clients will make fewer DNS
queries in some configurations.
* The realm configuration variable "sitename" can be set to cause the
client to query site-specific DNS records when making KDC requests.
Administrator experience:
* Principal aliases are supported in the DB2 and LMDB KDB modules and
in the kadmin protocol. (The LDAP KDB module has supported aliases
since release 1.7.)
* UNIX domain sockets are supported for the Kerberos and kpasswd
protocols.
* systemd socket activation is supported for krb5kdc and kadmind.
Developer experience:
* libkadm5 will use the provided krb5_context object to read
configuration values, instead of creating its own.
* KDB modules can be be implemented in terms of other modules using
the new krb5_db_load_module() function.
* Added an interface to retrieve the ticket session key from a GSS
context.
* The profile library supports the modification of empty profiles and
the copying of modified profiles, making it possible to construct an
in-memory profile and pass it to krb5_init_context_profile().
* GSS-API applications can pass the GSS_C_CHANNEL_BOUND flag to
gss_init_sec_context() to request strict enforcement of channel
bindings by the acceptor.
Protocol evolution:
* The KDC will no longer issue tickets with RC4 or triple-DES session
keys unless explicitly configured with the new allow_rc4 or
allow_des3 variables respectively.
* The PKINIT preauth module supports elliptic curve client
certificates, ECDH key exchange, and the Microsoft paChecksum2
field.
* The KDC will assume that all services can handle aes256-sha1 session
keys unless the service principal has a session_enctypes string
attribute.
* The IAKERB implementation has been changed to comply with the most
recent draft standard and to support realm discovery.
* Support for PAC full KDC checksums has been added to mitigate an
S4U2Proxy privilege escalation attack.
* The PKINIT client will advertise a more modern set of supported CMS
algorithms.
* Message-Authenticator is supported in the RADIUS implementation used
by the OTP kdcpreauth module.
Code quality:
* Removed unused code in libkrb5, libkrb5support, and the PKINIT
module.
* Removed old-style function declarations, to accomodate compilers
which have removed support for them.
* Modernized the KDC code for processing TGS requests, the code for
encrypting and decrypting key data, the PAC handling code, and the
GSS library packet parsing and composition code.
* Added OSS-Fuzz to the project's continuous integration
infrastructure.
* Improved the test framework's detection of memory errors in daemon
processes when used with asan.
* Rewrote the GSS per-message token parsing code for improved safety.
krb5-1.21 changes by ticket ID
krb5-1.22 changes by ticket ID
------------------------------
9052 Support macOS 11 native credential cache
9053 Make kprop work for dump files larger than 4GB
9054 Replace macros with typedefs in gssrpc types.h
9055 Use SHA-256 instead of SHA-1 for PKINIT CMS digest
9057 Omit LDFLAGS from krb5-config --libs output
9058 Add configure variable for default PKCS#11 module
9059 Use context profile for libkadm5 configuration
9066 Set reasonable supportedCMSTypes in PKINIT
9069 Update error checking for OpenSSL CMS_verify
9071 Add and use ts_interval() helper
9072 Avoid small read overrun in UTF8 normalization
9076 Use memmove() in Unicode functions
9077 Fix aclocal.m4 syntax error for autoconf 2.72
9078 Fix profile crash on memory exhaustion
9079 Fix preauth crash on memory exhaustion
9080 Fix gic_keytab crash on memory exhaustion
9082 Fix policy DB fallback error handling
9083 Fix kpropd crash with unrecognized option
9084 Add PAC full checksums
9085 Fix read overruns in SPNEGO parsing
9086 Fix possible double-free during KDB creation
9087 Fix meridian type in getdate.y
9088 Use control flow guard flag in Windows builds
9089 Add pac_privsvr_enctype string attribute
9090 Convey realm names to certauth modules
9091 Add GSS_C_INQ_ODBC_SESSION_KEY
9092 Fix maintainer-mode build for binutils 2.37
9093 Add PA-REDHAT-PASSKEY padata type
7721 Primary KDC lookups happen sooner than necessary
7899 Client waits before moving on after KDC_ERR_SVC_UNAVAILABLE
8618 ksu doesn't exit nonzero
9094 Get arm64-windows builds working
9095 PKINIT ECDH support
9096 Enable PKINIT if at least one group is available
9100 Add ecdsa-with-sha512/256 to supportedCMSTypes
9105 Wait indefinitely on KDC TCP connections
9106 Add request_timeout configuration parameter
9108 Remove PKINIT RSA support
9110 profile library null dereference when modifying empty profile
9111 Correct PKINIT EC cert signature metadata
9112 Support PKCS11 EC client certs in PKINIT
9113 Improve PKCS11 error reporting in PKINIT
9114 Build fails with link-time optimization
9116 Improve error message for DES kadmin/history key
9118 profile write operation interactions with reloading
9119 Make profile_copy() work on dirty profiles
9120 profile final flag limitations
9121 Don't flush libkrb5 context profiles
9122 Add GSS flag to include KERB_AP_OPTIONS_CBT
9123 Correct IAKERB protocol implementation
9124 Support site-local KDC discovery via DNS
9126 Handle empty initial buffer in IAKERB initiator
9130 make krb5_get_default_config_files public
9131 Adjust removed cred detection in FILE ccache
9132 Change krb5_get_credentials() endtime behavior
9133 Add acceptor-side IAKERB realm discovery
9135 Replace Windows installer FilesInUse dialog text
9139 Block library unloading to avoid finalizer races
9141 Fix krb5_crypto_us_timeofday() microseconds check
9142 Generate and verify message MACs in libkrad
9143 Fix memory leak in PAC checksum verification
9144 Fix potential PAC processing crash
9145 Prevent late initialization of GSS error map
9146 Allow null keyblocks in IOV checksum functions
9147 Add numeric constants to krad.h and use them
9148 Fix krb5_ldap_list_policy() filtering loop
9149 Use getentropy() when available
9151 Add kadmind support for disabling listening
9152 Default kdc_tcp_listen to kdc_listen value
9153 Fix LDAP module leak on authentication error
9154 Components of the X509_user_identity string cannot contain ':'
9155 UNIX domain socket support
9156 Allow KDB module stacking
9157 Add support for systemd socket activation
9158 Set missing mask flags for kdb5_util operations
9159 Prevent overflow when calculating ulog block size
9160 Allow only one salt type per enctype in key data
9161 Improve ulog block resize efficiency
9162 Build PKINIT on Windows
9163 Add alias support
9164 Add database format documentation
9165 Display NetBIOS ticket addresses in klist
9166 Add PKINIT paChecksum2 from MS-PKCA v20230920
9167 Add initiator-side IAKERB realm discovery
9168 Fix IAKERB accept_sec_context null pointer crash
9169 Fix IAKERB error handling
9170 Avoid gss_inquire_attrs_for_mech() null outputs
9171 Fix getsockname() call in Windows localaddr
9172 Check lengths in xdr_krb5_key_data()
9173 Limit -keepold for self-service key changes
9179 Avoid large numbers of refresh_time cache entries
Acknowledgements
----------------
@@ -338,6 +341,7 @@ reports, suggestions, and valuable resources:
Toby Blake
Radoslav Bodo
Alexander Bokovoy
Zoltan Borbely
Sumit Bose
Emmanuel Bouillon
Isaac Boukris
@@ -359,6 +363,7 @@ reports, suggestions, and valuable resources:
Andrea Cirulli
Christopher D. Clausen
Kevin Coffman
Gerald Combs
Simon Cooper
Sylvain Cortes
Ian Crowther
@@ -368,6 +373,7 @@ reports, suggestions, and valuable resources:
Nalin Dahyabhai
Mark Davies
Dennis Davis
Rull Deef
Alex Dehnert
Misty De Meo
Mark Deneen
@@ -385,6 +391,7 @@ reports, suggestions, and valuable resources:
Peter Eriksson
Juha Erkkilä
Gilles Espinasse
Valery Fedorenko
Sergey Fedorov
Ronni Feldt
Bill Fellows
@@ -398,6 +405,7 @@ reports, suggestions, and valuable resources:
Oliver Freyermuth
Ákos Frohner
Sebastian Galiano
Ilya Gladyshev
Marcus Granado
Dylan Gray
Norm Green
@@ -405,6 +413,7 @@ reports, suggestions, and valuable resources:
Helmut Grohne
Steve Grubb
Philip Guenther
Feng Guo
Timo Gurr
Dominic Hargreaves
Robbie Harwood
@@ -440,10 +449,12 @@ reports, suggestions, and valuable resources:
Zentaro Kavanagh
Mubashir Kazia
W. Trevor King
Steffen Kieß
Patrik Kis
Martin Kittel
Thomas Klausner
Tomasz Kłoczko
Ivan Korytov
Matthew Krupcale
Mikkel Kruse
Reinhard Kugler
@@ -476,6 +487,7 @@ reports, suggestions, and valuable resources:
Alexey Melnikov
Ivan A. Melnikov
Franklyn Mendez
Stefan Metzmacher
Mantas Mikulėnas
Markus Moeller
Kyle Moffett
@@ -487,6 +499,7 @@ reports, suggestions, and valuable resources:
Sam Morris
Zbysek Mraz
Edward Murrell
Bahaa Naamneh
Joshua Neuheisel
Nikos Nikoleris
Demi Obenour
@@ -524,6 +537,7 @@ reports, suggestions, and valuable resources:
Jens Schleusener
Ryan Schmidt
Andreas Schneider
Eli Schwartz
Paul Seyfert
Tom Shaw
Jim Shi
@@ -538,6 +552,7 @@ reports, suggestions, and valuable resources:
Bjørn Tore Sund
Ondřej Surý
Joseph Sutton
Alexey Tikhonov
Joe Travaglini
Sergei Trofimovich
Greg Troxel
@@ -460,6 +460,24 @@ This command requires the **add** and **delete** privileges.
Alias: **renprinc**
.. _add_alias:
add_alias
~~~~~~~~~
**add_alias** *alias_princ* *target_princ*
Create an alias *alias_princ* pointing to *target_princ*. Aliases may
be chained (that is, *target_princ* may itself be an alias) up to a
depth of 10.
This command requires the **add** privilege for *alias_princ* and the
**modify** privilege for *target_princ*.
(New in release 1.22.)
Aliases: **alias**
.. _delete_principal:
delete_principal
@@ -467,8 +485,8 @@ delete_principal
**delete_principal** [**-force**] *principal*
Deletes the specified *principal* from the database. This command
prompts for deletion, unless the **-force** option is given.
Deletes the specified *principal* or alias from the database. This
command prompts for deletion, unless the **-force** option is given.
This command requires the **delete** privilege.
@@ -121,6 +121,14 @@ ENVIRONMENT
See :ref:`kerberos(7)` for a description of Kerberos environment
variables.
As of release 1.22, kadmind supports systemd socket activation via the
LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by
the caller must correspond to configured listener addresses (via the
**kadmind_listen** or **kpasswd_listen** variables or equivalents) or
they will be ignored. Any configured listener addresses that do not
correspond to caller-provided sockets will be ignored if socket
activation is used.
SEE ALSO
--------
@@ -376,6 +376,14 @@ Options:
Dump types:
**alias**
principal alias information
**aliasname**
the name of the alias
**targetname**
the target of the alias
**keydata**
principal encryption key information, including actual key data
(which is still encrypted in the master key)
@@ -106,6 +106,13 @@ ENVIRONMENT
See :ref:`kerberos(7)` for a description of Kerberos environment
variables.
As of release 1.22, krb5kdc supports systemd socket activation via the
LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by
the caller must correspond to configured listener addresses (via the
**kdc_listen** variable or equivalent) or they will be ignored. Any
configured listener addresses that do not correspond to
caller-provided sockets will be ignored if socket activation is used.
SEE ALSO
--------
+43 -38
View File
@@ -289,14 +289,16 @@ The following tags may be specified in a [realms] subsection:
**kadmind_listen**
(Whitespace- or comma-separated list.) Specifies the kadmin RPC
listening addresses and/or ports for the :ref:`kadmind(8)` daemon.
Each entry may be an interface address, a port number, or an
address and port number separated by a colon. If the address
contains colons, enclose it in square brackets. If no address is
specified, the wildcard address is used. If kadmind fails to bind
to any of the specified addresses, it will fail to start. The
default is to bind to the wildcard address at the port specified
in **kadmind_port**, or the standard kadmin port (749). New in
release 1.15.
Each entry may be an interface address, a port number, an address
and port number separated by a colon, or a UNIX domain socket
pathname. If the address contains colons, enclose it in square
brackets. If no address is specified, the wildcard address is
used. To disable listening for kadmin RPC connections, set this
relation to the empty string with ``kadmind_listen = ""``. If
kadmind fails to bind to any of the specified addresses, it will
fail to start. The default is to bind to the wildcard address at
the port specified in **kadmind_port**, or the standard kadmin
port (749). New in release 1.15.
**kadmind_port**
(Port number.) Specifies the port on which the :ref:`kadmind(8)`
@@ -310,16 +312,18 @@ The following tags may be specified in a [realms] subsection:
``/.k5.REALM``, where *REALM* is the Kerberos realm.
**kdc_listen**
(Whitespace- or comma-separated list.) Specifies the UDP
listening addresses and/or ports for the :ref:`krb5kdc(8)` daemon.
Each entry may be an interface address, a port number, or an
address and port number separated by a colon. If the address
contains colons, enclose it in square brackets. If no address is
specified, the wildcard address is used. If no port is specified,
the standard port (88) is used. If the KDC daemon fails to bind
to any of the specified addresses, it will fail to start. The
default is to bind to the wildcard address on the standard port.
New in release 1.15.
(Whitespace- or comma-separated list.) Specifies the listening
addresses and/or ports for the :ref:`krb5kdc(8)` daemon. Each
entry may be an interface address, a port number, an address and
port number separated by a colon, or a UNIX domain socket
pathname. If the address contains colons, enclose it in square
brackets. If no address is specified, the wildcard address is
used. If no port is specified, the standard port (88) is used.
To disable listening on UDP, set this relation to the empty string
with ``kdc_listen = ""``. If the KDC daemon fails to bind to any
of the specified addresses, it will fail to start. The default is
to bind to the wildcard address on the standard port. New in
release 1.15.
**kdc_ports**
(Whitespace- or comma-separated list, deprecated.) Prior to
@@ -331,15 +335,10 @@ The following tags may be specified in a [realms] subsection:
**kdc_tcp_listen**
(Whitespace- or comma-separated list.) Specifies the TCP
listening addresses and/or ports for the :ref:`krb5kdc(8)` daemon.
Each entry may be an interface address, a port number, or an
address and port number separated by a colon. If the address
contains colons, enclose it in square brackets. If no address is
specified, the wildcard address is used. If no port is specified,
the standard port (88) is used. To disable listening on TCP, set
this relation to the empty string with ``kdc_tcp_listen = ""``.
If the KDC daemon fails to bind to any of the specified addresses,
it will fail to start. The default is to bind to the wildcard
address on the standard port. New in release 1.15.
The syntax is identical to that of **kdc_listen**. To disable
listening on TCP, set this relation to the empty string with
``kdc_tcp_listen = ""``. The default is to bind to the same
addresses and ports as for UDP. New in release 1.15.
**kdc_tcp_ports**
(Whitespace- or comma-separated list, deprecated.) Prior to
@@ -349,15 +348,18 @@ The following tags may be specified in a [realms] subsection:
**kdc_tcp_listen** if that relation is not defined.
**kpasswd_listen**
(Comma-separated list.) Specifies the kpasswd listening addresses
and/or ports for the :ref:`kadmind(8)` daemon. Each entry may be
an interface address, a port number, or an address and port number
separated by a colon. If the address contains colons, enclose it
in square brackets. If no address is specified, the wildcard
address is used. If kadmind fails to bind to any of the specified
addresses, it will fail to start. The default is to bind to the
wildcard address at the port specified in **kpasswd_port**, or the
standard kpasswd port (464). New in release 1.15.
(Comma-separated list.) Specifies the kpasswd listening
addresses and/or ports for the :ref:`kadmind(8)` daemon. Each
entry may be an interface address, a port number, an address and
port number separated by a colon, or a UNIX domain socket
pathname. If the address contains colons, enclose it in square
brackets. If no address is specified, the wildcard address is
used. To disable listening for kpasswd requests, set this
relation to the empty string with ``kpasswd_listen = ""``. If
kadmind fails to bind to any of the specified addresses, it will
fail to start. The default is to bind to the wildcard address at
the port specified in **kpasswd_port**, or the standard kpasswd
port (464). New in release 1.15.
**kpasswd_port**
(Port number.) Specifies the port on which the :ref:`kadmind(8)`
@@ -768,8 +770,11 @@ For information about the syntax of some of these options, see
be specified multiple times.
**pkinit_dh_min_bits**
Specifies the minimum number of bits the KDC is willing to accept
for a client's Diffie-Hellman key. The default is 2048.
Specifies the minimum strength of Diffie-Hellman group the KDC is
willing to accept for key exchange. Valid values in order of
increasing strength are 1024, 2048, P-256, 4096, P-384, and P-521.
The default is 2048. (P-256, P-384, and P-521 are new in release
1.22.)
**pkinit_allow_upn**
Specifies that the KDC is willing to accept client certificates
+46 -19
View File
@@ -35,12 +35,6 @@ or::
baz = quux
}
Placing a '\*' after the closing bracket of a section name indicates
that the section is *final*, meaning that if the same section appears
within a later file specified in **KRB5_CONFIG**, it will be ignored.
A subsection can be marked as final by placing a '\*' after either the
tag name or the closing brace.
The krb5.conf file can include other files using either of the
following directives at the beginning of a line::
@@ -58,6 +52,16 @@ section header. Starting in release 1.17, files are read in
alphanumeric order; in previous releases, they may be read in any
order.
Placing a '\*' after the closing bracket of a section name indicates
that the section is *final*, meaning that if the same section appears
again later, it will be ignored. A subsection can be marked as final
by placing a '\*' after either the tag name or the closing brace. A
relation can be marked as final by placing a '\*' after the tag name.
Prior to release 1.22, only sections and subsections can be marked as
final, and the flag only causes values to be ignored if they appear in
later files specified in **KRB5_CONFIG**, not if they appear later
within the same file or an included file.
The krb5.conf file can specify that configuration should be obtained
from a loadable module, rather than the file itself, using the
following directive at the beginning of a line before any section
@@ -221,6 +225,12 @@ The libdefaults section may contain any of the following relations:
data), and anything the fake KDC sends will not be trusted without
verification using some secret that it won't know.
**dns_lookup_realm**
Indicate whether DNS TXT records should be used to map hostnames
to realm names for hostnames not listed in the [domain_realm]
section, and to determine the default realm if **default_realm**
is not set. The default value is false.
**dns_uri_lookup**
Indicate whether DNS URI records should be used to locate the KDCs
and other servers for a realm, if they are not listed in the
@@ -362,6 +372,15 @@ The libdefaults section may contain any of the following relations:
(:ref:`duration` string.) Sets the default renewable lifetime
for initial ticket requests. The default value is 0.
**request_timeout**
(:ref:`duration` string.) Sets the maximum total time for KDC and
password change requests. This timeout does not affect the
intervals between requests, so setting a low timeout may result in
fewer requests being attempted and/or some servers not being
contacted. A value of 0 indicates no specific maximum, in which
case requests will time out if no server responds after several
tries. The default value is 0. (New in release 1.22.)
**spake_preauth_groups**
A whitespace or comma-separated list of words which specifies the
groups allowed for SPAKE preauthentication. The possible values
@@ -511,20 +530,21 @@ following tags may be specified in the realm's subsection:
been set to ``FILE:/tmp/my_proxy.pem``.
**kdc**
The name or address of a host running a KDC for that realm. An
optional port number, separated from the hostname by a colon, may
be included. If the name or address contains colons (for example,
if it is an IPv6 address), enclose it in square brackets to
The name or address of a host running a KDC for the realm, or a
UNIX domain socket path of a locally running KDC. An optional
port number, separated from the hostname by a colon, may be
included. If the name or address contains colons (for example, if
it is an IPv6 address), enclose it in square brackets to
distinguish the colon from a port separator. For your computer to
be able to communicate with the KDC for each realm, this tag must
be given a value in each realm subsection in the configuration
file, or there must be DNS SRV records specifying the KDCs.
**kpasswd_server**
Points to the server where all the password changes are performed.
If there is no such entry, DNS will be queried (unless forbidden
by **dns_lookup_kdc**). Finally, port 464 on the **admin_server**
host will be tried.
The location of the password change server for the realm, using
the same syntax as **kdc**. If there is no such entry, DNS will
be queried (unless forbidden by **dns_lookup_kdc**). Finally,
port 464 on the **admin_server** host will be tried.
**master_kdc**
The name for **primary_kdc** prior to release 1.19. Its value is
@@ -538,6 +558,10 @@ following tags may be specified in the realm's subsection:
the updated database has not been propagated to the replica
servers yet. New in release 1.19.
**sitename**
Specifies the name of the host's site for the purpose of DNS-based
KDC discovery for this realm. New in release 1.22.
**v4_instance_convert**
This subsection allows the administrator to configure exceptions
to the **default_domain** mapping rule. It contains V4 instances
@@ -1028,8 +1052,10 @@ information for PKINIT is as follows:
a particular smard card reader or token if there is more than one
available. ``certid=`` and/or ``certlabel=`` may be specified to
force the selection of a particular certificate on the device.
See the **pkinit_cert_match** configuration option for more ways
to select a particular certificate to use for PKINIT.
Specifier values must not contain colon characters, as colons are
always treated as separators. See the **pkinit_cert_match**
configuration option for more ways to select a particular
certificate to use for PKINIT.
**ENV:**\ *envvar*
*envvar* specifies the name of an environment variable which has
@@ -1128,9 +1154,10 @@ PKINIT krb5.conf options
option is not recommended.
**pkinit_dh_min_bits**
Specifies the size of the Diffie-Hellman key the client will
attempt to use. The acceptable values are 1024, 2048, and 4096.
The default is 2048.
Specifies the group of the Diffie-Hellman key the client will
attempt to use. The acceptable values are 1024, 2048, P-256,
4096, P-384, and P-521. The default is 2048. (P-256, P-384, and
P-521 are new in release 1.22.)
**pkinit_identities**
Specifies the location(s) to be used to find the user's X.509
+4 -3
View File
@@ -112,9 +112,10 @@ Configuring Kerberos with OpenLDAP back-end
details.
With the LDAP back end it is possible to provide aliases for principal
entries. Currently we provide no administrative utilities for
creating aliases, so it must be done by direct manipulation of the
LDAP entries.
entries. Beginning in release 1.22, aliases can be added with the
kadmin **add_alias** command, but it is also possible (in release 1.7
or later) to provide aliases through direct manipulation of the LDAP
entries.
An entry with aliases contains multiple values of the
*krbPrincipalName* attribute. Since LDAP attribute values are not
+4
View File
@@ -93,6 +93,10 @@ To view the attributes of a principal, use the kadmin`
To generate a listing of principals, use the kadmin
**list_principals** command.
To give a principal additional names, use the kadmin **add_alias**
command to create aliases to the principal (new in release 1.22).
Aliases can be removed with the **delete_principal** command.
.. _policies:
+10
View File
@@ -196,6 +196,13 @@ using the **kdc**, **master_kdc**, **admin_server**, and
explicit server locations, providing SRV records will still benefit
unconfigured clients, and be useful for other sites.
Clients can be configured with the **sitename** realm variable (new in
release 1.22). If a site name is set, the client first attempts SRV
record lookups with ".*sitename*._sites" inserted after the service
and protocol name and before the Kerberos realm. Site-specific
records may indicate servers more proximal to the client, allowing for
faster access.
.. _kdc_discovery:
@@ -244,6 +251,9 @@ URI lookups are enabled by default, and can be disabled by setting
precedence over SRV lookups, falling back to SRV lookups if no URI
records are found.
The **sitename** variable in the :ref:`realms` section of
:ref:`krb5.conf(5)` applies to URI lookups as well as SRV lookups.
.. _db_prop:
+36
View File
@@ -424,6 +424,42 @@ set. If the library does not support the query,
gss_inquire_cred_by_oid will return **GSS_S_UNAVAILABLE**.
Channel binding behavior and GSS_C_CHANNEL_BOUND_FLAG
-----------------------------------------------------
GSSAPI channel bindings can be used to limit the scope of a context
establishment token to a particular protected channel or endpoint,
such as a TLS channel or server certificate. Channel bindings can be
supplied via the *input_chan_bindings* parameter to either
gss_init_sec_context() or gss_accept_sec_context().
If both the initiator and acceptor of a GSSAPI exchange supply
matching channel bindings, **GSS_C_CHANNEL_BOUND_FLAG** will be
included in the gss_accept_sec_context() *ret_flags* result. If
either the initiator or acceptor (or both) do not supply channel
bindings, the exchange will succeed, but **GSS_C_CHANNEL_BOUND_FLAG**
will not be included in the return flags. If the acceptor and
initiator both inlude channel bindings but they do not match, the
exchange will fail.
If **GSS_C_CHANNEL_BOUND_FLAG** is included in the *req_flags*
parameter of gss_init_sec_context(), the initiator will add the
Microsoft KERB_AP_OPTIONS_CBT extension to the Kerberos authenticator.
This extension requests that the acceptor strictly enforce channel
bindings, causing the exchange to fail if the acceptor supplies
channel bindings and the initiator does not. The KERB_AP_OPTIONS_CBT
extension will also be included if the
**client_aware_channel_bindings** variable is set to ``true`` in
:ref:`libdefaults`.
Prior to release 1.19, **GSS_C_CHANNEL_BOUND_FLAG** is not
implemented, and the exchange will fail if the acceptor supply channel
bindings and the initiator does not (but not vice versa). Between
releases 1.19 and 1.21, **GSS_C_CHANNEL_BOUND_FLAG** is not recognized
as an initiator flag, so **client_aware_channel_bindings** is the only
way to cause KERB_AP_OPTIONS_CBT to be included.
AEAD message wrapping
---------------------
@@ -25,6 +25,7 @@ Frequently used public interfaces
krb5_change_password.rst
krb5_chpw_message.rst
krb5_expand_hostname.rst
krb5_free_config_files.rst
krb5_free_context.rst
krb5_free_error_message.rst
krb5_free_principal.rst
@@ -33,6 +34,7 @@ Frequently used public interfaces
krb5_get_error_message.rst
krb5_get_host_realm.rst
krb5_get_credentials.rst
krb5_get_default_config_files.rst
krb5_get_fallback_host_realm.rst
krb5_get_init_creds_keytab.rst
krb5_get_init_creds_opt_alloc.rst
@@ -9,6 +9,7 @@ Public
ADDRTYPE_ADDRPORT.rst
ADDRTYPE_CHAOS.rst
ADDRTYPE_DIRECTIONAL.rst
ADDRTYPE_DDP.rst
ADDRTYPE_INET.rst
ADDRTYPE_INET6.rst
@@ -17,11 +18,13 @@ Public
ADDRTYPE_IS_LOCAL.rst
ADDRTYPE_NETBIOS.rst
ADDRTYPE_XNS.rst
ADDRTYPE_UNIXSOCK.rst
AD_TYPE_EXTERNAL.rst
AD_TYPE_FIELD_TYPE_MASK.rst
AD_TYPE_REGISTERED.rst
AD_TYPE_RESERVED.rst
AP_OPTS_ETYPE_NEGOTIATION.rst
AP_OPTS_CBT_FLAG.rst
AP_OPTS_MUTUAL_REQUIRED.rst
AP_OPTS_RESERVED.rst
AP_OPTS_USE_SESSION_KEY.rst
@@ -177,6 +180,7 @@ Public
KRB5_KEYUSAGE_GSS_TOK_MIC.rst
KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG.rst
KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV.rst
KRB5_KEYUSAGE_FINISHED.rst
KRB5_KEYUSAGE_IAKERB_FINISHED.rst
KRB5_KEYUSAGE_KDC_REP_TICKET.rst
KRB5_KEYUSAGE_KRB_CRED_ENCPART.rst
+3
View File
@@ -284,6 +284,9 @@ Optional features
given, it controls the -fsanitize compilation flag value (the
default is "address").
**-**\ **-enable-ossfuzz**
Enable building fuzzing targets with OSS-Fuzz build support.
Optional packages
-----------------
+2 -2
View File
@@ -45,7 +45,7 @@ else:
# General information about the project.
project = u'MIT Kerberos'
copyright = u'1985-2024, MIT'
copyright = u'1985-2025, MIT'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -261,7 +261,7 @@ else:
rst_epilog = '\n'
if 'notice' in tags:
exclude_patterns = [ 'admin', 'appdev', 'basic', 'build',
exclude_patterns = [ 'admin', 'appdev', 'basic', 'build', 'formats',
'plugindev', 'user' ]
exclude_patterns += [ 'about.rst', 'build_this.rst', 'copyright.rst',
'index.rst', 'mitK5*.rst', 'resources.rst' ]
+1 -1
View File
@@ -1,7 +1,7 @@
Copyright
=========
Copyright |copy| 1985-2024 by the Massachusetts Institute of
Copyright |copy| 1985-2025 by the Massachusetts Institute of
Technology and its contributors. All rights reserved.
See :ref:`mitK5license` for additional copyright and license
+25 -11
View File
@@ -1,3 +1,5 @@
.. highlight:: abnf
KDC cookie format
=================
@@ -42,7 +44,9 @@ principal name with realm, marshalled according to :rfc:`1964` section
2.1.1.
The plain text of the encrypted part of a cookie is the DER encoding
of the following ASN.1 type::
of the following ASN.1 type:
.. code-block:: bnf
SecureCookie ::= SEQUENCE {
time INTEGER,
@@ -63,17 +67,27 @@ SPAKE cookie format (version 1)
-------------------------------
Inside the SecureCookie wrapper, a data value of type 151 contains
state for SPAKE pre-authentication. This data is the concatenation of
the following:
state for SPAKE pre-authentication. This data has the following
binary format with big-endian integer encoding:
* a two-byte big-endian version number with the value 1
* a two-byte big-endian stage number
* a four-byte big-endian group number
* a four-byte big-endian length and data for the SPAKE value
* a four-byte big-endian length and data for the transcript hash
* zero or more second factor records, each consisting of:
- a four-byte big-endian second-factor type
- a four-byte big-endian length and data
.. code-block:: bnf
cookie ::=
version (16 bits) [with the value 1]
stage number (16 bits)
group number (32 bits)
SPAKE value length (32 bits)
SPAKE value
transcript hash length (32 bits)
transcript hash
second factor record 1 (factor-record)
second factor record 2 (factor-record)
...
factor-record ::=
second factor type (32 bits)
second factor data length (32 bits)
second factor data
The stage value is 0 if the cookie was sent with a challenge message.
Otherwise it is 1 for the first encdata message sent by the KDC during
@@ -0,0 +1,459 @@
Kerberos Database (KDB) Formats
===============================
Dump format
-----------
Files created with the :ref:`kdb5_util(8)` **dump** command begin with
a versioned header "kdb5_util load_dump version 7". This version has
been in use since MIT krb5 release 1.11; some previous versions are
supported but are not described here.
Each subsequent line of the dump file contains one or more
tab-separated fields describing either a principal entry or a policy
entry. The fields of a principal entry line are:
* the word "princ"
* the string "38" (this was originally a length field)
* the length of the principal name in string form
* the decimal number of tag-length data elements
* the decimal number of key-data elements
* the string "0" (this was originally an extension length field)
* the principal name in string form
* the principal attributes as a decimal number; when converted to
binary, the bits from least significant to most significant are:
- disallow_postdated
- disallow_forwardable
- disallow_tgt_based
- disallow_renewable
- disallow_proxiable
- disallow_dup_skey
- disallow_all_tix
- requires_preauth
- requires_hwauth
- requires_pwchange
- disallow_svr
- pwchange_service
- support_desmd5
- new_princ
- ok_as_delegate
- ok_to_auth_as_delegate
- no_auth_data_required
- lockdown_keys
* the maximum ticket lifetime, as a decimal number of seconds
* the maximum renewable ticket lifetime, as a decimal number of seconds
* the principal expiration time, as a decimal POSIX timestamp
* the password expiration time, as a decimal POSIX timestamp
* the last successful authentication time, as a decimal POSIX
timestamp
* the last failed authentication time, as a decimal POSIX timestamp
* the decimal number of failed authentications since the last
successful authentication time
* for each tag-length data value:
- the tag value in decimal
- the length in decimal
- the data as a lowercase hexadecimal byte string, or "-1" if the length is 0
* for each key-data element:
- the string "2" if this element has non-normal salt type, "1"
otherwise
- the key version number of this element
- the encryption type
- the length of the encrypted key value
- the encrypted key as a lowercase hexadecimal byte string
- if this element has non-normal salt type:
- the salt type
- the length of the salt data
- the salt data as a lowercase hexadecimal byte string, or the
string "-1" if the salt data length is 0
* the string "-1;" (this was originally an extension field)
The fields of a policy entry line are:
* the string "policy"
* the policy name
* the minimum password lifetime as a decimal number of seconds
* the maximum password lifetime as a decimal number of seconds
* the minimum password length, in decimal
* the minimum number of character classes, in decimal
* the number of historical keys to be stored, in decimal
* the policy reference count (no longer used)
* the maximum number of failed authentications before lockout
* the time interval after which the failed authentication count is
reset, as a decimal number of seconds
* the lockout duration, as a decimal number of seconds
* the required principal attributes, in decimal (currently unenforced)
* the maximum ticket lifetime as a decimal number of seconds
(currently unenforced)
* the maximum renewable lifetime as a decimal number of seconds
(currently unenforced)
* the allowed key/salt types, or "-" if unrestricted
* the number of tag-length values
* for each tag-length data value:
- the tag value in decimal
- the length in decimal
- the data as a lowercase hexadecimal byte string, or "-1" if the
length is 0
Tag-length data formats
-----------------------
The currently defined tag-length data types are:
* (1) last password change: a four-byte little-endian POSIX timestamp
giving the last password change time
* (2) last modification data: a four-byte little-endian POSIX
timestamp followed by a zero-terminated principal name in string
form, giving the time of the last principal change and the principal
who performed it
* (3) kadmin data: the XDR encoding of a per-principal kadmin data
record (see below)
* (8) master key version: a two-byte little-endian integer containing
the master key version used to encrypt this principal's key data
* (9) active kvno: see below
* (10) master key auxiliary data: see below
* (11) string attributes: one or more iterations of a zero-terminated
string key followed by a zero-terminated string value
* (12) alias target principal: a zero-terminated principal name in
string form
* (255) LDAP object information: see below
* (768) referral padata: a DER-encoded PA-SVR-REFERRAL-DATA to be sent
to a TGS-REQ client within encrypted padata (see Appendix A of
:rfc:`1606`)
* (1792) last admin unlock: a four-byte little-endian POSIX timestamp
giving the time of the last administrative account unlock
* (32767) database arguments: a zero-terminated key=value string (may
appear multiple times); used by the kadmin protocol to
communicate -x arguments to kadmind
Per-principal kadmin data
~~~~~~~~~~~~~~~~~~~~~~~~~
Per-principal kadmin data records use a modified XDR encoding of the
kadmin_data type defined as follows:
.. code-block:: c
struct key_data {
int numfields;
unsigned int kvno;
int enctype;
int salttype;
unsigned int keylen;
unsigned int saltlen;
opaque key<>;
opaque salt<>;
};
struct hist_entry {
key_data keys<>;
};
struct kadmin_data {
int version_number;
nullstring policy;
int aux_attributes;
unsigned int old_key_next;
unsigned int admin_history_kvno;
hist_entry old_keysets<>;
};
The type "nullstring" uses a custom string encoder where the length
field is zero or the string length plus one; a length of zero
indicates that no policy object is specified for the principal. The
field "version_number" contains 0x12345C01. The aux_attributes field
contains the bit 0x800 if a policy object is associated with the
principal.
Within a key_data record, numfields is 2 if the key data has
non-normal salt type, 1 otherwise.
Active kvno and master key auxiliary data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These types only appear in the entry of the master key principal
(K/M). They use little-endian binary integer encoding.
The active kvno table determines which master key version is active
for a given timestamp. It uses the following binary format:
.. code-block:: bnf
active-key-version-table ::=
version (16 bits) [with the value 1]
version entry 1 (key-version-entry)
version entry 2 (key-version-entry)
...
key-version-entry ::=
key version (16 bits)
timestamp (32 bits) [when this key version becomes active]
The master key auxiliary data record contains copies of the current
master key encrypted in each older master key. It uses the following
binary format:
.. code-block:: bnf
master-key-aux ::=
version (16 bits) [with the value 1]
key entry 1 (key-entry)
key entry 2 (key-entry)
...
key-entry ::=
old master key version (16 bits)
latest master key version (16 bits)
latest master key encryption type (16 bits)
encrypted key length (16 bits)
encrypted key contents
LDAP object information
~~~~~~~~~~~~~~~~~~~~~~~
This type appears in principal entries retrieved with the LDAP KDB
module. The value uses the following binary format, using big-endian
integer encoding:
.. code-block:: bnf
ldap-principal-data ::=
record 1 (ldap-tl-data)
record 2 (ldap-tl-data)
...
ldap-tl-data ::=
type (8 bits)
length (16 bits)
data
The currently defined ldap-tl-data types are (all integers are
big-endian):
* (1) principal type: 16 bits containing the value 1, indicating that
the LDAP object containing the principal entry is a standalone
principal object
* (2) principal count: 16 bits containing the number of
krbPrincipalName values in the LDAP object
* (3) user DN: the string representation of the distinguished name of
the LDAP object
* (5) attribute mask: 16 bits indicating which Kerberos-specific LDAP
attributes are present in the LDAP object (see below)
* (7) link DN: the string representation of the distinguished name of
an LDAP object this object is linked to; may appear multiple times
When converted to binary, the attribute mask bits, from least
significant to most significant, correspond to the following LDAP
attributes:
* krbMaxTicketLife
* krbMaxRenewableAge
* krbTicketFlags
* krbPrincipalExpiration
* krbTicketPolicyReference
* krbPrincipalAuthInd
* krbPwdPolicyReference
* krbPasswordExpiration
* krbPrincipalKey
* krbLastPwdChange
* krbExtraData
* krbLastSuccessfulAuth
* krbLastFailedAuth
* krbLoginFailedCount
* krbLastAdminUnlock
* krbPwdHistory
Alias principal entries
-----------------------
To allow aliases to be represented in dump files and within the
incremental update protocol, the krb5 database library supports the
concept of an alias principal entry. An alias principal entry
contains an alias target principal in its tag-length data, has its
attributes set to disallow_all_tix, and has zero or empty values for
all other fields. The database glue library recognizes alias entries
and iteratively looks up the alias target up to a depth of 10 chained
aliases. (Added in release 1.22.)
DB2 principal and policy formats
--------------------------------
The DB2 KDB module uses the string form of a principal name, with zero
terminator, as a lookup key for principal entries. Principal entry
values use the following binary format with little-endian integer
encoding:
.. code-block:: bnf
db2-principal-entry ::=
len (16 bits) [always has the value 38]
attributes (32 bits)
max ticket lifetime (32 bits)
max renewable lifetime (32 bits)
principal expiration timestamp (32 bits)
password expiration timestamp (32 bits)
last successful authentication timestamp (32 bits)
last failed authentication timestamp (32 bits)
failed authentication counter (32 bits)
number of tag-length elements (16 bits)
number of key-data elements (16 bits)
length of string-form principal with zero terminator (16 bits)
string-form principal with zero terminator
tag-length entry 1 (tag-length-data)
tag-length entry 2 (tag-length-data)
...
key-data entry 1 (key-data)
key-data entry 2 (key-data)
...
tag-length-data ::=
type tag (16 bits)
data length (16 bits)
data
key-data ::=
salt indicator (16 bits) [1 for default salt, 2 otherwise]
key version (16 bits)
encryption type (16 bits)
encrypted key length (16 bits)
encrypted key
salt type (16 bits) [omitted if salt indicator is 1]
salt data length (16 bits) [omitted if salt indicator is 1]
salt data [omitted if salt indicator is 1]
DB2 policy entries reside in a separate database file. The lookup key
is the policy name with zero terminator. Policy entry values use a
modified XDR encoding of the policy type defined as follows:
.. code-block:: c
struct tl_data {
int type;
opaque data<>;
tl_data *next;
};
struct policy {
int version_number;
unsigned int min_life;
unsigned int max_pw_life;
unsigned int min_length;
unsigned int min_classes;
unsigned int history_num;
unsigned int refcount;
unsigned int max_fail;
unsigned int failcount_interval;
unsigned int lockout_duration;
unsigned int attributes;
unsigned int max_ticket_life;
unsigned int max_renewable_life;
nullstring allowed_keysalts;
int n_tl_data;
tl_data *tag_length_data;
};
The type "nullstring" uses the same custom encoder as in the
per-principal kadmin data.
The field "version_number" contains 0x12345D01, 0x12345D02, or
0x12345D03 for versions 1, 2, and 3 respectively. Versions 1 and 2
omit the fields "attributes" through "tag_length_data". Version 1
also omits the fields "max_fail" through "lockout_duration". Encoding
uses the lowest version that can represent the policy entry.
The field "refcount" is no longer used and its value is ignored.
LMDB principal and policy formats
---------------------------------
In the LMDB KDB module, principal entries are stored in the
"principal" database within the main LMDB environment (typically named
"principal.mdb"), with the exception of lockout-related fields which
are stored in the "lockout" table of the lockout LMDB environment
(typically named "principal.lockout.mdb"). For both databases the key
is the principal name in string form, with no zero terminator. Values
in the "principal" database use the following binary format with
little-endian integer encoding:
.. code-block:: bnf
lmdb-principal-entry ::=
attributes (32 bits)
max ticket lifetime (32 bits)
max renewable lifetime (32 bits)
principal expiration timestamp (32 bits)
password expiration timestamp (32 bits)
number of tag-length elements (16 bits)
number of key-data elements (16 bits)
tag-length entry 1 (tag-length-data)
tag-length entry 2 (tag-length-data)
...
key-data entry 1 (key-data)
key-data entry 2 (key-data)
...
tag-length-data ::=
type tag (16 bits)
data length (16 bits)
data value
key-data ::=
salt indicator (16 bits) [1 for default salt, 2 otherwise]
key version (16 bits)
encryption type (16 bits)
encrypted key length (16 bits)
encrypted key
salt type (16 bits) [omitted if salt indicator is 1]
salt data length (16 bits) [omitted if salt indicator is 1]
salt data [omitted if salt indicator is 1]
Values in the "lockout" database have the following binary format with
little-endian integer encoding:
.. code-block:: bnf
lmdb-lockout-entry ::=
last successful authentication timestamp (32 bits)
last failed authentication timestamp (32 bits)
failed authentication counter (32 bits)
In the "policy" database, the lookup key is the policy name with no
zero terminator. Values in this database use the following binary
format with little-endian integer encoding:
.. code-block:: bnf
lmdb-policy-entry ::=
minimum password lifetime (32 bits)
maximum password lifetime (32 bits)
minimum password length (32 bits)
minimum character classes (32 bits)
number of historical keys (32 bits)
maximum failed authentications before lockout (32 bits)
time interval to reset failed authentication counter (32 bits)
lockout duration (32 bits)
required principal attributes (32 bits) [currently unenforced]
maximum ticket lifetime (32 bits) [currently unenforced]
maximum renewable lifetime (32 bits) [currently unenforced]
allowed key/salt type specification length [32 bits]
allowed key/salt type specification
number of tag-length values (16 bits)
tag-length entry 1 (tag-length-data)
tag-length entry 2 (tag-length-data)
...
tag-length-data ::=
type tag (16 bits)
data length (16 bits)
data value
+1
View File
@@ -9,3 +9,4 @@ Protocols and file formats
rcache_file_format
cookie
freshness_token
database_formats
+1 -1
View File
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 9ca503a4e24138fa47d4451ee9426bb5
config: 62c817db4dbe5853c22bc095f98b965a
tags: 645f666f9bcd5a90fca523b33c5a78b7
@@ -460,6 +460,24 @@ This command requires the **add** and **delete** privileges.
Alias: **renprinc**
.. _add_alias:
add_alias
~~~~~~~~~
**add_alias** *alias_princ* *target_princ*
Create an alias *alias_princ* pointing to *target_princ*. Aliases may
be chained (that is, *target_princ* may itself be an alias) up to a
depth of 10.
This command requires the **add** privilege for *alias_princ* and the
**modify** privilege for *target_princ*.
(New in release 1.22.)
Aliases: **alias**
.. _delete_principal:
delete_principal
@@ -467,8 +485,8 @@ delete_principal
**delete_principal** [**-force**] *principal*
Deletes the specified *principal* from the database. This command
prompts for deletion, unless the **-force** option is given.
Deletes the specified *principal* or alias from the database. This
command prompts for deletion, unless the **-force** option is given.
This command requires the **delete** privilege.
@@ -121,6 +121,14 @@ ENVIRONMENT
See :ref:`kerberos(7)` for a description of Kerberos environment
variables.
As of release 1.22, kadmind supports systemd socket activation via the
LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by
the caller must correspond to configured listener addresses (via the
**kadmind_listen** or **kpasswd_listen** variables or equivalents) or
they will be ignored. Any configured listener addresses that do not
correspond to caller-provided sockets will be ignored if socket
activation is used.
SEE ALSO
--------
@@ -376,6 +376,14 @@ Options:
Dump types:
**alias**
principal alias information
**aliasname**
the name of the alias
**targetname**
the target of the alias
**keydata**
principal encryption key information, including actual key data
(which is still encrypted in the master key)
@@ -106,6 +106,13 @@ ENVIRONMENT
See :ref:`kerberos(7)` for a description of Kerberos environment
variables.
As of release 1.22, krb5kdc supports systemd socket activation via the
LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by
the caller must correspond to configured listener addresses (via the
**kdc_listen** variable or equivalent) or they will be ignored. Any
configured listener addresses that do not correspond to
caller-provided sockets will be ignored if socket activation is used.
SEE ALSO
--------
@@ -289,14 +289,16 @@ The following tags may be specified in a [realms] subsection:
**kadmind_listen**
(Whitespace- or comma-separated list.) Specifies the kadmin RPC
listening addresses and/or ports for the :ref:`kadmind(8)` daemon.
Each entry may be an interface address, a port number, or an
address and port number separated by a colon. If the address
contains colons, enclose it in square brackets. If no address is
specified, the wildcard address is used. If kadmind fails to bind
to any of the specified addresses, it will fail to start. The
default is to bind to the wildcard address at the port specified
in **kadmind_port**, or the standard kadmin port (749). New in
release 1.15.
Each entry may be an interface address, a port number, an address
and port number separated by a colon, or a UNIX domain socket
pathname. If the address contains colons, enclose it in square
brackets. If no address is specified, the wildcard address is
used. To disable listening for kadmin RPC connections, set this
relation to the empty string with ``kadmind_listen = ""``. If
kadmind fails to bind to any of the specified addresses, it will
fail to start. The default is to bind to the wildcard address at
the port specified in **kadmind_port**, or the standard kadmin
port (749). New in release 1.15.
**kadmind_port**
(Port number.) Specifies the port on which the :ref:`kadmind(8)`
@@ -310,16 +312,18 @@ The following tags may be specified in a [realms] subsection:
``/.k5.REALM``, where *REALM* is the Kerberos realm.
**kdc_listen**
(Whitespace- or comma-separated list.) Specifies the UDP
listening addresses and/or ports for the :ref:`krb5kdc(8)` daemon.
Each entry may be an interface address, a port number, or an
address and port number separated by a colon. If the address
contains colons, enclose it in square brackets. If no address is
specified, the wildcard address is used. If no port is specified,
the standard port (88) is used. If the KDC daemon fails to bind
to any of the specified addresses, it will fail to start. The
default is to bind to the wildcard address on the standard port.
New in release 1.15.
(Whitespace- or comma-separated list.) Specifies the listening
addresses and/or ports for the :ref:`krb5kdc(8)` daemon. Each
entry may be an interface address, a port number, an address and
port number separated by a colon, or a UNIX domain socket
pathname. If the address contains colons, enclose it in square
brackets. If no address is specified, the wildcard address is
used. If no port is specified, the standard port (88) is used.
To disable listening on UDP, set this relation to the empty string
with ``kdc_listen = ""``. If the KDC daemon fails to bind to any
of the specified addresses, it will fail to start. The default is
to bind to the wildcard address on the standard port. New in
release 1.15.
**kdc_ports**
(Whitespace- or comma-separated list, deprecated.) Prior to
@@ -331,15 +335,10 @@ The following tags may be specified in a [realms] subsection:
**kdc_tcp_listen**
(Whitespace- or comma-separated list.) Specifies the TCP
listening addresses and/or ports for the :ref:`krb5kdc(8)` daemon.
Each entry may be an interface address, a port number, or an
address and port number separated by a colon. If the address
contains colons, enclose it in square brackets. If no address is
specified, the wildcard address is used. If no port is specified,
the standard port (88) is used. To disable listening on TCP, set
this relation to the empty string with ``kdc_tcp_listen = ""``.
If the KDC daemon fails to bind to any of the specified addresses,
it will fail to start. The default is to bind to the wildcard
address on the standard port. New in release 1.15.
The syntax is identical to that of **kdc_listen**. To disable
listening on TCP, set this relation to the empty string with
``kdc_tcp_listen = ""``. The default is to bind to the same
addresses and ports as for UDP. New in release 1.15.
**kdc_tcp_ports**
(Whitespace- or comma-separated list, deprecated.) Prior to
@@ -349,15 +348,18 @@ The following tags may be specified in a [realms] subsection:
**kdc_tcp_listen** if that relation is not defined.
**kpasswd_listen**
(Comma-separated list.) Specifies the kpasswd listening addresses
and/or ports for the :ref:`kadmind(8)` daemon. Each entry may be
an interface address, a port number, or an address and port number
separated by a colon. If the address contains colons, enclose it
in square brackets. If no address is specified, the wildcard
address is used. If kadmind fails to bind to any of the specified
addresses, it will fail to start. The default is to bind to the
wildcard address at the port specified in **kpasswd_port**, or the
standard kpasswd port (464). New in release 1.15.
(Comma-separated list.) Specifies the kpasswd listening
addresses and/or ports for the :ref:`kadmind(8)` daemon. Each
entry may be an interface address, a port number, an address and
port number separated by a colon, or a UNIX domain socket
pathname. If the address contains colons, enclose it in square
brackets. If no address is specified, the wildcard address is
used. To disable listening for kpasswd requests, set this
relation to the empty string with ``kpasswd_listen = ""``. If
kadmind fails to bind to any of the specified addresses, it will
fail to start. The default is to bind to the wildcard address at
the port specified in **kpasswd_port**, or the standard kpasswd
port (464). New in release 1.15.
**kpasswd_port**
(Port number.) Specifies the port on which the :ref:`kadmind(8)`
@@ -768,8 +770,11 @@ For information about the syntax of some of these options, see
be specified multiple times.
**pkinit_dh_min_bits**
Specifies the minimum number of bits the KDC is willing to accept
for a client's Diffie-Hellman key. The default is 2048.
Specifies the minimum strength of Diffie-Hellman group the KDC is
willing to accept for key exchange. Valid values in order of
increasing strength are 1024, 2048, P-256, 4096, P-384, and P-521.
The default is 2048. (P-256, P-384, and P-521 are new in release
1.22.)
**pkinit_allow_upn**
Specifies that the KDC is willing to accept client certificates
@@ -35,12 +35,6 @@ or::
baz = quux
}
Placing a '\*' after the closing bracket of a section name indicates
that the section is *final*, meaning that if the same section appears
within a later file specified in **KRB5_CONFIG**, it will be ignored.
A subsection can be marked as final by placing a '\*' after either the
tag name or the closing brace.
The krb5.conf file can include other files using either of the
following directives at the beginning of a line::
@@ -58,6 +52,16 @@ section header. Starting in release 1.17, files are read in
alphanumeric order; in previous releases, they may be read in any
order.
Placing a '\*' after the closing bracket of a section name indicates
that the section is *final*, meaning that if the same section appears
again later, it will be ignored. A subsection can be marked as final
by placing a '\*' after either the tag name or the closing brace. A
relation can be marked as final by placing a '\*' after the tag name.
Prior to release 1.22, only sections and subsections can be marked as
final, and the flag only causes values to be ignored if they appear in
later files specified in **KRB5_CONFIG**, not if they appear later
within the same file or an included file.
The krb5.conf file can specify that configuration should be obtained
from a loadable module, rather than the file itself, using the
following directive at the beginning of a line before any section
@@ -221,6 +225,12 @@ The libdefaults section may contain any of the following relations:
data), and anything the fake KDC sends will not be trusted without
verification using some secret that it won't know.
**dns_lookup_realm**
Indicate whether DNS TXT records should be used to map hostnames
to realm names for hostnames not listed in the [domain_realm]
section, and to determine the default realm if **default_realm**
is not set. The default value is false.
**dns_uri_lookup**
Indicate whether DNS URI records should be used to locate the KDCs
and other servers for a realm, if they are not listed in the
@@ -362,6 +372,15 @@ The libdefaults section may contain any of the following relations:
(:ref:`duration` string.) Sets the default renewable lifetime
for initial ticket requests. The default value is 0.
**request_timeout**
(:ref:`duration` string.) Sets the maximum total time for KDC and
password change requests. This timeout does not affect the
intervals between requests, so setting a low timeout may result in
fewer requests being attempted and/or some servers not being
contacted. A value of 0 indicates no specific maximum, in which
case requests will time out if no server responds after several
tries. The default value is 0. (New in release 1.22.)
**spake_preauth_groups**
A whitespace or comma-separated list of words which specifies the
groups allowed for SPAKE preauthentication. The possible values
@@ -511,20 +530,21 @@ following tags may be specified in the realm's subsection:
been set to ``FILE:/tmp/my_proxy.pem``.
**kdc**
The name or address of a host running a KDC for that realm. An
optional port number, separated from the hostname by a colon, may
be included. If the name or address contains colons (for example,
if it is an IPv6 address), enclose it in square brackets to
The name or address of a host running a KDC for the realm, or a
UNIX domain socket path of a locally running KDC. An optional
port number, separated from the hostname by a colon, may be
included. If the name or address contains colons (for example, if
it is an IPv6 address), enclose it in square brackets to
distinguish the colon from a port separator. For your computer to
be able to communicate with the KDC for each realm, this tag must
be given a value in each realm subsection in the configuration
file, or there must be DNS SRV records specifying the KDCs.
**kpasswd_server**
Points to the server where all the password changes are performed.
If there is no such entry, DNS will be queried (unless forbidden
by **dns_lookup_kdc**). Finally, port 464 on the **admin_server**
host will be tried.
The location of the password change server for the realm, using
the same syntax as **kdc**. If there is no such entry, DNS will
be queried (unless forbidden by **dns_lookup_kdc**). Finally,
port 464 on the **admin_server** host will be tried.
**master_kdc**
The name for **primary_kdc** prior to release 1.19. Its value is
@@ -538,6 +558,10 @@ following tags may be specified in the realm's subsection:
the updated database has not been propagated to the replica
servers yet. New in release 1.19.
**sitename**
Specifies the name of the host's site for the purpose of DNS-based
KDC discovery for this realm. New in release 1.22.
**v4_instance_convert**
This subsection allows the administrator to configure exceptions
to the **default_domain** mapping rule. It contains V4 instances
@@ -1028,8 +1052,10 @@ information for PKINIT is as follows:
a particular smard card reader or token if there is more than one
available. ``certid=`` and/or ``certlabel=`` may be specified to
force the selection of a particular certificate on the device.
See the **pkinit_cert_match** configuration option for more ways
to select a particular certificate to use for PKINIT.
Specifier values must not contain colon characters, as colons are
always treated as separators. See the **pkinit_cert_match**
configuration option for more ways to select a particular
certificate to use for PKINIT.
**ENV:**\ *envvar*
*envvar* specifies the name of an environment variable which has
@@ -1128,9 +1154,10 @@ PKINIT krb5.conf options
option is not recommended.
**pkinit_dh_min_bits**
Specifies the size of the Diffie-Hellman key the client will
attempt to use. The acceptable values are 1024, 2048, and 4096.
The default is 2048.
Specifies the group of the Diffie-Hellman key the client will
attempt to use. The acceptable values are 1024, 2048, P-256,
4096, P-384, and P-521. The default is 2048. (P-256, P-384, and
P-521 are new in release 1.22.)
**pkinit_identities**
Specifies the location(s) to be used to find the user's X.509
@@ -112,9 +112,10 @@ Configuring Kerberos with OpenLDAP back-end
details.
With the LDAP back end it is possible to provide aliases for principal
entries. Currently we provide no administrative utilities for
creating aliases, so it must be done by direct manipulation of the
LDAP entries.
entries. Beginning in release 1.22, aliases can be added with the
kadmin **add_alias** command, but it is also possible (in release 1.7
or later) to provide aliases through direct manipulation of the LDAP
entries.
An entry with aliases contains multiple values of the
*krbPrincipalName* attribute. Since LDAP attribute values are not
@@ -93,6 +93,10 @@ To view the attributes of a principal, use the kadmin`
To generate a listing of principals, use the kadmin
**list_principals** command.
To give a principal additional names, use the kadmin **add_alias**
command to create aliases to the principal (new in release 1.22).
Aliases can be removed with the **delete_principal** command.
.. _policies:
@@ -196,6 +196,13 @@ using the **kdc**, **master_kdc**, **admin_server**, and
explicit server locations, providing SRV records will still benefit
unconfigured clients, and be useful for other sites.
Clients can be configured with the **sitename** realm variable (new in
release 1.22). If a site name is set, the client first attempts SRV
record lookups with ".*sitename*._sites" inserted after the service
and protocol name and before the Kerberos realm. Site-specific
records may indicate servers more proximal to the client, allowing for
faster access.
.. _kdc_discovery:
@@ -244,6 +251,9 @@ URI lookups are enabled by default, and can be disabled by setting
precedence over SRV lookups, falling back to SRV lookups if no URI
records are found.
The **sitename** variable in the :ref:`realms` section of
:ref:`krb5.conf(5)` applies to URI lookups as well as SRV lookups.
.. _db_prop:
@@ -424,6 +424,42 @@ set. If the library does not support the query,
gss_inquire_cred_by_oid will return **GSS_S_UNAVAILABLE**.
Channel binding behavior and GSS_C_CHANNEL_BOUND_FLAG
-----------------------------------------------------
GSSAPI channel bindings can be used to limit the scope of a context
establishment token to a particular protected channel or endpoint,
such as a TLS channel or server certificate. Channel bindings can be
supplied via the *input_chan_bindings* parameter to either
gss_init_sec_context() or gss_accept_sec_context().
If both the initiator and acceptor of a GSSAPI exchange supply
matching channel bindings, **GSS_C_CHANNEL_BOUND_FLAG** will be
included in the gss_accept_sec_context() *ret_flags* result. If
either the initiator or acceptor (or both) do not supply channel
bindings, the exchange will succeed, but **GSS_C_CHANNEL_BOUND_FLAG**
will not be included in the return flags. If the acceptor and
initiator both inlude channel bindings but they do not match, the
exchange will fail.
If **GSS_C_CHANNEL_BOUND_FLAG** is included in the *req_flags*
parameter of gss_init_sec_context(), the initiator will add the
Microsoft KERB_AP_OPTIONS_CBT extension to the Kerberos authenticator.
This extension requests that the acceptor strictly enforce channel
bindings, causing the exchange to fail if the acceptor supplies
channel bindings and the initiator does not. The KERB_AP_OPTIONS_CBT
extension will also be included if the
**client_aware_channel_bindings** variable is set to ``true`` in
:ref:`libdefaults`.
Prior to release 1.19, **GSS_C_CHANNEL_BOUND_FLAG** is not
implemented, and the exchange will fail if the acceptor supply channel
bindings and the initiator does not (but not vice versa). Between
releases 1.19 and 1.21, **GSS_C_CHANNEL_BOUND_FLAG** is not recognized
as an initiator flag, so **client_aware_channel_bindings** is the only
way to cause KERB_AP_OPTIONS_CBT to be included.
AEAD message wrapping
---------------------
@@ -25,6 +25,7 @@ Frequently used public interfaces
krb5_change_password.rst
krb5_chpw_message.rst
krb5_expand_hostname.rst
krb5_free_config_files.rst
krb5_free_context.rst
krb5_free_error_message.rst
krb5_free_principal.rst
@@ -33,6 +34,7 @@ Frequently used public interfaces
krb5_get_error_message.rst
krb5_get_host_realm.rst
krb5_get_credentials.rst
krb5_get_default_config_files.rst
krb5_get_fallback_host_realm.rst
krb5_get_init_creds_keytab.rst
krb5_get_init_creds_opt_alloc.rst
@@ -39,7 +39,7 @@ This function returns constant storage that must not be freed.
..
.. seealso::
#KRB5_ANONYMOUS_PRINCSTR
KRB5_ANONYMOUS_PRINCSTR
@@ -39,7 +39,7 @@ This function returns constant storage that must not be freed.
..
.. seealso::
#KRB5_ANONYMOUS_REALMSTR
KRB5_ANONYMOUS_REALMSTR
@@ -40,16 +40,16 @@ This function sets the local and/or remote addresses in *auth_context* based on
- #KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR Generate local address.
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR Generate local address.
- #KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR Generate remote address.
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR Generate remote address.
- #KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR Generate local address and port.
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR Generate local address and port.
- #KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR Generate remote address and port.
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR Generate remote address and port.
@@ -34,16 +34,16 @@ krb5_auth_con_getflags - Retrieve flags from a krb5_auth_context structure.
Valid values for *flags* are:
- #KRB5_AUTH_CONTEXT_DO_TIME Use timestamps
- KRB5_AUTH_CONTEXT_DO_TIME Use timestamps
- #KRB5_AUTH_CONTEXT_RET_TIME Save timestamps
- KRB5_AUTH_CONTEXT_RET_TIME Save timestamps
- #KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers
- KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers
- #KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers
- KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers
@@ -32,7 +32,7 @@ krb5_auth_con_getlocalseqnumber - Retrieve the local sequence number from an au
Retrieve the local sequence number from *auth_context* and return it in *seqnumber* . The #KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in *auth_context* for this function to be useful.
Retrieve the local sequence number from *auth_context* and return it in *seqnumber* . The KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in *auth_context* for this function to be useful.
@@ -32,7 +32,7 @@ krb5_auth_con_getremoteseqnumber - Retrieve the remote sequence number from an
Retrieve the remote sequence number from *auth_context* and return it in *seqnumber* . The #KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in *auth_context* for this function to be useful.
Retrieve the remote sequence number from *auth_context* and return it in *seqnumber* . The KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in *auth_context* for this function to be useful.
@@ -34,7 +34,7 @@ This function creates an authentication context to hold configuration and state
By default, flags for the context are set to enable the use of the replay cache (#KRB5_AUTH_CONTEXT_DO_TIME), but not sequence numbers. Use krb5_auth_con_setflags() to change the flags.
By default, flags for the context are set to enable the use of the replay cache (KRB5_AUTH_CONTEXT_DO_TIME), but not sequence numbers. Use krb5_auth_con_setflags() to change the flags.
@@ -34,16 +34,16 @@ krb5_auth_con_setflags - Set a flags field in a krb5_auth_context structure.
Valid values for *flags* are:
- #KRB5_AUTH_CONTEXT_DO_TIME Use timestamps
- KRB5_AUTH_CONTEXT_DO_TIME Use timestamps
- #KRB5_AUTH_CONTEXT_RET_TIME Save timestamps
- KRB5_AUTH_CONTEXT_RET_TIME Save timestamps
- #KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers
- KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers
- #KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers
- KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers
@@ -34,7 +34,7 @@ krb5_c_crypto_length_iov - Fill in lengths for header, trailer and padding in a
Padding is set to the actual padding required based on the provided *data* buffers. Typically this API is used after setting up the data buffers and #KRB5_CRYPTO_TYPE_SIGN_ONLY buffers, but before actually allocating header, trailer and padding.
Padding is set to the actual padding required based on the provided *data* buffers. Typically this API is used after setting up the data buffers and KRB5_CRYPTO_TYPE_SIGN_ONLY buffers, but before actually allocating header, trailer and padding.
@@ -38,7 +38,7 @@ krb5_c_encrypt - Encrypt data using a key (operates on keyblock).
This function encrypts the data block *input* and stores the outputinto *output* . The actual encryption key will be derived from *key* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation.
This function encrypts the data block *input* and stores the output into *output* . The actual encryption key will be derived from *key* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation.
@@ -38,7 +38,7 @@ krb5_c_make_checksum_iov - Fill in a checksum element in IOV array (operates on
Create a checksum in the #KRB5_CRYPTO_TYPE_CHECKSUM element over #KRB5_CRYPTO_TYPE_DATA and #KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in *data* . Only the #KRB5_CRYPTO_TYPE_CHECKSUM region is modified.
Create a checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element over KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in *data* . Only the KRB5_CRYPTO_TYPE_CHECKSUM region is modified.
@@ -40,7 +40,7 @@ krb5_c_verify_checksum_iov - Validate a checksum element in IOV array (operates
Confirm that the checksum in the #KRB5_CRYPTO_TYPE_CHECKSUM element is a valid checksum of the #KRB5_CRYPTO_TYPE_DATA and #KRB5_CRYPTO_TYPE_SIGN_ONLY regions in the iov.
Confirm that the checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element is a valid checksum of the KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY regions in the iov.
@@ -22,7 +22,7 @@ krb5_cc_cache_match - Find a credential cache with a specified client principal
:retval:
- 0 Success
- KRB5_CC_NOTFOUND None
- KRB5_CC_NOTFOUND
..
@@ -46,34 +46,34 @@ Valid values for *flags* are:
- #KRB5_TC_MATCH_TIMES The requested lifetime must be at least as great as in *mcreds* .
- KRB5_TC_MATCH_TIMES The requested lifetime must be at least as great as in *mcreds* .
- #KRB5_TC_MATCH_IS_SKEY The *is_skey* field much match exactly.
- KRB5_TC_MATCH_IS_SKEY The *is_skey* field much match exactly.
- #KRB5_TC_MATCH_FLAGS Flags set in *mcreds* must be set.
- KRB5_TC_MATCH_FLAGS Flags set in *mcreds* must be set.
- #KRB5_TC_MATCH_TIMES_EXACT The requested lifetime must match exactly.
- KRB5_TC_MATCH_TIMES_EXACT The requested lifetime must match exactly.
- #KRB5_TC_MATCH_FLAGS_EXACT Flags must match exactly.
- KRB5_TC_MATCH_FLAGS_EXACT Flags must match exactly.
- #KRB5_TC_MATCH_AUTHDATA The authorization data must match.
- KRB5_TC_MATCH_AUTHDATA The authorization data must match.
- #KRB5_TC_MATCH_SRV_NAMEONLY Only the name portion of the principal name must match, not the realm.
- KRB5_TC_MATCH_SRV_NAMEONLY Only the name portion of the principal name must match, not the realm.
- #KRB5_TC_MATCH_2ND_TKT The second tickets must match.
- KRB5_TC_MATCH_2ND_TKT The second tickets must match.
- #KRB5_TC_MATCH_KTYPE The encryption key types must match.
- KRB5_TC_MATCH_KTYPE The encryption key types must match.
- #KRB5_TC_SUPPORTED_KTYPES Check all matching entries that have any supported encryption type and return the one with the encryption type listed earliest.
- KRB5_TC_SUPPORTED_KTYPES Check all matching entries that have any supported encryption type and return the one with the encryption type listed earliest.
Use krb5_free_cred_contents() to free *creds* when it is no longer needed.
@@ -48,19 +48,19 @@ The possible values of the output *result_code* are:
- #KRB5_KPASSWD_SUCCESS (0) - success
- KRB5_KPASSWD_SUCCESS (0) - success
- #KRB5_KPASSWD_MALFORMED (1) - Malformed request error
- KRB5_KPASSWD_MALFORMED (1) - Malformed request error
- #KRB5_KPASSWD_HARDERROR (2) - Server error
- KRB5_KPASSWD_HARDERROR (2) - Server error
- #KRB5_KPASSWD_AUTHERROR (3) - Authentication error
- KRB5_KPASSWD_AUTHERROR (3) - Authentication error
- #KRB5_KPASSWD_SOFTERROR (4) - Password change rejected
- KRB5_KPASSWD_SOFTERROR (4) - Password change rejected
@@ -0,0 +1,44 @@
krb5_free_config_files - Free a list allocated by krb5_get_default_config_files()
===================================================================================
..
.. c:function:: void krb5_free_config_files(char ** filenames)
..
:param:
**[in]** **filenames** - Configuration filename list
..
..
..
.. note::
New in 1.22
@@ -49,7 +49,7 @@ krb5_fwd_tgt_creds - Get a forwarded TGT and format a KRB-CRED message.
Get a TGT for use at the remote host *rhost* and format it into a KRB-CRED message. If *rhost* is NULL and *server* is of type #KRB5_NT_SRV_HST, the second component of *server* will be used.
Get a TGT for use at the remote host *rhost* and format it into a KRB-CRED message. If *rhost* is NULL and *server* is of type KRB5_NT_SRV_HST, the second component of *server* will be used.
@@ -45,16 +45,16 @@ Use *ccache* or a TGS exchange to get a service ticket matching *in_creds* .
Valid values for *options* are:
- #KRB5_GC_CACHED Search only credential cache for the ticket
- KRB5_GC_CACHED Search only credential cache for the ticket
- #KRB5_GC_USER_USER Return a user to user authentication ticket
- KRB5_GC_USER_USER Return a user to user authentication ticket
*in_creds* must be non-null. *in_creds->client* and *in_creds->server* must be filled in to specify the client and the server respectively. If any authorization data needs to be requested for the service ticket (such as restrictions on how the ticket can be used), specify it in *in_creds->authdata* ; otherwise set *in_creds->authdata* to NULL. The session key type is specified in *in_creds->keyblock.enctype* , if it is nonzero.
The expiration date is specified in *in_creds->times.endtime* . The KDC may return tickets with an earlier expiration date. If *in_creds->times.endtime* is set to 0, the latest possible expiration date will be requested.
If *in_creds->times.endtime* is specified, it is used as the requested expiration date if a TGS request is made. If *in_creds->times.endtime* is set to 0, the latest possible expiration date will be requested. The KDC or cache may return a ticket with an earlier expiration date.
@@ -0,0 +1,52 @@
krb5_get_default_config_files - Return a list of default configuration filenames.
===================================================================================
..
.. c:function:: krb5_error_code krb5_get_default_config_files(char *** filenames)
..
:param:
**[out]** **filenames** - Configuration filename list
..
..
Fill in *filenames* with a null-terminated list of configuration files which will be read by krb5_init_context() in the current process environment.
Use krb5_free_config_files() to free *filenames* when it is no longer needed.
..
.. note::
New in 1.22
@@ -34,7 +34,7 @@ krb5_get_init_creds_opt_set_fast_flags - Set FAST flags in initial credential o
The following flag values are valid:
- #KRB5_FAST_REQUIRED - Require FAST to be used
- KRB5_FAST_REQUIRED - Require FAST to be used
@@ -18,7 +18,7 @@ krb5_get_prompt_types - Get prompt types array from a context.
:return:
- Pointer to an array of prompt types corresponding to the prompter's prompts arguments. Each type has one of the following values: #KRB5_PROMPT_TYPE_PASSWORD #KRB5_PROMPT_TYPE_NEW_PASSWORD #KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN #KRB5_PROMPT_TYPE_PREAUTH
- Pointer to an array of prompt types corresponding to the prompter's prompts arguments. Each type has one of the following values: KRB5_PROMPT_TYPE_PASSWORD KRB5_PROMPT_TYPE_NEW_PASSWORD KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN KRB5_PROMPT_TYPE_PREAUTH
..
@@ -35,10 +35,10 @@ Create a context structure, optionally using a specified profile and initializat
- #KRB5_INIT_CONTEXT_SECURE Ignore environment variables
- KRB5_INIT_CONTEXT_SECURE Ignore environment variables
- #KRB5_INIT_CONTEXT_KDC Use KDC configuration if creating profile
- KRB5_INIT_CONTEXT_KDC Use KDC configuration if creating profile
@@ -42,7 +42,7 @@ This function constructs the next KDC request in an initial credential exchange,
If more requests are needed, *flags* will be set to #KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in *out* . If no more requests are needed, *flags* will not contain #KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and *out* will be empty.
If more requests are needed, *flags* will be set to KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in *out* . If no more requests are needed, *flags* will not contain KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and *out* will be empty.
@@ -38,7 +38,7 @@ krb5_k_make_checksum_iov - Fill in a checksum element in IOV array (operates on
Create a checksum in the #KRB5_CRYPTO_TYPE_CHECKSUM element over #KRB5_CRYPTO_TYPE_DATA and #KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in *data* . Only the #KRB5_CRYPTO_TYPE_CHECKSUM region is modified.
Create a checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element over KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in *data* . Only the KRB5_CRYPTO_TYPE_CHECKSUM region is modified.
@@ -40,7 +40,7 @@ krb5_k_verify_checksum_iov - Validate a checksum element in IOV array (operates
Confirm that the checksum in the #KRB5_CRYPTO_TYPE_CHECKSUM element is a valid checksum of the #KRB5_CRYPTO_TYPE_DATA and #KRB5_CRYPTO_TYPE_SIGN_ONLY regions in the iov.
Confirm that the checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element is a valid checksum of the KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY regions in the iov.
@@ -49,11 +49,11 @@ The local and remote addresses in *auth_context* are optional; if either is spec
If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If #KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If #KRB5_AUTH_CONTEXT_RET_TIME is set in *auth_context* , the timestamp used for the KRB-CRED message is stored in *rdata_out* .
If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If KRB5_AUTH_CONTEXT_RET_TIME is set in *auth_context* , the timestamp used for the KRB-CRED message is stored in *rdata_out* .
If either #KRB5_AUTH_CONTEXT_DO_SEQUENCE or #KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the *auth_context* local sequence number is included in the KRB-CRED message and then incremented. If #KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in *rdata_out* .
If either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the *auth_context* local sequence number is included in the KRB-CRED message and then incremented. If KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in *rdata_out* .
@@ -81,7 +81,7 @@ The message will be encrypted using the send subkey of *auth_context* if it is p
.. note::
The *rdata_out* argument is required if the #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
@@ -44,11 +44,11 @@ The local address in *auth_context* must be set, and is used to form the sender
If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , a timestamp is included in the KRB-PRIV message, and an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If #KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If #KRB5_AUTH_CONTEXT_RET_TIME is set in *auth_context* , a timestamp is included in the KRB-PRIV message and is stored in *rdata_out* .
If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , a timestamp is included in the KRB-PRIV message, and an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If KRB5_AUTH_CONTEXT_RET_TIME is set in *auth_context* , a timestamp is included in the KRB-PRIV message and is stored in *rdata_out* .
If either #KRB5_AUTH_CONTEXT_DO_SEQUENCE or #KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the *auth_context* local sequence number is included in the KRB-PRIV message and then incremented. If #KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in *rdata_out* .
If either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the *auth_context* local sequence number is included in the KRB-PRIV message and then incremented. If KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in *rdata_out* .
@@ -72,7 +72,7 @@ Use krb5_free_data_contents() to free *der_out* when it is no longer needed.
.. note::
The *rdata_out* argument is required if the #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
@@ -36,7 +36,7 @@ This function fills in *outbuf* with an AP-REP message using information from *a
If the flags in *auth_context* indicate that a sequence number should be used (either #KRB5_AUTH_CONTEXT_DO_SEQUENCE or #KRB5_AUTH_CONTEXT_RET_SEQUENCE) and the local sequence number in *auth_context* is 0, a new number will be generated with krb5_generate_seq_number().
If the flags in *auth_context* indicate that a sequence number should be used (either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE) and the local sequence number in *auth_context* is 0, a new number will be generated with krb5_generate_seq_number().
@@ -40,13 +40,13 @@ krb5_mk_req_extended - Create a KRB_AP_REQ message using supplied credentials.
Valid *ap_req_options* are:
- #AP_OPTS_USE_SESSION_KEY - Use the session key when creating the request used for user to user authentication.
- AP_OPTS_USE_SESSION_KEY - Use the session key when creating the request used for user to user authentication.
- #AP_OPTS_MUTUAL_REQUIRED - Request a mutual authentication packet from the receiver.
- AP_OPTS_MUTUAL_REQUIRED - Request a mutual authentication packet from the receiver.
- #AP_OPTS_USE_SUBKEY - Generate a subsession key from the current session key obtained from the credentials.
- AP_OPTS_USE_SUBKEY - Generate a subsession key from the current session key obtained from the credentials.
This function creates a KRB_AP_REQ message using supplied credentials *in_creds* . *auth_context* may point to an existing auth context or to NULL, in which case a new one will be created. If *in_data* is non-null, a checksum of it will be included in the authenticator contained in the KRB_AP_REQ message. Use krb5_free_data_contents() to free *outbuf* when it is no longer needed.
@@ -48,11 +48,11 @@ The local address in *auth_context* must be set, and is used to form the sender
If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , a timestamp is included in the KRB-SAFE message, and an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If #KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If #KRB5_AUTH_CONTEXT_RET_TIME is set in *auth_context* , a timestamp is included in the KRB-SAFE message and is stored in *rdata_out* .
If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , a timestamp is included in the KRB-SAFE message, and an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If KRB5_AUTH_CONTEXT_RET_TIME is set in *auth_context* , a timestamp is included in the KRB-SAFE message and is stored in *rdata_out* .
If either #KRB5_AUTH_CONTEXT_DO_SEQUENCE or #KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the *auth_context* local sequence number is included in the KRB-SAFE message and then incremented. If #KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in *rdata_out* .
If either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the *auth_context* local sequence number is included in the KRB-SAFE message and then incremented. If KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in *rdata_out* .
@@ -76,7 +76,7 @@ Use krb5_free_data_contents() to free *der_out* when it is no longer needed.
.. note::
The *rdata_out* argument is required if the #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
@@ -40,25 +40,25 @@ This function adds a buffer of type *type* and contents *data* to *pac* if there
The valid values of *type* is one of the following:
- #KRB5_PAC_LOGON_INFO - Logon information
- KRB5_PAC_LOGON_INFO - Logon information
- #KRB5_PAC_CREDENTIALS_INFO - Credentials information
- KRB5_PAC_CREDENTIALS_INFO - Credentials information
- #KRB5_PAC_SERVER_CHECKSUM - Server checksum
- KRB5_PAC_SERVER_CHECKSUM - Server checksum
- #KRB5_PAC_PRIVSVR_CHECKSUM - KDC checksum
- KRB5_PAC_PRIVSVR_CHECKSUM - KDC checksum
- #KRB5_PAC_CLIENT_INFO - Client name and ticket information
- KRB5_PAC_CLIENT_INFO - Client name and ticket information
- #KRB5_PAC_DELEGATION_INFO - Constrained delegation information
- KRB5_PAC_DELEGATION_INFO - Constrained delegation information
- #KRB5_PAC_UPN_DNS_INFO - User principal name and DNS information
- KRB5_PAC_UPN_DNS_INFO - User principal name and DNS information
@@ -43,16 +43,16 @@ Similar to krb5_parse_name(), this function converts a single-string representat
The following flags are valid:
- #KRB5_PRINCIPAL_PARSE_NO_REALM - no realm must be present in *name*
- KRB5_PRINCIPAL_PARSE_NO_REALM - no realm must be present in *name*
- #KRB5_PRINCIPAL_PARSE_REQUIRE_REALM - realm must be present in *name*
- KRB5_PRINCIPAL_PARSE_REQUIRE_REALM - realm must be present in *name*
- #KRB5_PRINCIPAL_PARSE_ENTERPRISE - create single-component enterprise principal
- KRB5_PRINCIPAL_PARSE_ENTERPRISE - create single-component enterprise principal
- #KRB5_PRINCIPAL_PARSE_IGNORE_REALM - ignore realm if present in *name*
- KRB5_PRINCIPAL_PARSE_IGNORE_REALM - ignore realm if present in *name*
If **KRB5_PRINCIPAL_PARSE_NO_REALM** or **KRB5_PRINCIPAL_PARSE_IGNORE_REALM** is specified in *flags* , the realm of the new principal will be empty. Otherwise, the default realm for *context* will be used if *name* does not specify a realm.
@@ -36,16 +36,16 @@ krb5_principal_compare_flags - Compare two principals with additional flags.
Valid flags are:
- #KRB5_PRINCIPAL_COMPARE_IGNORE_REALM - ignore realm component
- KRB5_PRINCIPAL_COMPARE_IGNORE_REALM - ignore realm component
- #KRB5_PRINCIPAL_COMPARE_ENTERPRISE - UPNs as real principals
- KRB5_PRINCIPAL_COMPARE_ENTERPRISE - UPNs as real principals
- #KRB5_PRINCIPAL_COMPARE_CASEFOLD case-insensitive
- KRB5_PRINCIPAL_COMPARE_CASEFOLD case-insensitive
- #KRB5_PRINCIPAL_COMPARE_UTF8 - treat principals as UTF-8
- KRB5_PRINCIPAL_COMPARE_UTF8 - treat principals as UTF-8
@@ -60,7 +60,7 @@ Use krb5_free_tgt_creds() to free *creds_out* when it is no longer needed.
.. note::
The *rdata_out* argument is required if the #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .`
The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .`
@@ -44,11 +44,11 @@ If *auth_context* has a remote address set, the address will be used to verify t
If the #KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in *auth_context* , the sequence number of the KRB-PRIV message is checked against the remote sequence number field of *auth_context* . Otherwise, the sequence number is not used.
If the KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in *auth_context* , the sequence number of the KRB-PRIV message is checked against the remote sequence number field of *auth_context* . Otherwise, the sequence number is not used.
If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in-memory replay cache to detect reflections or replays.
If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in-memory replay cache to detect reflections or replays.
@@ -72,7 +72,7 @@ Use krb5_free_data_contents() to free *userdata_out* when it is no longer needed
.. note::
The *rdata_out* argument is required if the #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
@@ -82,7 +82,7 @@ Various other checks are performed on the decoded data, including cross-realm po
On success the authenticator, subkey, and remote sequence number of the request are stored in *auth_context* . If the #AP_OPTS_MUTUAL_REQUIRED bit is set, the local sequence number is XORed with the remote sequence number in the request.
On success the authenticator, subkey, and remote sequence number of the request are stored in *auth_context* . If the AP_OPTS_MUTUAL_REQUIRED bit is set, the local sequence number is XORed with the remote sequence number in the request.
@@ -44,11 +44,11 @@ If *auth_context* has a remote address set, the address will be used to verify t
If the #KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in *auth_context* , the sequence number of the KRB-SAFE message is checked against the remote sequence number field of *auth_context* . Otherwise, the sequence number is not used.
If the KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in *auth_context* , the sequence number of the KRB-SAFE message is checked against the remote sequence number field of *auth_context* . Otherwise, the sequence number is not used.
If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in-memory replay cache to detect reflections or replays.
If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in-memory replay cache to detect reflections or replays.
@@ -72,7 +72,7 @@ Use krb5_free_data_contents() to free *userdata_out* when it is no longer needed
.. note::
The *rdata_out* argument is required if the #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .
@@ -32,7 +32,7 @@ krb5_sendauth - Client function for sendauth protocol.
**[out]** **error** - If non-null, contains KRB_ERROR message returned from server
**[out]** **rep_result** - If non-null and *ap_req_options* is #AP_OPTS_MUTUAL_REQUIRED, contains the result of mutual authentication exchange
**[out]** **rep_result** - If non-null and *ap_req_options* is AP_OPTS_MUTUAL_REQUIRED, contains the result of mutual authentication exchange
**[out]** **out_creds** - If non-null, the retrieved credentials
@@ -29,7 +29,7 @@ krb5_set_password - Set a password for a principal using specified credentials.
:retval:
- 0 Success and result_code is set to #KRB5_KPASSWD_SUCCESS.
- 0 Success and result_code is set to KRB5_KPASSWD_SUCCESS.
:return:
@@ -32,7 +32,7 @@ krb5_sname_match - Test whether a principal matches a matching principal.
If *matching* is NULL, return TRUE. If *matching* is not a matching principal, return the value of krb5_principal_compare(context, matching, princ).
If *matching* is NULL, return TRUE. If *matching* is not a matching principal, return the value of krb5_principal_compare(context, matching,princ).
@@ -49,11 +49,11 @@ The *type* can be one of the following:
- #KRB5_NT_SRV_HST canonicalizes the host name before looking up the realm and generating the principal.
- KRB5_NT_SRV_HST canonicalizes the host name before looking up the realm and generating the principal.
- #KRB5_NT_UNKNOWN accepts the hostname as given, and does not canonicalize it.
- KRB5_NT_UNKNOWN accepts the hostname as given, and does not canonicalize it.
Use krb5_free_principal to free *ret_princ* when it is no longer needed.
@@ -42,7 +42,7 @@ This function constructs the next KDC request for a TGS exchange, allowing the c
If more requests are needed, *flags* will be set to #KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in *out* . If no more requests are needed, *flags* will not contain #KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and *out* will be empty.
If more requests are needed, *flags* will be set to KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in *out* . If no more requests are needed, *flags* will not contain KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and *out* will be empty.
@@ -43,13 +43,13 @@ Similar to krb5_unparse_name(), this function converts a krb5_principal structur
The following flags are valid:
- #KRB5_PRINCIPAL_UNPARSE_SHORT - omit realm if it is the local realm
- KRB5_PRINCIPAL_UNPARSE_SHORT - omit realm if it is the local realm
- #KRB5_PRINCIPAL_UNPARSE_NO_REALM - omit realm
- KRB5_PRINCIPAL_UNPARSE_NO_REALM - omit realm
- #KRB5_PRINCIPAL_UNPARSE_DISPLAY - do not quote special characters
- KRB5_PRINCIPAL_UNPARSE_DISPLAY - do not quote special characters
Use krb5_free_unparsed_name() to free *name* when it is no longer needed.
@@ -0,0 +1,17 @@
.. highlight:: c
.. _ADDRTYPE-DIRECTIONAL-data:
ADDRTYPE_DIRECTIONAL
====================
..
.. data:: ADDRTYPE_DIRECTIONAL
..
=========================== ======================
``ADDRTYPE_DIRECTIONAL`` ``0x0003``
=========================== ======================
@@ -0,0 +1,17 @@
.. highlight:: c
.. _ADDRTYPE-UNIXSOCK-data:
ADDRTYPE_UNIXSOCK
=================
..
.. data:: ADDRTYPE_UNIXSOCK
..
======================== ======================
``ADDRTYPE_UNIXSOCK`` ``(0x8000 | 0x0001)``
======================== ======================
@@ -0,0 +1,17 @@
.. highlight:: c
.. _AP-OPTS-CBT-FLAG-data:
AP_OPTS_CBT_FLAG
================
..
.. data:: AP_OPTS_CBT_FLAG
..
======================= ======================
``AP_OPTS_CBT_FLAG`` ``0x00000004 /* include KERB_AP_OPTIONS_CBT */``
======================= ======================
@@ -0,0 +1,17 @@
.. highlight:: c
.. _KRB5-KEYUSAGE-FINISHED-data:
KRB5_KEYUSAGE_FINISHED
======================
..
.. data:: KRB5_KEYUSAGE_FINISHED
..
============================= ======================
``KRB5_KEYUSAGE_FINISHED`` ``41``
============================= ======================
@@ -9,6 +9,7 @@ Public
ADDRTYPE_ADDRPORT.rst
ADDRTYPE_CHAOS.rst
ADDRTYPE_DIRECTIONAL.rst
ADDRTYPE_DDP.rst
ADDRTYPE_INET.rst
ADDRTYPE_INET6.rst
@@ -17,11 +18,13 @@ Public
ADDRTYPE_IS_LOCAL.rst
ADDRTYPE_NETBIOS.rst
ADDRTYPE_XNS.rst
ADDRTYPE_UNIXSOCK.rst
AD_TYPE_EXTERNAL.rst
AD_TYPE_FIELD_TYPE_MASK.rst
AD_TYPE_REGISTERED.rst
AD_TYPE_RESERVED.rst
AP_OPTS_ETYPE_NEGOTIATION.rst
AP_OPTS_CBT_FLAG.rst
AP_OPTS_MUTUAL_REQUIRED.rst
AP_OPTS_RESERVED.rst
AP_OPTS_USE_SESSION_KEY.rst
@@ -177,6 +180,7 @@ Public
KRB5_KEYUSAGE_GSS_TOK_MIC.rst
KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG.rst
KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV.rst
KRB5_KEYUSAGE_FINISHED.rst
KRB5_KEYUSAGE_IAKERB_FINISHED.rst
KRB5_KEYUSAGE_KDC_REP_TICKET.rst
KRB5_KEYUSAGE_KRB_CRED_ENCPART.rst
@@ -284,6 +284,9 @@ Optional features
given, it controls the -fsanitize compilation flag value (the
default is "address").
**-**\ **-enable-ossfuzz**
Enable building fuzzing targets with OSS-Fuzz build support.
Optional packages
-----------------
@@ -1,7 +1,7 @@
Copyright
=========
Copyright |copy| 1985-2024 by the Massachusetts Institute of
Copyright |copy| 1985-2025 by the Massachusetts Institute of
Technology and its contributors. All rights reserved.
See :ref:`mitK5license` for additional copyright and license
@@ -1,3 +1,5 @@
.. highlight:: abnf
KDC cookie format
=================
@@ -42,7 +44,9 @@ principal name with realm, marshalled according to :rfc:`1964` section
2.1.1.
The plain text of the encrypted part of a cookie is the DER encoding
of the following ASN.1 type::
of the following ASN.1 type:
.. code-block:: bnf
SecureCookie ::= SEQUENCE {
time INTEGER,
@@ -63,17 +67,27 @@ SPAKE cookie format (version 1)
-------------------------------
Inside the SecureCookie wrapper, a data value of type 151 contains
state for SPAKE pre-authentication. This data is the concatenation of
the following:
state for SPAKE pre-authentication. This data has the following
binary format with big-endian integer encoding:
* a two-byte big-endian version number with the value 1
* a two-byte big-endian stage number
* a four-byte big-endian group number
* a four-byte big-endian length and data for the SPAKE value
* a four-byte big-endian length and data for the transcript hash
* zero or more second factor records, each consisting of:
- a four-byte big-endian second-factor type
- a four-byte big-endian length and data
.. code-block:: bnf
cookie ::=
version (16 bits) [with the value 1]
stage number (16 bits)
group number (32 bits)
SPAKE value length (32 bits)
SPAKE value
transcript hash length (32 bits)
transcript hash
second factor record 1 (factor-record)
second factor record 2 (factor-record)
...
factor-record ::=
second factor type (32 bits)
second factor data length (32 bits)
second factor data
The stage value is 0 if the cookie was sent with a challenge message.
Otherwise it is 1 for the first encdata message sent by the KDC during
@@ -0,0 +1,459 @@
Kerberos Database (KDB) Formats
===============================
Dump format
-----------
Files created with the :ref:`kdb5_util(8)` **dump** command begin with
a versioned header "kdb5_util load_dump version 7". This version has
been in use since MIT krb5 release 1.11; some previous versions are
supported but are not described here.
Each subsequent line of the dump file contains one or more
tab-separated fields describing either a principal entry or a policy
entry. The fields of a principal entry line are:
* the word "princ"
* the string "38" (this was originally a length field)
* the length of the principal name in string form
* the decimal number of tag-length data elements
* the decimal number of key-data elements
* the string "0" (this was originally an extension length field)
* the principal name in string form
* the principal attributes as a decimal number; when converted to
binary, the bits from least significant to most significant are:
- disallow_postdated
- disallow_forwardable
- disallow_tgt_based
- disallow_renewable
- disallow_proxiable
- disallow_dup_skey
- disallow_all_tix
- requires_preauth
- requires_hwauth
- requires_pwchange
- disallow_svr
- pwchange_service
- support_desmd5
- new_princ
- ok_as_delegate
- ok_to_auth_as_delegate
- no_auth_data_required
- lockdown_keys
* the maximum ticket lifetime, as a decimal number of seconds
* the maximum renewable ticket lifetime, as a decimal number of seconds
* the principal expiration time, as a decimal POSIX timestamp
* the password expiration time, as a decimal POSIX timestamp
* the last successful authentication time, as a decimal POSIX
timestamp
* the last failed authentication time, as a decimal POSIX timestamp
* the decimal number of failed authentications since the last
successful authentication time
* for each tag-length data value:
- the tag value in decimal
- the length in decimal
- the data as a lowercase hexadecimal byte string, or "-1" if the length is 0
* for each key-data element:
- the string "2" if this element has non-normal salt type, "1"
otherwise
- the key version number of this element
- the encryption type
- the length of the encrypted key value
- the encrypted key as a lowercase hexadecimal byte string
- if this element has non-normal salt type:
- the salt type
- the length of the salt data
- the salt data as a lowercase hexadecimal byte string, or the
string "-1" if the salt data length is 0
* the string "-1;" (this was originally an extension field)
The fields of a policy entry line are:
* the string "policy"
* the policy name
* the minimum password lifetime as a decimal number of seconds
* the maximum password lifetime as a decimal number of seconds
* the minimum password length, in decimal
* the minimum number of character classes, in decimal
* the number of historical keys to be stored, in decimal
* the policy reference count (no longer used)
* the maximum number of failed authentications before lockout
* the time interval after which the failed authentication count is
reset, as a decimal number of seconds
* the lockout duration, as a decimal number of seconds
* the required principal attributes, in decimal (currently unenforced)
* the maximum ticket lifetime as a decimal number of seconds
(currently unenforced)
* the maximum renewable lifetime as a decimal number of seconds
(currently unenforced)
* the allowed key/salt types, or "-" if unrestricted
* the number of tag-length values
* for each tag-length data value:
- the tag value in decimal
- the length in decimal
- the data as a lowercase hexadecimal byte string, or "-1" if the
length is 0
Tag-length data formats
-----------------------
The currently defined tag-length data types are:
* (1) last password change: a four-byte little-endian POSIX timestamp
giving the last password change time
* (2) last modification data: a four-byte little-endian POSIX
timestamp followed by a zero-terminated principal name in string
form, giving the time of the last principal change and the principal
who performed it
* (3) kadmin data: the XDR encoding of a per-principal kadmin data
record (see below)
* (8) master key version: a two-byte little-endian integer containing
the master key version used to encrypt this principal's key data
* (9) active kvno: see below
* (10) master key auxiliary data: see below
* (11) string attributes: one or more iterations of a zero-terminated
string key followed by a zero-terminated string value
* (12) alias target principal: a zero-terminated principal name in
string form
* (255) LDAP object information: see below
* (768) referral padata: a DER-encoded PA-SVR-REFERRAL-DATA to be sent
to a TGS-REQ client within encrypted padata (see Appendix A of
:rfc:`1606`)
* (1792) last admin unlock: a four-byte little-endian POSIX timestamp
giving the time of the last administrative account unlock
* (32767) database arguments: a zero-terminated key=value string (may
appear multiple times); used by the kadmin protocol to
communicate -x arguments to kadmind
Per-principal kadmin data
~~~~~~~~~~~~~~~~~~~~~~~~~
Per-principal kadmin data records use a modified XDR encoding of the
kadmin_data type defined as follows:
.. code-block:: c
struct key_data {
int numfields;
unsigned int kvno;
int enctype;
int salttype;
unsigned int keylen;
unsigned int saltlen;
opaque key<>;
opaque salt<>;
};
struct hist_entry {
key_data keys<>;
};
struct kadmin_data {
int version_number;
nullstring policy;
int aux_attributes;
unsigned int old_key_next;
unsigned int admin_history_kvno;
hist_entry old_keysets<>;
};
The type "nullstring" uses a custom string encoder where the length
field is zero or the string length plus one; a length of zero
indicates that no policy object is specified for the principal. The
field "version_number" contains 0x12345C01. The aux_attributes field
contains the bit 0x800 if a policy object is associated with the
principal.
Within a key_data record, numfields is 2 if the key data has
non-normal salt type, 1 otherwise.
Active kvno and master key auxiliary data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These types only appear in the entry of the master key principal
(K/M). They use little-endian binary integer encoding.
The active kvno table determines which master key version is active
for a given timestamp. It uses the following binary format:
.. code-block:: bnf
active-key-version-table ::=
version (16 bits) [with the value 1]
version entry 1 (key-version-entry)
version entry 2 (key-version-entry)
...
key-version-entry ::=
key version (16 bits)
timestamp (32 bits) [when this key version becomes active]
The master key auxiliary data record contains copies of the current
master key encrypted in each older master key. It uses the following
binary format:
.. code-block:: bnf
master-key-aux ::=
version (16 bits) [with the value 1]
key entry 1 (key-entry)
key entry 2 (key-entry)
...
key-entry ::=
old master key version (16 bits)
latest master key version (16 bits)
latest master key encryption type (16 bits)
encrypted key length (16 bits)
encrypted key contents
LDAP object information
~~~~~~~~~~~~~~~~~~~~~~~
This type appears in principal entries retrieved with the LDAP KDB
module. The value uses the following binary format, using big-endian
integer encoding:
.. code-block:: bnf
ldap-principal-data ::=
record 1 (ldap-tl-data)
record 2 (ldap-tl-data)
...
ldap-tl-data ::=
type (8 bits)
length (16 bits)
data
The currently defined ldap-tl-data types are (all integers are
big-endian):
* (1) principal type: 16 bits containing the value 1, indicating that
the LDAP object containing the principal entry is a standalone
principal object
* (2) principal count: 16 bits containing the number of
krbPrincipalName values in the LDAP object
* (3) user DN: the string representation of the distinguished name of
the LDAP object
* (5) attribute mask: 16 bits indicating which Kerberos-specific LDAP
attributes are present in the LDAP object (see below)
* (7) link DN: the string representation of the distinguished name of
an LDAP object this object is linked to; may appear multiple times
When converted to binary, the attribute mask bits, from least
significant to most significant, correspond to the following LDAP
attributes:
* krbMaxTicketLife
* krbMaxRenewableAge
* krbTicketFlags
* krbPrincipalExpiration
* krbTicketPolicyReference
* krbPrincipalAuthInd
* krbPwdPolicyReference
* krbPasswordExpiration
* krbPrincipalKey
* krbLastPwdChange
* krbExtraData
* krbLastSuccessfulAuth
* krbLastFailedAuth
* krbLoginFailedCount
* krbLastAdminUnlock
* krbPwdHistory
Alias principal entries
-----------------------
To allow aliases to be represented in dump files and within the
incremental update protocol, the krb5 database library supports the
concept of an alias principal entry. An alias principal entry
contains an alias target principal in its tag-length data, has its
attributes set to disallow_all_tix, and has zero or empty values for
all other fields. The database glue library recognizes alias entries
and iteratively looks up the alias target up to a depth of 10 chained
aliases. (Added in release 1.22.)
DB2 principal and policy formats
--------------------------------
The DB2 KDB module uses the string form of a principal name, with zero
terminator, as a lookup key for principal entries. Principal entry
values use the following binary format with little-endian integer
encoding:
.. code-block:: bnf
db2-principal-entry ::=
len (16 bits) [always has the value 38]
attributes (32 bits)
max ticket lifetime (32 bits)
max renewable lifetime (32 bits)
principal expiration timestamp (32 bits)
password expiration timestamp (32 bits)
last successful authentication timestamp (32 bits)
last failed authentication timestamp (32 bits)
failed authentication counter (32 bits)
number of tag-length elements (16 bits)
number of key-data elements (16 bits)
length of string-form principal with zero terminator (16 bits)
string-form principal with zero terminator
tag-length entry 1 (tag-length-data)
tag-length entry 2 (tag-length-data)
...
key-data entry 1 (key-data)
key-data entry 2 (key-data)
...
tag-length-data ::=
type tag (16 bits)
data length (16 bits)
data
key-data ::=
salt indicator (16 bits) [1 for default salt, 2 otherwise]
key version (16 bits)
encryption type (16 bits)
encrypted key length (16 bits)
encrypted key
salt type (16 bits) [omitted if salt indicator is 1]
salt data length (16 bits) [omitted if salt indicator is 1]
salt data [omitted if salt indicator is 1]
DB2 policy entries reside in a separate database file. The lookup key
is the policy name with zero terminator. Policy entry values use a
modified XDR encoding of the policy type defined as follows:
.. code-block:: c
struct tl_data {
int type;
opaque data<>;
tl_data *next;
};
struct policy {
int version_number;
unsigned int min_life;
unsigned int max_pw_life;
unsigned int min_length;
unsigned int min_classes;
unsigned int history_num;
unsigned int refcount;
unsigned int max_fail;
unsigned int failcount_interval;
unsigned int lockout_duration;
unsigned int attributes;
unsigned int max_ticket_life;
unsigned int max_renewable_life;
nullstring allowed_keysalts;
int n_tl_data;
tl_data *tag_length_data;
};
The type "nullstring" uses the same custom encoder as in the
per-principal kadmin data.
The field "version_number" contains 0x12345D01, 0x12345D02, or
0x12345D03 for versions 1, 2, and 3 respectively. Versions 1 and 2
omit the fields "attributes" through "tag_length_data". Version 1
also omits the fields "max_fail" through "lockout_duration". Encoding
uses the lowest version that can represent the policy entry.
The field "refcount" is no longer used and its value is ignored.
LMDB principal and policy formats
---------------------------------
In the LMDB KDB module, principal entries are stored in the
"principal" database within the main LMDB environment (typically named
"principal.mdb"), with the exception of lockout-related fields which
are stored in the "lockout" table of the lockout LMDB environment
(typically named "principal.lockout.mdb"). For both databases the key
is the principal name in string form, with no zero terminator. Values
in the "principal" database use the following binary format with
little-endian integer encoding:
.. code-block:: bnf
lmdb-principal-entry ::=
attributes (32 bits)
max ticket lifetime (32 bits)
max renewable lifetime (32 bits)
principal expiration timestamp (32 bits)
password expiration timestamp (32 bits)
number of tag-length elements (16 bits)
number of key-data elements (16 bits)
tag-length entry 1 (tag-length-data)
tag-length entry 2 (tag-length-data)
...
key-data entry 1 (key-data)
key-data entry 2 (key-data)
...
tag-length-data ::=
type tag (16 bits)
data length (16 bits)
data value
key-data ::=
salt indicator (16 bits) [1 for default salt, 2 otherwise]
key version (16 bits)
encryption type (16 bits)
encrypted key length (16 bits)
encrypted key
salt type (16 bits) [omitted if salt indicator is 1]
salt data length (16 bits) [omitted if salt indicator is 1]
salt data [omitted if salt indicator is 1]
Values in the "lockout" database have the following binary format with
little-endian integer encoding:
.. code-block:: bnf
lmdb-lockout-entry ::=
last successful authentication timestamp (32 bits)
last failed authentication timestamp (32 bits)
failed authentication counter (32 bits)
In the "policy" database, the lookup key is the policy name with no
zero terminator. Values in this database use the following binary
format with little-endian integer encoding:
.. code-block:: bnf
lmdb-policy-entry ::=
minimum password lifetime (32 bits)
maximum password lifetime (32 bits)
minimum password length (32 bits)
minimum character classes (32 bits)
number of historical keys (32 bits)
maximum failed authentications before lockout (32 bits)
time interval to reset failed authentication counter (32 bits)
lockout duration (32 bits)
required principal attributes (32 bits) [currently unenforced]
maximum ticket lifetime (32 bits) [currently unenforced]
maximum renewable lifetime (32 bits) [currently unenforced]
allowed key/salt type specification length [32 bits]
allowed key/salt type specification
number of tag-length values (16 bits)
tag-length entry 1 (tag-length-data)
tag-length entry 2 (tag-length-data)
...
tag-length-data ::=
type tag (16 bits)
data length (16 bits)
data value
@@ -9,3 +9,4 @@ Protocols and file formats
rcache_file_format
cookie
freshness_token
database_formats
@@ -19,8 +19,8 @@ Quick facts
License - :ref:`mitK5license`
Releases:
- Latest stable: https://web.mit.edu/kerberos/krb5-1.20/
- Supported: https://web.mit.edu/kerberos/krb5-1.19/
- Latest stable: https://web.mit.edu/kerberos/krb5-1.22/
- Supported: https://web.mit.edu/kerberos/krb5-1.21/
- Release cycle: approximately 12 months
Supported platforms \/ OS distributions:
@@ -685,6 +685,69 @@ Release 1.21
- Improved the test framework's detection of memory errors in daemon
processes when used with asan.
Release 1.22
* User experience:
- The libdefaults configuration variable "request_timeout" can be
set to limit the total timeout for KDC requests. When making a
KDC request, the client will now wait indefinitely (or until the
request timeout has elapsed) on a KDC which accepts a TCP
connection, without contacting any additional KDCs. Clients will
make fewer DNS queries in some configurations.
- The realm configuration variable "sitename" can be set to cause
the client to query site-specific DNS records when making KDC
requests.
* Administrator experience:
- Principal aliases are supported in the DB2 and LMDB KDB modules
and in the kadmin protocol. (The LDAP KDB module has supported
aliases since release 1.7.)
- UNIX domain sockets are supported for the Kerberos and kpasswd
protocols.
- systemd socket activation is supported for krb5kdc and kadmind.
* Developer experience:
- KDB modules can be be implemented in terms of other modules using
the new krb5_db_load_module() function.
- The profile library supports the modification of empty profiles
and the copying of modified profiles, making it possible to
construct an in-memory profile and pass it to
krb5_init_context_profile().
- GSS-API applications can pass the GSS_C_CHANNEL_BOUND flag to
gss_init_sec_context() to request strict enforcement of channel
bindings by the acceptor.
* Protocol evolution:
- The PKINIT preauth module supports elliptic curve client
certificates, ECDH key exchange, and the Microsoft paChecksum2
field.
- The IAKERB implementation has been changed to comply with the most
recent draft standard and to support realm discovery.
- Message-Authenticator is supported in the RADIUS implementation
used by the OTP kdcpreauth module.
* Code quality:
- Removed old-style function declarations, to accomodate compilers
which have removed support for them.
- Added OSS-Fuzz to the project's continuous integration
infrastructure.
- Rewrote the GSS per-message token parsing code for improved
safety.
`Pre-authentication mechanisms`
- PW-SALT :rfc:`4120#section-5.2.7.3`
@@ -193,10 +193,6 @@ OPTIONS
**X509_anchors**\ =\ *value*
specify where to find trusted X509 anchor information
**flag_RSA_PROTOCOL**\ [**=yes**]
specify use of RSA, rather than the default Diffie-Hellman
protocol
**disable_freshness**\ [**=yes**]
disable sending freshness tokens (for testing purposes only)
+35 -18
View File
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- agogo theme.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@@ -19,6 +19,10 @@ body {
line-height: 1.4em;
color: black;
background-color: #5d1509;
/* fix for background colors breaking at horizontal
scrolling on smaller devices */
min-width: fit-content;
}
@@ -41,6 +45,10 @@ a {
color: #881f0d;
}
a:visited {
color: #551a8b;
}
div.bodywrapper a, div.footer a {
text-decoration: underline;
}
@@ -127,8 +135,7 @@ dt:target, .highlighted {
/* Header */
div.header {
padding-top: 10px;
padding-bottom: 10px;
padding: 1em;
}
div.header .headertitle {
@@ -165,8 +172,7 @@ img.logo {
/* Content */
div.content-wrapper {
background-color: white;
padding-top: 20px;
padding-bottom: 20px;
padding: 1em;
}
div.document {
@@ -267,32 +273,36 @@ div.document ol {
/* Sidebar */
div.sidebar {
div.sidebar,
aside.sidebar {
width: 20%;
float: right;
font-size: .9em;
}
div.sidebar a, div.header a {
div.sidebar a, aside.sidebar a, div.header a {
text-decoration: none;
}
div.sidebar a:hover, div.header a:hover {
div.sidebar a:hover, aside.sidebar a:hover, div.header a:hover {
text-decoration: underline;
}
div.sidebar h3 {
div.sidebar h3,
aside.sidebar h3 {
color: #2e3436;
text-transform: uppercase;
font-size: 130%;
letter-spacing: .1em;
}
div.sidebar ul {
div.sidebar ul,
aside.sidebar ul {
list-style-type: none;
}
div.sidebar li.toctree-l1 a {
div.sidebar li.toctree-l1 a,
aside.sidebar li.toctree-l1 a {
display: block;
padding: 1px;
border: 1px solid #dddddd;
@@ -302,37 +312,44 @@ div.sidebar li.toctree-l1 a {
color: #2e3436;
}
div.sidebar li.toctree-l2 a {
div.sidebar li.toctree-l2 a,
aside.sidebar li.toctree-l2 a {
background-color: transparent;
border: none;
margin-left: 1em;
border-bottom: 1px solid #dddddd;
}
div.sidebar li.toctree-l3 a {
div.sidebar li.toctree-l3 a,
aside.sidebar li.toctree-l3 a {
background-color: transparent;
border: none;
margin-left: 2em;
border-bottom: 1px solid #dddddd;
}
div.sidebar li.toctree-l2:last-child a {
div.sidebar li.toctree-l2:last-child a,
aside.sidebar li.toctree-l2:last-child a {
border-bottom: none;
}
div.sidebar li.toctree-l1.current a {
div.sidebar li.toctree-l1.current a,
aside.sidebar li.toctree-l1.current a {
border-right: 5px solid #fcaf3e;
}
div.sidebar li.toctree-l1.current li.toctree-l2 a {
div.sidebar li.toctree-l1.current li.toctree-l2 a,
aside.sidebar li.toctree-l1.current li.toctree-l2 a {
border-right: none;
}
div.sidebar input[type="text"] {
div.sidebar input[type="text"],
aside.sidebar input[type="text"] {
width: 170px;
}
div.sidebar input[type="submit"] {
div.sidebar input[type="submit"],
aside.sidebar input[type="submit"] {
width: 30px;
}
+47 -27
View File
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@@ -222,7 +222,7 @@ table.modindextable td {
/* -- general body styles --------------------------------------------------- */
div.body {
min-width: 450px;
min-width: 360px;
max-width: 800px;
}
@@ -237,14 +237,8 @@ a.headerlink {
visibility: hidden;
}
a.brackets:before,
span.brackets > a:before{
content: "[";
}
a.brackets:after,
span.brackets > a:after {
content: "]";
a:visited {
color: #551A8B;
}
h1:hover > a.headerlink,
@@ -335,12 +329,16 @@ p.sidebar-title {
font-weight: bold;
}
nav.contents,
aside.topic,
div.admonition, div.topic, blockquote {
clear: left;
}
/* -- topics ---------------------------------------------------------------- */
nav.contents,
aside.topic,
div.topic {
border: 1px solid #ccc;
padding: 7px;
@@ -379,6 +377,8 @@ div.body p.centered {
div.sidebar > :last-child,
aside.sidebar > :last-child,
nav.contents > :last-child,
aside.topic > :last-child,
div.topic > :last-child,
div.admonition > :last-child {
margin-bottom: 0;
@@ -386,6 +386,8 @@ div.admonition > :last-child {
div.sidebar::after,
aside.sidebar::after,
nav.contents::after,
aside.topic::after,
div.topic::after,
div.admonition::after,
blockquote::after {
@@ -428,10 +430,6 @@ table.docutils td, table.docutils th {
border-bottom: 1px solid #aaa;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
@@ -615,19 +613,26 @@ ul.simple p {
margin-bottom: 0;
}
dl.footnote > dt,
dl.citation > dt {
aside.footnote > span,
div.citation > span {
float: left;
margin-right: 0.5em;
}
dl.footnote > dd,
dl.citation > dd {
aside.footnote > span:last-of-type,
div.citation > span:last-of-type {
padding-right: 0.5em;
}
aside.footnote > p {
margin-left: 2em;
}
div.citation > p {
margin-left: 4em;
}
aside.footnote > p:last-of-type,
div.citation > p:last-of-type {
margin-bottom: 0em;
}
dl.footnote > dd:after,
dl.citation > dd:after {
aside.footnote > p:last-of-type:after,
div.citation > p:last-of-type:after {
content: "";
clear: both;
}
@@ -644,10 +649,6 @@ dl.field-list > dt {
padding-right: 5px;
}
dl.field-list > dt:after {
content: ":";
}
dl.field-list > dd {
padding-left: 0.5em;
margin-top: 0em;
@@ -673,6 +674,16 @@ dd {
margin-left: 30px;
}
.sig dd {
margin-top: 0px;
margin-bottom: 0px;
}
.sig dl {
margin-top: 0px;
margin-bottom: 0px;
}
dl > dd:last-child,
dl > dd:last-child > :last-child {
margin-bottom: 0;
@@ -741,6 +752,14 @@ abbr, acronym {
cursor: help;
}
.translated {
background-color: rgba(207, 255, 207, 0.2)
}
.untranslated {
background-color: rgba(255, 207, 207, 0.2)
}
/* -- code displays --------------------------------------------------------- */
pre {
@@ -757,6 +776,7 @@ span.pre {
-ms-hyphens: none;
-webkit-hyphens: none;
hyphens: none;
white-space: nowrap;
}
div[class*="highlight-"] {
+103 -270
View File
@@ -2,322 +2,155 @@
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
* Base JavaScript utilities for all Sphinx HTML documentation.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
"use strict";
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
"TEXTAREA",
"INPUT",
"SELECT",
"BUTTON",
]);
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
*/
jQuery.urldecode = function(x) {
if (!x) {
return x
const _ready = (callback) => {
if (document.readyState !== "loading") {
callback();
} else {
document.addEventListener("DOMContentLoaded", callback);
}
return decodeURIComponent(x.replace(/\+/g, ' '));
};
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
var bbox = node.parentElement.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this, addItems);
});
}
}
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};
/*
* backward compatibility for jQuery.browser
* This will be supported until firefox bug is fixed.
*/
if (!jQuery.browser) {
jQuery.uaMatch = function(ua) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
jQuery.browser = {};
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
}
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
this.initOnKeyListeners();
}
const Documentation = {
init: () => {
Documentation.initDomainIndexTable();
Documentation.initOnKeyListeners();
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
LOCALE : 'unknown',
TRANSLATIONS: {},
PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
LOCALE: "unknown",
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated === 'undefined')
return string;
return (typeof translated === 'string') ? translated : translated[0];
gettext: (string) => {
const translated = Documentation.TRANSLATIONS[string];
switch (typeof translated) {
case "undefined":
return string; // no translation
case "string":
return translated; // translation exists
default:
return translated[0]; // (singular, plural) translation tuple exists
}
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
ngettext: (singular, plural, n) => {
const translated = Documentation.TRANSLATIONS[singular];
if (typeof translated !== "undefined")
return translated[Documentation.PLURAL_EXPR(n)];
return n === 1 ? singular : plural;
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
addTranslations: (catalog) => {
Object.assign(Documentation.TRANSLATIONS, catalog.messages);
Documentation.PLURAL_EXPR = new Function(
"n",
`return (${catalog.plural_expr})`
);
Documentation.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
* helper function to focus on search bar
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
focusSearchBar: () => {
document.querySelectorAll("input[name=q]")[0]?.focus();
},
/**
* workaround a firefox stupidity
* see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
* Initialise the domain index toggle buttons
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
if (!body.length) {
body = $('body');
initDomainIndexTable: () => {
const toggler = (el) => {
const idNumber = el.id.substr(7);
const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
if (el.src.substr(-9) === "minus.png") {
el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
toggledRows.forEach((el) => (el.style.display = "none"));
} else {
el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
toggledRows.forEach((el) => (el.style.display = ""));
}
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
};
const togglerElements = document.querySelectorAll("img.toggler");
togglerElements.forEach((el) =>
el.addEventListener("click", (event) => toggler(event.currentTarget))
);
togglerElements.forEach((el) => (el.style.display = ""));
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
initOnKeyListeners: () => {
// only install a listener if it is really needed
if (
!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
)
return;
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
document.addEventListener("keydown", (event) => {
// bail for input elements
if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
// bail with special keys
if (event.altKey || event.ctrlKey || event.metaKey) return;
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
if (!event.shiftKey) {
switch (event.key) {
case "ArrowLeft":
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this === '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
},
initOnKeyListeners: function() {
$(document).keydown(function(event) {
var activeElementType = document.activeElement.tagName;
// don't navigate when in search box, textarea, dropdown or button
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
&& activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey
&& !event.shiftKey) {
switch (event.keyCode) {
case 37: // left
var prevHref = $('link[rel="prev"]').prop('href');
if (prevHref) {
window.location.href = prevHref;
return false;
const prevLink = document.querySelector('link[rel="prev"]');
if (prevLink && prevLink.href) {
window.location.href = prevLink.href;
event.preventDefault();
}
break;
case 39: // right
var nextHref = $('link[rel="next"]').prop('href');
if (nextHref) {
window.location.href = nextHref;
return false;
case "ArrowRight":
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
const nextLink = document.querySelector('link[rel="next"]');
if (nextLink && nextLink.href) {
window.location.href = nextLink.href;
event.preventDefault();
}
break;
}
}
// some keyboard layouts may need Shift to get /
switch (event.key) {
case "/":
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
Documentation.focusSearchBar();
event.preventDefault();
}
});
}
},
};
// quick alias for translations
_ = Documentation.gettext;
const _ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});
_ready(Documentation.init);
@@ -1,12 +1,13 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '1.21.3',
LANGUAGE: 'None',
const DOCUMENTATION_OPTIONS = {
VERSION: '1.22-final',
LANGUAGE: 'en',
COLLAPSE_INDEX: false,
BUILDER: 'html',
FILE_SUFFIX: '.html',
LINK_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false
NAVIGATION_WITH_KEYS: false,
SHOW_SEARCH_SUMMARY: true,
ENABLE_SEARCH_SHORTCUTS: true,
};
File diff suppressed because it is too large. Load diff
+2 -100
View File
@@ -5,12 +5,12 @@
* This script contains the language-specific data used by searchtools.js,
* namely the list of stopwords, stemmer, scorer and splitter.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
/* Non-minified version is copied as a separate JS file, is available */
@@ -197,101 +197,3 @@ var Stemmer = function() {
}
}
var splitChars = (function() {
var result = {};
var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
var i, j, start, end;
for (i = 0; i < singles.length; i++) {
result[singles[i]] = true;
}
var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
[722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
[1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
[1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
[1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
[2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
[2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
[2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
[2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
[2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
[2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
[2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
[3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
[3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
[3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
[3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
[3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
[3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
[4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
[4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
[4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
[4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
[5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
[6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
[6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
[6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
[6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
[7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
[7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
[8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
[8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
[8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
[10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
[11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
[12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
[12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
[12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
[19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
[42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
[42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
[43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
[43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
[43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
[43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
[44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
[57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
[64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
[65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
[65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
for (i = 0; i < ranges.length; i++) {
start = ranges[i][0];
end = ranges[i][1];
for (j = start; j <= end; j++) {
result[j] = true;
}
}
return result;
})();
function splitQuery(query) {
var result = [];
var start = -1;
for (var i = 0; i < query.length; i++) {
if (splitChars[query.charCodeAt(i)]) {
if (start !== -1) {
result.push(query.slice(start, i));
start = -1;
}
} else if (start === -1) {
start = i;
}
}
if (start !== -1) {
result.push(query.slice(start));
}
return result;
}
@@ -17,6 +17,7 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left:
.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
+435 -389
View File
@@ -4,22 +4,24 @@
*
* Sphinx JavaScript utilities for the full-text search.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
"use strict";
if (!Scorer) {
/**
* Simple result scoring code.
*/
/**
* Simple result scoring code.
*/
if (typeof Scorer === "undefined") {
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// The function takes a result array [docname, title, anchor, descr, score, filename]
// and returns the new score.
/*
score: function(result) {
return result[4];
score: result => {
const [docname, title, anchor, descr, score, filename] = result
return score
},
*/
@@ -28,9 +30,11 @@ if (!Scorer) {
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
objPrio: {
0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5, // used to be unimportantResults
},
// Used when the priority is not in the mapping.
objPrioDefault: 0,
@@ -39,459 +43,507 @@ if (!Scorer) {
partialTitle: 7,
// query found in terms
term: 5,
partialTerm: 2
partialTerm: 2,
};
}
if (!splitQuery) {
function splitQuery(query) {
return query.split(/\s+/);
const _removeChildren = (element) => {
while (element && element.lastChild) element.removeChild(element.lastChild);
};
/**
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
*/
const _escapeRegExp = (string) =>
string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
const _displayItem = (item, searchTerms, highlightTerms) => {
const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
const contentRoot = document.documentElement.dataset.content_root
?? DOCUMENTATION_OPTIONS.URL_ROOT;
const [docName, title, anchor, descr, score, _filename] = item;
let listItem = document.createElement("li");
let requestUrl;
let linkUrl;
if (docBuilder === "dirhtml") {
// dirhtml builder
let dirname = docName + "/";
if (dirname.match(/\/index\/$/))
dirname = dirname.substring(0, dirname.length - 6);
else if (dirname === "index/") dirname = "";
requestUrl = contentRoot + dirname;
linkUrl = requestUrl;
} else {
// normal html builders
requestUrl = contentRoot + docName + docFileSuffix;
linkUrl = docName + docLinkSuffix;
}
let linkEl = listItem.appendChild(document.createElement("a"));
linkEl.href = linkUrl + anchor;
linkEl.dataset.score = score;
linkEl.innerHTML = title;
if (descr) {
listItem.appendChild(document.createElement("span")).innerHTML =
" (" + descr + ")";
// highlight search terms in the description
if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
}
else if (showSearchSummary)
fetch(requestUrl)
.then((responseData) => responseData.text())
.then((data) => {
if (data)
listItem.appendChild(
Search.makeSearchSummary(data, searchTerms)
);
// highlight search terms in the summary
if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
});
Search.output.appendChild(listItem);
};
const _finishSearch = (resultCount) => {
Search.stopPulse();
Search.title.innerText = _("Search Results");
if (!resultCount)
Search.status.innerText = Documentation.gettext(
"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
);
else
Search.status.innerText = _(
`Search finished, found ${resultCount} page(s) matching the search query.`
);
};
const _displayNextItem = (
results,
resultCount,
searchTerms,
highlightTerms,
) => {
// results left, load the summary and display it
// this is intended to be dynamic (don't sub resultsCount)
if (results.length) {
_displayItem(results.pop(), searchTerms, highlightTerms);
setTimeout(
() => _displayNextItem(results, resultCount, searchTerms, highlightTerms),
5
);
}
// search finished, update title and status message
else _finishSearch(resultCount);
};
/**
* Default splitQuery function. Can be overridden in ``sphinx.search`` with a
* custom function per language.
*
* The regular expression works by splitting the string on consecutive characters
* that are not Unicode letters, numbers, underscores, or emoji characters.
* This is the same as ``\W+`` in Python, preserving the surrogate pair area.
*/
if (typeof splitQuery === "undefined") {
var splitQuery = (query) => query
.split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
.filter(term => term) // remove remaining empty strings
}
/**
* Search Module
*/
var Search = {
const Search = {
_index: null,
_queued_query: null,
_pulse_status: -1,
_index : null,
_queued_query : null,
_pulse_status : -1,
htmlToText : function(htmlString) {
var virtualDocument = document.implementation.createHTMLDocument('virtual');
var htmlElement = $(htmlString, virtualDocument);
htmlElement.find('.headerlink').remove();
docContent = htmlElement.find('[role=main]')[0];
if(docContent === undefined) {
console.warn("Content block not found. Sphinx search tries to obtain it " +
"via '[role=main]'. Could you check your theme or template.");
return "";
}
return docContent.textContent || docContent.innerText;
htmlToText: (htmlString) => {
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
const docContent = htmlElement.querySelector('[role="main"]');
if (docContent !== undefined) return docContent.textContent;
console.warn(
"Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
);
return "";
},
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
init: () => {
const query = new URLSearchParams(window.location.search).get("q");
document
.querySelectorAll('input[name="q"]')
.forEach((el) => (el.value = query));
if (query) Search.performSearch(query);
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null,
dataType: "script", cache: true,
complete: function(jqxhr, textstatus) {
if (textstatus != "success") {
document.getElementById("searchindexloader").src = url;
}
}});
},
loadIndex: (url) =>
(document.body.appendChild(document.createElement("script")).src = url),
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
setIndex: (index) => {
Search._index = index;
if (Search._queued_query !== null) {
const query = Search._queued_query;
Search._queued_query = null;
Search.query(query);
}
},
hasIndex : function() {
return this._index !== null;
},
hasIndex: () => Search._index !== null,
deferQuery : function(query) {
this._queued_query = query;
},
deferQuery: (query) => (Search._queued_query = query),
stopPulse : function() {
this._pulse_status = 0;
},
stopPulse: () => (Search._pulse_status = -1),
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
var i;
startPulse: () => {
if (Search._pulse_status >= 0) return;
const pulse = () => {
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
}
Search.dots.innerText = ".".repeat(Search._pulse_status);
if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
};
pulse();
},
/**
* perform a search for something (or wait until index is loaded)
*/
performSearch : function(query) {
performSearch: (query) => {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p class="search-summary">&nbsp;</p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
const searchText = document.createElement("h2");
searchText.textContent = _("Searching");
const searchSummary = document.createElement("p");
searchSummary.classList.add("search-summary");
searchSummary.innerText = "";
const searchList = document.createElement("ul");
searchList.classList.add("search");
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
const out = document.getElementById("search-results");
Search.title = out.appendChild(searchText);
Search.dots = Search.title.appendChild(document.createElement("span"));
Search.status = out.appendChild(searchSummary);
Search.output = out.appendChild(searchList);
const searchProgress = document.getElementById("search-progress");
// Some themes don't use the search progress node
if (searchProgress) {
searchProgress.innerText = _("Preparing search...");
}
Search.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
if (Search.hasIndex()) Search.query(query);
else Search.deferQuery(query);
},
/**
* execute search (requires search index to be loaded)
*/
query : function(query) {
var i;
query: (query) => {
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const titles = Search._index.titles;
const allTitles = Search._index.alltitles;
const indexEntries = Search._index.indexentries;
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = splitQuery(query);
var objectterms = [];
for (i = 0; i < tmp.length; i++) {
if (tmp[i] !== "") {
objectterms.push(tmp[i].toLowerCase());
}
// stem the search terms and add them to the correct list
const stemmer = new Stemmer();
const searchTerms = new Set();
const excludedTerms = new Set();
const highlightTerms = new Set();
const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
splitQuery(query.trim()).forEach((queryTerm) => {
const queryTermLower = queryTerm.toLowerCase();
// maybe skip this "word"
// stopwords array is from language_data.js
if (
stopwords.indexOf(queryTermLower) !== -1 ||
queryTerm.match(/^\d+$/)
)
return;
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i].toLowerCase());
// prevent stemmer from cutting word smaller than two chars
if(word.length < 3 && tmp[i].length >= 3) {
word = tmp[i];
}
var toAppend;
let word = stemmer.stemWord(queryTermLower);
// select the correct list
if (word[0] == '-') {
toAppend = excluded;
word = word.substr(1);
}
if (word[0] === "-") excludedTerms.add(word.substr(1));
else {
toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
searchTerms.add(word);
highlightTerms.add(queryTermLower);
}
// only add if not already in the list
if (!$u.contains(toAppend, word))
toAppend.push(word);
});
if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js
localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" "))
}
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// console.debug("SEARCH: searching for:");
// console.info("required: ", [...searchTerms]);
// console.info("excluded: ", [...excludedTerms]);
// prepare search
var terms = this._index.terms;
var titleterms = this._index.titleterms;
// array of [docname, title, anchor, descr, score, filename]
let results = [];
_removeChildren(document.getElementById("search-progress"));
// array of [filename, title, anchor, descr, score]
var results = [];
$('#search-progress').empty();
const queryLower = query.toLowerCase();
for (const [title, foundTitles] of Object.entries(allTitles)) {
if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) {
for (const [file, id] of foundTitles) {
let score = Math.round(100 * queryLower.length / title.length)
results.push([
docNames[file],
titles[file] !== title ? `${titles[file]} > ${title}` : title,
id !== null ? "#" + id : "",
null,
score,
filenames[file],
]);
}
}
}
// search for explicit entries in index directives
for (const [entry, foundEntries] of Object.entries(indexEntries)) {
if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {
for (const [file, id] of foundEntries) {
let score = Math.round(100 * queryLower.length / entry.length)
results.push([
docNames[file],
titles[file],
id ? "#" + id : "",
null,
score,
filenames[file],
]);
}
}
}
// lookup as object
for (i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0, i),
objectterms.slice(i+1, objectterms.length));
results = results.concat(this.performObjectSearch(objectterms[i], others));
}
objectTerms.forEach((term) =>
results.push(...Search.performObjectSearch(term, objectTerms))
);
// lookup as search terms in fulltext
results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
results.push(...Search.performTermsSearch(searchTerms, excludedTerms));
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
for (i = 0; i < results.length; i++)
results[i][4] = Scorer.score(results[i]);
}
if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item)));
// now sort the results by score (in opposite order of appearance, since the
// display function below uses pop() to retrieve items) and then
// alphabetically
results.sort(function(a, b) {
var left = a[4];
var right = b[4];
if (left > right) {
return 1;
} else if (left < right) {
return -1;
} else {
results.sort((a, b) => {
const leftScore = a[4];
const rightScore = b[4];
if (leftScore === rightScore) {
// same score: sort alphabetically
left = a[1].toLowerCase();
right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
const leftTitle = a[1].toLowerCase();
const rightTitle = b[1].toLowerCase();
if (leftTitle === rightTitle) return 0;
return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
}
return leftScore > rightScore ? 1 : -1;
});
// remove duplicate search results
// note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
let seen = new Set();
results = results.reverse().reduce((acc, result) => {
let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
if (!seen.has(resultStr)) {
acc.push(result);
seen.add(resultStr);
}
return acc;
}, []);
results = results.reverse();
// for debugging
//Search.lastresults = results.slice(); // a copy
//console.info('search results:', Search.lastresults);
// console.info("search results:", Search.lastresults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li></li>');
var requestUrl = "";
var linkUrl = "";
if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;
linkUrl = requestUrl;
} else {
// normal html builders
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;
linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX;
}
listItem.append($('<a/>').attr('href',
linkUrl +
highlightstring + item[2]).html(item[1]));
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.ajax({url: requestUrl,
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
if (data !== '' && data !== undefined) {
var summary = Search.makeSearchSummary(data, searchterms, hlterms);
if (summary) {
listItem.append(summary);
}
}
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
}});
} else {
// no source available, just display title
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
_displayNextItem(results, results.length, searchTerms, highlightTerms);
},
/**
* search for object names
*/
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var docnames = this._index.docnames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
performObjectSearch: (object, objectTerms) => {
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const objects = Search._index.objects;
const objNames = Search._index.objnames;
const titles = Search._index.titles;
var i;
var results = [];
const results = [];
for (var prefix in objects) {
const objectSearchCallback = (prefix, match) => {
const name = match[4]
const fullname = (prefix ? prefix + "." : "") + name;
const fullnameLower = fullname.toLowerCase();
if (fullnameLower.indexOf(object) < 0) return;
let score = 0;
const parts = fullnameLower.split(".");
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullnameLower === object || parts.slice(-1)[0] === object)
score += Scorer.objNameMatch;
else if (parts.slice(-1)[0].indexOf(object) > -1)
score += Scorer.objPartialMatch; // matches in last name
const objName = objNames[match[1]][2];
const title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
const otherTerms = new Set(objectTerms);
otherTerms.delete(object);
if (otherTerms.size > 0) {
const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
if (
[...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
)
return;
}
let anchor = match[3];
if (anchor === "") anchor = fullname;
else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
const descr = objName + _(", in ") + title;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2]))
score += Scorer.objPrio[match[2]];
else score += Scorer.objPrioDefault;
results.push([
docNames[match[0]],
fullname,
"#" + anchor,
descr,
score,
filenames[match[0]],
]);
};
Object.keys(objects).forEach((prefix) => {
if (!(objects[prefix] instanceof Array)) {
objects[prefix] = Object.entries(objects[prefix]).map(([name, match]) => [...match, name]);
}
for (var iMatch = 0; iMatch != objects[prefix].length; ++iMatch) {
var match = objects[prefix][iMatch];
var name = match[4];
var fullname = (prefix ? prefix + '.' : '') + name;
var fullnameLower = fullname.toLowerCase()
if (fullnameLower.indexOf(object) > -1) {
var score = 0;
var parts = fullnameLower.split('.');
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullnameLower == object || parts[parts.length - 1] == object) {
score += Scorer.objNameMatch;
// matches in last name
} else if (parts[parts.length - 1].indexOf(object) > -1) {
score += Scorer.objPartialMatch;
}
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
var anchor = match[3];
if (anchor === '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2])) {
score += Scorer.objPrio[match[2]];
} else {
score += Scorer.objPrioDefault;
}
results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
}
}
}
objects[prefix].forEach((array) =>
objectSearchCallback(prefix, array)
);
});
return results;
},
/**
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
*/
escapeRegExp : function(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
},
/**
* search for full-text terms in the index
*/
performTermsSearch : function(searchterms, excluded, terms, titleterms) {
var docnames = this._index.docnames;
var filenames = this._index.filenames;
var titles = this._index.titles;
performTermsSearch: (searchTerms, excludedTerms) => {
// prepare search
const terms = Search._index.terms;
const titleTerms = Search._index.titleterms;
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const titles = Search._index.titles;
var i, j, file;
var fileMap = {};
var scoreMap = {};
var results = [];
const scoreMap = new Map();
const fileMap = new Map();
// perform the search on the required terms
for (i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
var files = [];
var _o = [
{files: terms[word], score: Scorer.term},
{files: titleterms[word], score: Scorer.title}
searchTerms.forEach((word) => {
const files = [];
const arr = [
{ files: terms[word], score: Scorer.term },
{ files: titleTerms[word], score: Scorer.title },
];
// add support for partial matches
if (word.length > 2) {
var word_regex = this.escapeRegExp(word);
for (var w in terms) {
if (w.match(word_regex) && !terms[word]) {
_o.push({files: terms[w], score: Scorer.partialTerm})
}
}
for (var w in titleterms) {
if (w.match(word_regex) && !titleterms[word]) {
_o.push({files: titleterms[w], score: Scorer.partialTitle})
}
}
const escapedWord = _escapeRegExp(word);
Object.keys(terms).forEach((term) => {
if (term.match(escapedWord) && !terms[word])
arr.push({ files: terms[term], score: Scorer.partialTerm });
});
Object.keys(titleTerms).forEach((term) => {
if (term.match(escapedWord) && !titleTerms[word])
arr.push({ files: titleTerms[word], score: Scorer.partialTitle });
});
}
// no match but word was a required one
if ($u.every(_o, function(o){return o.files === undefined;})) {
break;
}
if (arr.every((record) => record.files === undefined)) return;
// found search word in contents
$u.each(_o, function(o) {
var _files = o.files;
if (_files === undefined)
return
arr.forEach((record) => {
if (record.files === undefined) return;
if (_files.length === undefined)
_files = [_files];
files = files.concat(_files);
let recordFiles = record.files;
if (recordFiles.length === undefined) recordFiles = [recordFiles];
files.push(...recordFiles);
// set score for the word in each file to Scorer.term
for (j = 0; j < _files.length; j++) {
file = _files[j];
if (!(file in scoreMap))
scoreMap[file] = {};
scoreMap[file][word] = o.score;
}
// set score for the word in each file
recordFiles.forEach((file) => {
if (!scoreMap.has(file)) scoreMap.set(file, {});
scoreMap.get(file)[word] = record.score;
});
});
// create the mapping
for (j = 0; j < files.length; j++) {
file = files[j];
if (file in fileMap && fileMap[file].indexOf(word) === -1)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
files.forEach((file) => {
if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1)
fileMap.get(file).push(word);
else fileMap.set(file, [word]);
});
});
// now check if the files don't contain excluded terms
for (file in fileMap) {
var valid = true;
const results = [];
for (const [file, wordList] of fileMap) {
// check if all requirements are matched
var filteredTermCount = // as search terms with length < 3 are discarded: ignore
searchterms.filter(function(term){return term.length > 2}).length
// as search terms with length < 3 are discarded
const filteredTermCount = [...searchTerms].filter(
(term) => term.length > 2
).length;
if (
fileMap[file].length != searchterms.length &&
fileMap[file].length != filteredTermCount
) continue;
wordList.length !== searchTerms.size &&
wordList.length !== filteredTermCount
)
continue;
// ensure that none of the excluded terms is in the search result
for (i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
titleterms[excluded[i]] == file ||
$u.contains(terms[excluded[i]] || [], file) ||
$u.contains(titleterms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
if (
[...excludedTerms].some(
(term) =>
terms[term] === file ||
titleTerms[term] === file ||
(terms[term] || []).includes(file) ||
(titleTerms[term] || []).includes(file)
)
)
break;
// if we have still a valid result we can add it to the result list
if (valid) {
// select one (max) score for the file.
// for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
}
// select one (max) score for the file.
const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
// add result to the result list
results.push([
docNames[file],
titles[file],
"",
null,
score,
filenames[file],
]);
}
return results;
},
@@ -499,34 +551,28 @@ var Search = {
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurrence, the
* latter for highlighting it.
* of stemmed words.
*/
makeSearchSummary : function(htmlText, keywords, hlwords) {
var text = Search.htmlToText(htmlText);
if (text == "") {
return null;
}
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<p class="context"></p>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
makeSearchSummary: (htmlText, keywords) => {
const text = Search.htmlToText(htmlText);
if (text === "") return null;
const textLower = text.toLowerCase();
const actualStartPosition = [...keywords]
.map((k) => textLower.indexOf(k.toLowerCase()))
.filter((i) => i > -1)
.slice(-1)[0];
const startWithContext = Math.max(actualStartPosition - 120, 0);
const top = startWithContext === 0 ? "" : "...";
const tail = startWithContext + 240 < text.length ? "..." : "";
let summary = document.createElement("p");
summary.classList.add("context");
summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
return summary;
},
};
$(document).ready(function() {
Search.init();
});
_ready(Search.init);
@@ -0,0 +1,154 @@
/* Highlighting utilities for Sphinx HTML documentation. */
"use strict";
const SPHINX_HIGHLIGHT_ENABLED = true
/**
* highlight a given string on a node by wrapping it in
* span elements with the given class name.
*/
const _highlight = (node, addItems, text, className) => {
if (node.nodeType === Node.TEXT_NODE) {
const val = node.nodeValue;
const parent = node.parentNode;
const pos = val.toLowerCase().indexOf(text);
if (
pos >= 0 &&
!parent.classList.contains(className) &&
!parent.classList.contains("nohighlight")
) {
let span;
const closestNode = parent.closest("body, svg, foreignObject");
const isInSVG = closestNode && closestNode.matches("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.classList.add(className);
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
const rest = document.createTextNode(val.substr(pos + text.length));
parent.insertBefore(
span,
parent.insertBefore(
rest,
node.nextSibling
)
);
node.nodeValue = val.substr(0, pos);
/* There may be more occurrences of search term in this node. So call this
* function recursively on the remaining fragment.
*/
_highlight(rest, addItems, text, className);
if (isInSVG) {
const rect = document.createElementNS(
"http://www.w3.org/2000/svg",
"rect"
);
const bbox = parent.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute("class", className);
addItems.push({ parent: parent, target: rect });
}
}
} else if (node.matches && !node.matches("button, select, textarea")) {
node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
}
};
const _highlightText = (thisNode, text, className) => {
let addItems = [];
_highlight(thisNode, addItems, text, className);
addItems.forEach((obj) =>
obj.parent.insertAdjacentElement("beforebegin", obj.target)
);
};
/**
* Small JavaScript module for the documentation.
*/
const SphinxHighlight = {
/**
* highlight the search words provided in localstorage in the text
*/
highlightSearchWords: () => {
if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
// get and clear terms from localstorage
const url = new URL(window.location);
const highlight =
localStorage.getItem("sphinx_highlight_terms")
|| url.searchParams.get("highlight")
|| "";
localStorage.removeItem("sphinx_highlight_terms")
url.searchParams.delete("highlight");
window.history.replaceState({}, "", url);
// get individual terms from highlight string
const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
if (terms.length === 0) return; // nothing to do
// There should never be more than one element matching "div.body"
const divBody = document.querySelectorAll("div.body");
const body = divBody.length ? divBody[0] : document.querySelector("body");
window.setTimeout(() => {
terms.forEach((term) => _highlightText(body, term, "highlighted"));
}, 10);
const searchBox = document.getElementById("searchbox");
if (searchBox === null) return;
searchBox.appendChild(
document
.createRange()
.createContextualFragment(
'<p class="highlight-link">' +
'<a href="javascript:SphinxHighlight.hideSearchWords()">' +
_("Hide Search Matches") +
"</a></p>"
)
);
},
/**
* helper function to hide the search marks again
*/
hideSearchWords: () => {
document
.querySelectorAll("#searchbox .highlight-link")
.forEach((el) => el.remove());
document
.querySelectorAll("span.highlighted")
.forEach((el) => el.classList.remove("highlighted"));
localStorage.removeItem("sphinx_highlight_terms")
},
initEscapeListener: () => {
// only install a listener if it is really needed
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;
document.addEventListener("keydown", (event) => {
// bail for input elements
if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
// bail with special keys
if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) {
SphinxHighlight.hideSearchWords();
event.preventDefault();
}
});
},
};
_ready(() => {
/* Do not call highlightSearchWords() when we are on the search page.
* It will highlight words from the *previous* search query.
*/
if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords();
SphinxHighlight.initEscapeListener();
});
File diff suppressed because it is too large. Load diff
Loaded 100 of 1985 files, more files were not shown because too many files have changed in this diff. Show more