mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
more fuzzing fun
This commit is contained in:
+35
-2
@@ -48,11 +48,17 @@ to the build system is not required and not wanted.
|
||||
make_seed_corpus.sh packages src/fuzz/corpus/ into
|
||||
$OUT/<fuzzer>_seed_corpus.zip
|
||||
fuzz_request.options per-harness libFuzzer options (max_len, dict)
|
||||
fuzz_options.options
|
||||
fuzz_eventloop.options
|
||||
fuzz_str.options
|
||||
fuzz_memorypool.options
|
||||
fuzz_auth_header.options
|
||||
fuzz_postprocessor.options
|
||||
dicts/fuzz_request.dict per-harness fuzzing dictionaries
|
||||
dicts/fuzz_options.dict
|
||||
dicts/fuzz_eventloop.dict
|
||||
dicts/fuzz_str.dict
|
||||
dicts/fuzz_memorypool.dict
|
||||
dicts/fuzz_auth_header.dict
|
||||
dicts/fuzz_postprocessor.dict
|
||||
README this file
|
||||
@@ -64,7 +70,7 @@ the corpus packager live here and not in the OSS-Fuzz repository.
|
||||
|
||||
|
||||
-------------------------------------------------------------------
|
||||
2. The four fuzz targets
|
||||
2. The fuzz targets
|
||||
-------------------------------------------------------------------
|
||||
|
||||
fuzz_request a real struct MHD_Daemon driven over a
|
||||
@@ -75,13 +81,28 @@ the corpus packager live here and not in the OSS-Fuzz repository.
|
||||
constructor, the authentication entry point,
|
||||
the event-loop API, and whether the
|
||||
connection is suspended or upgraded
|
||||
fuzz_options the daemon configuration surface: the input
|
||||
picks the MHD_FLAG bits and the MHD_OPTION
|
||||
array, reaching the flag validation, the
|
||||
thread pool, the internal polling modes, the
|
||||
listen socket and the connection limits
|
||||
fuzz_eventloop the external event loop: the input is a
|
||||
program of opcodes that polls, ignores
|
||||
timeouts, mismatches descriptor sets and
|
||||
suspends/resumes against a live daemon
|
||||
fuzz_str the mhd_str.c primitives with exactly-sized
|
||||
output buffers
|
||||
fuzz_memorypool memorypool.c, the per-connection bump
|
||||
allocator, with the harness's own oracles
|
||||
fuzz_auth_header MHD_get_rq_dauth_params_() /
|
||||
MHD_get_rq_bauth_params_()
|
||||
fuzz_postprocessor MHD_post_process()
|
||||
|
||||
All four are single translation units that export
|
||||
src/fuzz/ has one more harness, `fuzz_tls`, which is deliberately absent
|
||||
here: it needs a TLS backend and this build is --disable-https (see
|
||||
section 3).
|
||||
|
||||
All seven are single translation units that export
|
||||
|
||||
int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size);
|
||||
|
||||
@@ -107,8 +128,20 @@ harness ignores the extra bytes, so libFuzzer does not waste its budget:
|
||||
and a body-oracle declaration. Larger
|
||||
inputs are safe -- every segment is bounded
|
||||
independently -- but buy almost nothing.
|
||||
fuzz_options 8192 the flag/option block plus one short
|
||||
request; the request half is what makes
|
||||
the tail of the input worth anything, so
|
||||
this tracks fuzz_request rather than the
|
||||
(much smaller) option block alone.
|
||||
fuzz_eventloop 512 configuration byte + the opcode program.
|
||||
Opcodes are one byte each and the program
|
||||
is bounded, so a longer input only adds
|
||||
opcodes that are never interpreted.
|
||||
fuzz_str 514 2 selector bytes + the payload, which the
|
||||
harness truncates to 512.
|
||||
fuzz_memorypool 200 the smallest of the set: a pool size and a
|
||||
short program of allocate/reallocate/reset
|
||||
operations, all bounded.
|
||||
fuzz_auth_header 4097 1 selector byte + the Authorization header
|
||||
value, truncated to 4096.
|
||||
fuzz_postprocessor 8196 4 selector bytes + the POST body, truncated
|
||||
|
||||
@@ -40,6 +40,7 @@ OUTDIR="${2:-${OUT:-$(pwd)/out}}"
|
||||
|
||||
CORPUS="${SRCDIR}/src/fuzz/corpus"
|
||||
FINDINGS="${CORPUS}/known-findings"
|
||||
DISTILLED="${CORPUS}/distilled"
|
||||
PATCHES="${SRCDIR}/patches"
|
||||
|
||||
FUZZERS="fuzz_request fuzz_options fuzz_eventloop fuzz_str fuzz_memorypool fuzz_auth_header fuzz_postprocessor"
|
||||
@@ -98,6 +99,19 @@ for fuzzer in ${FUZZERS}; do
|
||||
done
|
||||
fi
|
||||
|
||||
# distilled/ is the edge-minimal residue of a fuzzing campaign, named
|
||||
# "<harness>-dNNN.bin" and therefore routed by prefix like the seeds
|
||||
# above. It is by far the largest part of the seed corpus and the
|
||||
# reason a fresh ClusterFuzz run starts near the coverage the last
|
||||
# campaign reached instead of climbing back to it.
|
||||
if [ -d "${DISTILLED}" ]; then
|
||||
for f in "${DISTILLED}/${fuzzer}"-*.bin; do
|
||||
[ -f "${f}" ] || continue
|
||||
cp "${f}" "${dir}/distilled-$(basename "${f}")"
|
||||
n=$((n + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "${n}" -eq 0 ]; then
|
||||
echo "ERROR: no seeds found for ${fuzzer} in ${CORPUS}" >&2
|
||||
exit 1
|
||||
|
||||
+10
-3
@@ -146,19 +146,26 @@ refresh-corpus: $(check_PROGRAMS)
|
||||
# Replay the whole on-disk corpus through every harness; this is what a
|
||||
# CI regression run should do after a crash has been fixed.
|
||||
#
|
||||
# corpus/known-findings/ is listed separately because --corpus-dir does
|
||||
# not recurse. It holds the reproducers of the findings in README
|
||||
# corpus/known-findings/ and corpus/distilled/ are listed separately
|
||||
# because --corpus-dir does not recurse.
|
||||
#
|
||||
# known-findings/ holds the reproducers of the findings in README
|
||||
# section 6; all of them are fixed, so anything failing there is a
|
||||
# regression. The one intended exception is a reproducer committed while
|
||||
# its finding is still open: that fails here until the fix lands, which
|
||||
# is what a regression test for an unfixed bug is supposed to do.
|
||||
#
|
||||
# distilled/ is the edge-minimal residue of a fuzzing campaign; see
|
||||
# corpus/README. It is the slowest part of check-corpus by file count
|
||||
# and the most valuable part by coverage.
|
||||
#
|
||||
# Note that these only bite on a tree configured with --enable-asserts;
|
||||
# without it mhd_assert() compiles away and most of these reproducers
|
||||
# pass whether MHD is fixed or not.
|
||||
CORPUS_DIRS = \
|
||||
$(srcdir)/corpus \
|
||||
$(srcdir)/corpus/known-findings
|
||||
$(srcdir)/corpus/known-findings \
|
||||
$(srcdir)/corpus/distilled
|
||||
|
||||
.PHONY: check-corpus
|
||||
check-corpus: $(check_PROGRAMS)
|
||||
|
||||
+117
-3
@@ -1,7 +1,7 @@
|
||||
GNU libmicrohttpd -- in-process fuzzing harnesses
|
||||
=================================================
|
||||
|
||||
This directory contains four in-process fuzzing harnesses for MHD. All
|
||||
This directory contains eight in-process fuzzing harnesses for MHD. All
|
||||
of them are *dual mode*:
|
||||
|
||||
* they export the libFuzzer entry point
|
||||
@@ -46,6 +46,50 @@ fuzz_postprocessor.c fuzzing of MHD_post_process() with random
|
||||
boundaries), random post-processor buffer sizes
|
||||
and random chunking of the POST data.
|
||||
|
||||
fuzz_options.c the daemon *configuration* surface. fuzz_request
|
||||
always starts the daemon in one shape; this one
|
||||
lets the input pick the MHD_FLAG bits and the
|
||||
MHD_OPTION array, so the flag validation in
|
||||
MHD_start_daemon(), parse_options_va(), the
|
||||
internal polling thread, the thread pool,
|
||||
epoll/poll/select, the listen socket, the per-IP
|
||||
and per-daemon connection limits and quiesce all
|
||||
become reachable.
|
||||
|
||||
fuzz_eventloop.c the external event loop and the scheduling of the
|
||||
connection life cycle. The input is not a
|
||||
request but a *schedule*: a program of one-byte
|
||||
opcodes interpreted against a live daemon, so the
|
||||
application can poll at adversarial times, ignore
|
||||
the timeout it was given, call
|
||||
MHD_run_from_select() with descriptor sets that
|
||||
do not match what MHD asked for, and
|
||||
suspend/resume across those calls. Byte 3 bit 4
|
||||
also lets it stop the daemon with a connection
|
||||
queued by MHD_add_connection() but never
|
||||
started, which is the only way into
|
||||
new_connection_close_() -- see section 5.5.
|
||||
|
||||
fuzz_memorypool.c direct fuzzing of src/microhttpd/memorypool.c,
|
||||
the per-connection bump allocator. A single
|
||||
mis-computed offset there is a cross-request
|
||||
information leak that ASAN cannot see on its own,
|
||||
because the whole pool is one malloc()ed object;
|
||||
the harness therefore carries its own oracles and
|
||||
knows the red zone size that
|
||||
MHD_ASAN_POISON_ACTIVE adds between two blocks.
|
||||
|
||||
fuzz_tls.c MHD's own TLS plumbing -- the MHD_USE_TLS option
|
||||
surface (HTTPS_MEM_KEY/CERT/TRUST/DHPARAMS,
|
||||
PRIORITIES, CRED_TYPE, KEY_PASSWORD, ALPN, SNI,
|
||||
GNUTLS_PSK_CRED_HANDLER) rather than GnuTLS,
|
||||
which has its own OSS-Fuzz project. Byte 9 bit 7
|
||||
switches on the TLS-PSK scenario, the only route
|
||||
to psk_gnutls_adapter() -- see section 5.5. It
|
||||
needs a TLS backend and is therefore the one
|
||||
harness contrib/oss-fuzz/build.sh does not build
|
||||
(that build is --disable-https).
|
||||
|
||||
Shared code lives in `fuzz_common.h` (header-only, so every harness
|
||||
stays a single translation unit).
|
||||
|
||||
@@ -426,6 +470,45 @@ finds each of them on its own within a few thousand iterations.
|
||||
immediately. The target models a *caller*, not the library, so it
|
||||
is off by default.
|
||||
|
||||
5.5 Code that only a deliberate scenario reaches
|
||||
A coverage-guided engine gets to a branch by mutating towards it, so
|
||||
it never gets to one that needs several unrelated configuration
|
||||
bytes to be right at the same time: the intermediate inputs score no
|
||||
better than the ones around them, and the fuzzer has no gradient to
|
||||
follow. An 8 hour, 12 core, 1.6 billion execution campaign, on top
|
||||
of the whole test suite, left exactly three library functions at zero
|
||||
coverage for that reason. All three now have a scenario:
|
||||
|
||||
psk_gnutls_adapter() (daemon.c) -- MHD's only piece of TLS code that
|
||||
takes a buffer straight from an application callback. Needs
|
||||
GNUTLS_CRD_PSK, a PSK-capable priority string *on both ends*
|
||||
("NORMAL" has none), MHD_OPTION_GNUTLS_PSK_CRED_HANDLER, and a
|
||||
client offering a PSK identity. fuzz_tls byte 9 bit 7 switches all
|
||||
four on together; bits 3-5 then pick which arm of the adapter to
|
||||
exercise (missing callback, failing callback, 4 KiB key, key length
|
||||
taken from the identity the client sent, size above UINT_MAX, and
|
||||
the two sizes below the MHD_PSK_MIN_SIZE the adapter enforces --
|
||||
zero and one byte short, which together with the exactly-minimum
|
||||
PSK_OK bracket that check from both sides). Seeds `psk-*`.
|
||||
|
||||
new_connection_close_() (daemon.c) -- frees a connection that was
|
||||
accepted but never started. On a thread-safe daemon (the default,
|
||||
including a pure external event loop) MHD_add_connection() only
|
||||
queues the socket; the connection object is built by the next run.
|
||||
The function is reachable only if the daemon is stopped before that
|
||||
run happens, and every harness used to call MHD_run() once more
|
||||
during teardown. fuzz_eventloop byte 3 bit 4 queues one connection
|
||||
after the teardown and stops without running. Seeds
|
||||
`stop-with-queued-connection`, `stop-with-queued-after-quiesce`.
|
||||
It is not a race: no second thread is involved.
|
||||
|
||||
MHD_check_response_header_token_ci() (response.c) -- this one was
|
||||
not a fuzzing problem. The function was added in 2017 and never
|
||||
called, so no input could reach it. The single place that wants it,
|
||||
the "Connection: upgrade" check in MHD_queue_response(), open-coded
|
||||
the scan against response->first_header instead; that now calls the
|
||||
helper, and the existing `ext-upgrade` seed and K7 cover it.
|
||||
|
||||
|
||||
-------------------------------------------------------------------
|
||||
6. Findings against MHD 1.0.7 - all fixed, kept as regressions
|
||||
@@ -695,15 +778,46 @@ K14 daemon.c:1358 call_handlers():
|
||||
confirm it against the OSS-Fuzz build configuration.
|
||||
Repro: corpus/known-findings/K14-fuzz_eventloop-force-close-not-closed.bin
|
||||
|
||||
K15 daemon.c:9201 close_all_connections():
|
||||
mhd_assert (MHD_D_IS_USING_THREADS_ (daemon))
|
||||
Fixed; found while giving new_connection_close_() its first coverage
|
||||
(section 5.5).
|
||||
|
||||
Three places describe the same invariant and one of them disagreed.
|
||||
internal_add_connection() queues a connection when
|
||||
`external_add && MHD_D_IS_THREAD_SAFE_(daemon)`, and
|
||||
new_connections_list_process_() asserts MHD_D_IS_THREAD_SAFE_ --
|
||||
that is, whenever the daemon was not started with
|
||||
MHD_USE_NO_THREAD_SAFETY, which includes every external event loop.
|
||||
The shutdown drain asserted the much stronger
|
||||
MHD_D_IS_USING_THREADS_ instead, i.e. that the daemon has an
|
||||
internal polling thread.
|
||||
|
||||
So an application that drives an external event loop, calls
|
||||
MHD_add_connection() and then MHD_stop_daemon() before the next
|
||||
MHD_run() aborts on an --enable-asserts build. No threads and no
|
||||
race are involved, and a build with NDEBUG handles the same sequence
|
||||
correctly, which is why nothing had noticed: the list is exactly what
|
||||
holds the connection at that point and new_connection_close_() frees
|
||||
it properly.
|
||||
|
||||
The assert was the outlier and now matches the other two sites. The
|
||||
opposite reading -- that an external event loop should not queue at
|
||||
all and internal_add_connection() should test
|
||||
MHD_D_IS_USING_THREADS_ -- would change MHD_add_connection()'s
|
||||
threading contract, since queueing is what makes that call safe from
|
||||
another thread on a daemon with no thread of its own.
|
||||
Repro: corpus/known-findings/K15-fuzz_eventloop-stop-with-queued-connection.bin
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
K1-K12 are fixed on master:
|
||||
K1-K12 and K15 are fixed on master:
|
||||
|
||||
K1 300a2ab0 K4a 0b750975 K7 acef58a0 K10 (memorypool)
|
||||
K2 68c83f22 K4b 0b750975 K8 07c051dd K11 (memorypool)
|
||||
K3 e04eb218 K5 6fcdfd43 K9 (postproc) K12 (daemon/TLS)
|
||||
K6 f438804c
|
||||
K6 f438804c K15 (daemon)
|
||||
|
||||
K13 and K14 are open, with proposed fixes in ../../patches/. Until K14
|
||||
lands, `make check-corpus` fails on an `--enable-asserts` build, because
|
||||
|
||||
@@ -128,6 +128,76 @@ fuzz_postprocessor seeds
|
||||
Content-Type.
|
||||
|
||||
|
||||
distilled/
|
||||
----------
|
||||
|
||||
The edge-minimal residue of a fuzzing campaign: 2467 inputs, 222 KB,
|
||||
named `<harness>-dNNN.bin` and routed by that prefix exactly like the
|
||||
seeds above.
|
||||
|
||||
Unlike `<harness>-NN.bin` these are *not* generated from a built-in
|
||||
table, so `refresh-corpus` neither writes nor clobbers them; and unlike
|
||||
`known-findings/` they are not hand-edited and carry no individual
|
||||
meaning. Do not document them one by one -- the set is only ever
|
||||
regenerated wholesale.
|
||||
|
||||
Provenance: an 8 hour, 12 core, 1.62 billion execution campaign
|
||||
(ASan+UBSan, libFuzzer, hourly restarts) starting from the seed corpus
|
||||
above. The campaign corpus was 18 226 inputs / 12 MB, which is too much
|
||||
to carry in a source tree, so it was reduced by greedy set cover over
|
||||
*edges* rather than by `-merge=1`, which minimises for features and
|
||||
keeps roughly seven times as many files:
|
||||
|
||||
<target> -merge=1 -merge_control_file=mcf.txt <empty dir> <corpus>
|
||||
|
||||
writes a `COV` line per input, and the cover is computed from those
|
||||
offline. Because these harnesses are mildly non-deterministic, the
|
||||
cover is built only from edges that two independent merges agree an
|
||||
input reproduces -- the same "several independent merges" rule stated at
|
||||
the top of this file.
|
||||
|
||||
**An engine-produced corpus is not pristine, and this directory has to
|
||||
be filtered before it can be committed.** `fuzz_request` inputs carry a
|
||||
ground-truth body declaration in their `op == 1` segment, and the body
|
||||
oracle is armed only for a `fuzz_pristine` input precisely because
|
||||
"random mutations invalidate such declarations" (`fuzz_common.h`).
|
||||
libFuzzer mutates that segment independently of the wire segments, so a
|
||||
campaign corpus is full of inputs whose declaration no longer describes
|
||||
their own request -- 383 of 6884 here, 5.6%. Under libFuzzer that is
|
||||
harmless: `-DFUZZ_NO_MAIN` compiles out every assignment to
|
||||
`fuzz_pristine`, so the oracle never arms and the campaign never
|
||||
notices. But `--corpus-dir` sets `fuzz_pristine = 1` for *every* file it
|
||||
reads, so replaying such an input reports a "request body desync"
|
||||
against a declaration that was never true -- a false positive, and one
|
||||
that looks exactly like a request-smuggling finding.
|
||||
|
||||
Committing the raw cover therefore broke `make check-corpus` with 42
|
||||
such reports. The fix is to sweep every candidate with
|
||||
`--file=` first and exclude the ones that fire *before* computing the
|
||||
cover, which is what produced the set in this directory; all 2467 files
|
||||
replay clean through all eight harnesses. Anyone replaying a downloaded
|
||||
ClusterFuzz corpus locally will hit the same thing, and it is not a bug
|
||||
in MHD.
|
||||
|
||||
The set reaches ~99% of the campaign's edges, not 100%: 3763/3798 for
|
||||
fuzz_request, and exactly 100% for the four direct-API harnesses, which
|
||||
are deterministic. Two thirds of that shortfall is the exclusion above
|
||||
-- 64 edges were reached only by inputs with a stale declaration -- and
|
||||
the rest is edges no single input reproduces reliably. Forcing the
|
||||
latter in by adding every input that covers a rare edge was tried and
|
||||
moved the number by one, so that part is inherent to minimising rather
|
||||
than a fixable omission. Trading 1% of edges for 86% fewer files is the
|
||||
intended bargain. Do not chase it.
|
||||
|
||||
To regenerate after a long campaign: keep the campaign corpus, sweep it
|
||||
for oracle-firing inputs, run two independent merges over what is left,
|
||||
recompute the cover, and replace this directory wholesale. Check the
|
||||
result the same way it was checked here -- replay both the campaign
|
||||
corpus and the distilled set with `-runs=0` three times each and compare
|
||||
the `INITED cov:` figures, because a single measurement of either is
|
||||
worth a few edges of noise -- and finish with `make check-corpus`.
|
||||
|
||||
|
||||
known-findings/
|
||||
---------------
|
||||
|
||||
@@ -179,6 +249,16 @@ hand-written input would be clobbered or renumbered by the next
|
||||
Only fires on an --enable-asserts
|
||||
*ASan* build: the redzones change
|
||||
the pool arithmetic that reaches it.
|
||||
K15-fuzz_eventloop- daemon.c close_all_connections()
|
||||
stop-with-queued-connection.bin asserted that only a daemon with an
|
||||
internal polling thread can have
|
||||
connections queued by
|
||||
MHD_add_connection(), while the code
|
||||
that fills that list queues for any
|
||||
thread-safe daemon. An external
|
||||
event loop that adds a connection and
|
||||
stops before the next MHD_run()
|
||||
aborts on an --enable-asserts build.
|
||||
|
||||
These files are *not* regenerated by `--write-corpus`; they are edited by
|
||||
hand. When the input format changes they have to be migrated, and the
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
B:
|
||||
@@ -0,0 +1 @@
|
||||
�s
|
||||
@@ -0,0 +1 @@
|
||||
�s
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Basic Y
|
||||
@@ -0,0 +1 @@
|
||||
SHA5 2
|
||||
@@ -0,0 +1 @@
|
||||
Basic
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest qop="\z"
|
||||
@@ -0,0 +1 @@
|
||||
"a
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Basic 45]f
|
||||
@@ -0,0 +1 @@
|
||||
Digest nc
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Basic dXNlcjpwYXNz
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
i:n¤st
|
||||
@@ -0,0 +1 @@
|
||||
Basic
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Basic Q Q
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest ,
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest nc="""
|
||||
@@ -0,0 +1 @@
|
||||
Basic dXNÿcjNz
|
||||
@@ -0,0 +1 @@
|
||||
Basic QQas(c$Q
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest qop="A\D"
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
@Digest qop="a\uth"
|
||||
@@ -0,0 +1 @@
|
||||
逑レレレレレレレレレレレレfレレレレレレレレレレレレ)=レレレレレレレレレレレレレレレレレレレ/レレレレレレレレレレレes
|
||||
@@ -0,0 +1 @@
|
||||
f˙˙˙˙˙˙˙˙˙˙˙˙rfrealm="Te"f˙˙˙˙˙˙stRealm"f˙˙˙˙˙˙˙˙˙˙˙ffff"ťfffff
|
||||
@@ -0,0 +1,2 @@
|
||||
BstReamm:peeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee '
|
||||
捏
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
eg
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Basic ;
|
||||
@@ -0,0 +1 @@
|
||||
Basic ,
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest "x
|
||||
@@ -0,0 +1 @@
|
||||
Basic ====
|
||||
@@ -0,0 +1 @@
|
||||
Basic QQ==
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Basic dXN{
|
||||
@@ -0,0 +1 @@
|
||||
Basic 1QQ=
|
||||
@@ -0,0 +1 @@
|
||||
basic zzz=
|
||||
@@ -0,0 +1 @@
|
||||
Basic sh==
|
||||
@@ -0,0 +1 @@
|
||||
Basic E(=J
|
||||
@@ -0,0 +1 @@
|
||||
Basic QQ=-
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
basic QëDigest
|
||||
@@ -0,0 +1 @@
|
||||
Basic QQ==QQ==
|
||||
@@ -0,0 +1 @@
|
||||
Basic =QQ==QQ=
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest qop="\D"
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest qop="a\!"
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
@Digest qop="auth\Ò"
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest userhash="\g"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest algorithm="\¯"
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest algorithm="\MD5"
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Digest algorithm=MD5-sess
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user