diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b8da84c97..75b364f6d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,7 +34,8 @@ jobs: sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list sudo apt-get -o Dpkg::Use-Pty=0 update sudo rm -f /var/lib/man-db/auto-update - sudo apt-get -o Dpkg::Use-Pty=0 install -y cmake clang ninja-build + sudo apt-get -o Dpkg::Use-Pty=0 install -y \ + cmake clang ninja-build protobuf-compiler libprotobuf-dev - name: Compile mainline env: @@ -54,7 +55,8 @@ jobs: sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list sudo apt-get -o Dpkg::Use-Pty=0 update sudo rm -f /var/lib/man-db/auto-update - sudo apt-get -o Dpkg::Use-Pty=0 install -y cmake clang ninja-build + sudo apt-get -o Dpkg::Use-Pty=0 install -y \ + cmake clang ninja-build protobuf-compiler libprotobuf-dev - name: Compile deps target run: ./scripts/compile_target.sh deps diff --git a/CMakeLists.txt b/CMakeLists.txt index 03e239ff8..dff042f11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.11) project(curl_fuzzer_deps) +set(Protobuf_USE_STATIC_LIBS ON CACHE BOOL "Link against static protobuf" FORCE) + if(NOT "$ENV{MAKE}" STREQUAL "") set(MAKE "$ENV{MAKE}") else() @@ -8,6 +10,45 @@ else() endif() include(ExternalProject) +find_package(Protobuf REQUIRED) + +set(CURL_FUZZER_PROTO ${CMAKE_CURRENT_SOURCE_DIR}/schemas/curl_fuzzer.proto) +protobuf_generate_cpp(CURL_FUZZER_PROTO_SRCS CURL_FUZZER_PROTO_HDRS + ${CURL_FUZZER_PROTO}) + +add_library(curl_fuzzer_proto STATIC ${CURL_FUZZER_PROTO_SRCS}) +target_include_directories(curl_fuzzer_proto PUBLIC + ${CMAKE_CURRENT_BINARY_DIR} + ${PROTOBUF_INCLUDE_DIRS}) +target_link_libraries(curl_fuzzer_proto PUBLIC ${PROTOBUF_LIBRARIES}) + +# Install libprotobuf-mutator +# +# renovate: datasource=github-tags depName=google/libprotobuf-mutator +set(LIB_PROTO_MUTATOR_TAG v1.5) +set(LIB_PROTO_MUTATOR_INSTALL_DIR ${CMAKE_BINARY_DIR}/libprotobuf-mutator-install) +set(LIB_PROTO_MUTATOR_INCLUDE_DIR ${LIB_PROTO_MUTATOR_INSTALL_DIR}/include) +set(LIB_PROTO_MUTATOR_STATIC_LIB ${LIB_PROTO_MUTATOR_INSTALL_DIR}/lib/libprotobuf-mutator.a) +set(LIB_PROTO_MUTATOR_FUZZER_LIB ${LIB_PROTO_MUTATOR_INSTALL_DIR}/lib/libprotobuf-mutator-libfuzzer.a) + +ExternalProject_Add(libprotobuf_mutator_external + GIT_REPOSITORY https://github.com/google/libprotobuf-mutator.git + GIT_TAG ${LIB_PROTO_MUTATOR_TAG} + PREFIX ${CMAKE_BINARY_DIR}/libprotobuf-mutator + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${LIB_PROTO_MUTATOR_INSTALL_DIR} + -DBUILD_SHARED_LIBS=OFF + -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=OFF + -DLIB_PROTO_MUTATOR_WITH_LIBFUZZER=ON + -DLIB_PROTO_MUTATOR_EXAMPLES=OFF + -DLIB_PROTO_MUTATOR_TESTING=OFF + -DProtobuf_USE_STATIC_LIBS=ON + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + BUILD_BYPRODUCTS ${LIB_PROTO_MUTATOR_STATIC_LIB} ${LIB_PROTO_MUTATOR_FUZZER_LIB} + INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + DOWNLOAD_NO_PROGRESS 1 +) # Install zlib # @@ -223,7 +264,8 @@ add_custom_target(deps zstd_external libidn2_external ${GDB_DEP} - openldap_external + openldap_external + libprotobuf_mutator_external ) # Now for the main dependencies! @@ -336,7 +378,11 @@ else() endif() # Common sources and flags -set(COMMON_SOURCES curl_fuzzer.cc curl_fuzzer_tlv.cc curl_fuzzer_callback.cc) +set(COMMON_SOURCES + curl_fuzzer.cc + curl_fuzzer_tlv.cc + curl_fuzzer_callback.cc + curl_fuzzer_scenario.cc) set(COMMON_FLAGS -g -DCURL_DISABLE_DEPRECATION) set(COMMON_LINK_LIBS ${CURL_LIB_DIR}/libcurl.a @@ -348,19 +394,24 @@ set(COMMON_LINK_LIBS ${OPENLDAP_STATIC_LIB_LDAP} ${OPENLDAP_STATIC_LIB_LBER} ${LIB_FUZZING_ENGINE} + ${LIB_PROTO_MUTATOR_FUZZER_LIB} + ${LIB_PROTO_MUTATOR_STATIC_LIB} + curl_fuzzer_proto pthread m ) +list(APPEND COMMON_LINK_LIBS ${PROTOBUF_LIBRARIES}) set(COMMON_LINK_OPTIONS ${LIB_FUZZING_ENGINE_FLAG}) +list(APPEND COMMON_LINK_OPTIONS -static-libstdc++ -static-libgcc) # Ensure that curl and its dependencies are built before the fuzzers -set(FUZZ_DEPS curl_external ${CURL_DEPS} ${LIB_FUZZING_ENGINE_DEP}) +set(FUZZ_DEPS curl_external ${CURL_DEPS} ${LIB_FUZZING_ENGINE_DEP} curl_fuzzer_proto libprotobuf_mutator_external) # Helper macro to define a fuzzer target macro(curl_add_fuzzer _name _proto) add_executable(${_name} ${COMMON_SOURCES}) target_compile_options(${_name} PRIVATE ${COMMON_FLAGS} -DFUZZ_PROTOCOLS_${_proto}) - target_include_directories(${_name} PRIVATE ${CURL_INCLUDE_DIRS}) + target_include_directories(${_name} PRIVATE ${CURL_INCLUDE_DIRS} ${LIB_PROTO_MUTATOR_INCLUDE_DIR} ${LIB_PROTO_MUTATOR_INCLUDE_DIR}/libprotobuf-mutator) target_link_libraries(${_name} PRIVATE ${COMMON_LINK_LIBS}) target_link_options(${_name} PRIVATE ${COMMON_LINK_OPTIONS}) add_dependencies(${_name} ${FUZZ_DEPS}) @@ -387,7 +438,7 @@ curl_add_fuzzer(curl_fuzzer_ws WS) # BUFQ fuzzer add_executable(curl_fuzzer_bufq fuzz_bufq.cc) target_compile_options(curl_fuzzer_bufq PRIVATE ${COMMON_FLAGS}) -target_include_directories(curl_fuzzer_bufq PRIVATE ${CURL_INCLUDE_DIRS}) +target_include_directories(curl_fuzzer_bufq PRIVATE ${CURL_INCLUDE_DIRS} ${LIB_PROTO_MUTATOR_INCLUDE_DIR} ${LIB_PROTO_MUTATOR_INCLUDE_DIR}/libprotobuf-mutator) target_link_libraries(curl_fuzzer_bufq PRIVATE ${COMMON_LINK_LIBS}) target_link_options(curl_fuzzer_bufq PRIVATE ${COMMON_LINK_OPTIONS}) add_dependencies(curl_fuzzer_bufq ${FUZZ_DEPS}) diff --git a/README.md b/README.md index ac217fd23..e20050a9f 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,22 @@ temporary directory instead. `./mainline.sh` is run regressibly by Github Actions. +## Structure-aware fuzzing with libprotobuf-mutator + +Every `curl_fuzzer*` binary now links +[libprotobuf-mutator](https://github.com/google/libprotobuf-mutator) directly. +Build the usual targets and you automatically get structured `Scenario` +generation: + +```shell +cmake -S . -B build +cmake --build build --target curl_fuzzer +``` + +The shared engine still understands legacy TLV corpora, but the libFuzzer +entry-point feeds decoded `Scenario` protos into the same execution path, so +crash reports remain comparable to the classic workflow. + ## I want more information when running a testcase or multiple testcases Setting the `FUZZ_VERBOSE` environment variable turns on curl verbose logging. @@ -80,6 +96,22 @@ read_corpus ``` This will print out a list of contents inside the file. +## I want to convert TLV corpora into structured scenarios + +Install the tooling (see above), then run the converter to mirror TLV corpus +entries into Scenario `.textproto` files: + +```shell +corpora_to_textproto --output scenarios/ +``` + +By default the tool walks the `corpora/` tree and writes `*.textproto` files to +`scenarios/`, preserving the directory structure. You can point `--output` to a +different directory or pass one or more explicit corpus paths when you only +want to convert selected inputs. The converter automatically skips corpora for +the `curl_fuzzer_fnmatch`, `curl_fuzzer_bufq`, and `fuzz_url` harnesses because +they do not use the structured Scenario pipeline. + ## I want an HTML decoder for corpus files Generate a standalone HTML page that can inspect TLV corpora directly in your browser: diff --git a/corpora/.gitignore b/corpora/.gitignore new file mode 100644 index 000000000..03b0ee1b5 --- /dev/null +++ b/corpora/.gitignore @@ -0,0 +1,20 @@ +# Ignore all the scenario corpora +curl_fuzzer/ +curl_fuzzer_dict/ +curl_fuzzer_file/ +curl_fuzzer_ftp/ +curl_fuzzer_gopher/ +curl_fuzzer_http/ +curl_fuzzer_https/ +curl_fuzzer_imap/ +curl_fuzzer_ldap/ +curl_fuzzer_mqtt/ +curl_fuzzer_pop3/ +curl_fuzzer_rtmp/ +curl_fuzzer_rtsp/ +curl_fuzzer_scp/ +curl_fuzzer_sftp/ +curl_fuzzer_smb/ +curl_fuzzer_smtp/ +curl_fuzzer_tftp/ +curl_fuzzer_ws/ diff --git a/corpora/curl_fuzzer/oss-fuzz-3327 b/corpora/curl_fuzzer/oss-fuzz-3327 deleted file mode 100644 index 064cc623a..000000000 Binary files a/corpora/curl_fuzzer/oss-fuzz-3327 and /dev/null differ diff --git a/corpora/curl_fuzzer/test1 b/corpora/curl_fuzzer/test1 deleted file mode 100644 index f7b734a9c..000000000 Binary files a/corpora/curl_fuzzer/test1 and /dev/null differ diff --git a/corpora/curl_fuzzer/test10 b/corpora/curl_fuzzer/test10 deleted file mode 100644 index af1ed53ca..000000000 Binary files a/corpora/curl_fuzzer/test10 and /dev/null differ diff --git a/corpora/curl_fuzzer/test100 b/corpora/curl_fuzzer/test100 deleted file mode 100644 index b58d9335a..000000000 Binary files a/corpora/curl_fuzzer/test100 and /dev/null differ diff --git a/corpora/curl_fuzzer/test100_2 b/corpora/curl_fuzzer/test100_2 deleted file mode 100644 index 71411963d..000000000 Binary files a/corpora/curl_fuzzer/test100_2 and /dev/null differ diff --git a/corpora/curl_fuzzer/test100_3 b/corpora/curl_fuzzer/test100_3 deleted file mode 100644 index 9ba49bda6..000000000 Binary files a/corpora/curl_fuzzer/test100_3 and /dev/null differ diff --git a/corpora/curl_fuzzer/test1011 b/corpora/curl_fuzzer/test1011 deleted file mode 100644 index 505070a8e..000000000 Binary files a/corpora/curl_fuzzer/test1011 and /dev/null differ diff --git a/corpora/curl_fuzzer/test12 b/corpora/curl_fuzzer/test12 deleted file mode 100644 index 9ad91dc07..000000000 Binary files a/corpora/curl_fuzzer/test12 and /dev/null differ diff --git a/corpora/curl_fuzzer/test1201 b/corpora/curl_fuzzer/test1201 deleted file mode 100644 index 49a874662..000000000 Binary files a/corpora/curl_fuzzer/test1201 and /dev/null differ diff --git a/corpora/curl_fuzzer/test13 b/corpora/curl_fuzzer/test13 deleted file mode 100644 index 448077dde..000000000 Binary files a/corpora/curl_fuzzer/test13 and /dev/null differ diff --git a/corpora/curl_fuzzer/test1326 b/corpora/curl_fuzzer/test1326 deleted file mode 100644 index 8801fac96..000000000 Binary files a/corpora/curl_fuzzer/test1326 and /dev/null differ diff --git a/corpora/curl_fuzzer/test1450 b/corpora/curl_fuzzer/test1450 deleted file mode 100644 index 601236168..000000000 Binary files a/corpora/curl_fuzzer/test1450 and /dev/null differ diff --git a/corpora/curl_fuzzer/test2 b/corpora/curl_fuzzer/test2 deleted file mode 100644 index 8b44d6719..000000000 Binary files a/corpora/curl_fuzzer/test2 and /dev/null differ diff --git a/corpora/curl_fuzzer/test271 b/corpora/curl_fuzzer/test271 deleted file mode 100644 index 3a26767f7..000000000 Binary files a/corpora/curl_fuzzer/test271 and /dev/null differ diff --git a/corpora/curl_fuzzer/test3 b/corpora/curl_fuzzer/test3 deleted file mode 100644 index 81c6670aa..000000000 Binary files a/corpora/curl_fuzzer/test3 and /dev/null differ diff --git a/corpora/curl_fuzzer/test39 b/corpora/curl_fuzzer/test39 deleted file mode 100644 index 7fdb86743..000000000 Binary files a/corpora/curl_fuzzer/test39 and /dev/null differ diff --git a/corpora/curl_fuzzer/test4 b/corpora/curl_fuzzer/test4 deleted file mode 100644 index 3fa395a29..000000000 Binary files a/corpora/curl_fuzzer/test4 and /dev/null differ diff --git a/corpora/curl_fuzzer/test5 b/corpora/curl_fuzzer/test5 deleted file mode 100644 index bdaac4e66..000000000 Binary files a/corpora/curl_fuzzer/test5 and /dev/null differ diff --git a/corpora/curl_fuzzer/test567 b/corpora/curl_fuzzer/test567 deleted file mode 100644 index 752235435..000000000 Binary files a/corpora/curl_fuzzer/test567 and /dev/null differ diff --git a/corpora/curl_fuzzer/test6 b/corpora/curl_fuzzer/test6 deleted file mode 100644 index 98d9be216..000000000 Binary files a/corpora/curl_fuzzer/test6 and /dev/null differ diff --git a/corpora/curl_fuzzer/test64 b/corpora/curl_fuzzer/test64 deleted file mode 100644 index 31cfd0f1b..000000000 Binary files a/corpora/curl_fuzzer/test64 and /dev/null differ diff --git a/corpora/curl_fuzzer/test800 b/corpora/curl_fuzzer/test800 deleted file mode 100644 index a5899be43..000000000 Binary files a/corpora/curl_fuzzer/test800 and /dev/null differ diff --git a/corpora/curl_fuzzer/test800_2 b/corpora/curl_fuzzer/test800_2 deleted file mode 100644 index db1f130ed..000000000 Binary files a/corpora/curl_fuzzer/test800_2 and /dev/null differ diff --git a/corpora/curl_fuzzer/test850 b/corpora/curl_fuzzer/test850 deleted file mode 100644 index 22c08dcfc..000000000 Binary files a/corpora/curl_fuzzer/test850 and /dev/null differ diff --git a/corpora/curl_fuzzer/test900 b/corpora/curl_fuzzer/test900 deleted file mode 100644 index eecf0cbaf..000000000 Binary files a/corpora/curl_fuzzer/test900 and /dev/null differ diff --git a/corpora/curl_fuzzer/test900_2 b/corpora/curl_fuzzer/test900_2 deleted file mode 100644 index c27a76bc4..000000000 Binary files a/corpora/curl_fuzzer/test900_2 and /dev/null differ diff --git a/corpora/curl_fuzzer/test_accept_encoding b/corpora/curl_fuzzer/test_accept_encoding deleted file mode 100644 index 1ebdb7f71..000000000 Binary files a/corpora/curl_fuzzer/test_accept_encoding and /dev/null differ diff --git a/corpora/curl_fuzzer/test_file_nobody b/corpora/curl_fuzzer/test_file_nobody deleted file mode 100644 index ba1cf1864..000000000 Binary files a/corpora/curl_fuzzer/test_file_nobody and /dev/null differ diff --git a/corpora/curl_fuzzer/test_ftp_list b/corpora/curl_fuzzer/test_ftp_list deleted file mode 100644 index be90ebfe5..000000000 Binary files a/corpora/curl_fuzzer/test_ftp_list and /dev/null differ diff --git a/corpora/curl_fuzzer/test_ftp_wildcard b/corpora/curl_fuzzer/test_ftp_wildcard deleted file mode 100644 index e790dbc49..000000000 Binary files a/corpora/curl_fuzzer/test_ftp_wildcard and /dev/null differ diff --git a/corpora/curl_fuzzer/test_wrongproto b/corpora/curl_fuzzer/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer/timeout-4625841444093952 b/corpora/curl_fuzzer/timeout-4625841444093952 deleted file mode 100644 index 9a95f306a..000000000 Binary files a/corpora/curl_fuzzer/timeout-4625841444093952 and /dev/null differ diff --git a/corpora/curl_fuzzer_dict/test1450 b/corpora/curl_fuzzer_dict/test1450 deleted file mode 100644 index 601236168..000000000 Binary files a/corpora/curl_fuzzer_dict/test1450 and /dev/null differ diff --git a/corpora/curl_fuzzer_dict/test_url_dict b/corpora/curl_fuzzer_dict/test_url_dict deleted file mode 100644 index 4e45bad57..000000000 Binary files a/corpora/curl_fuzzer_dict/test_url_dict and /dev/null differ diff --git a/corpora/curl_fuzzer_dict/test_wrongproto b/corpora/curl_fuzzer_dict/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_dict/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_file/test_file_nobody b/corpora/curl_fuzzer_file/test_file_nobody deleted file mode 100644 index ba1cf1864..000000000 Binary files a/corpora/curl_fuzzer_file/test_file_nobody and /dev/null differ diff --git a/corpora/curl_fuzzer_file/test_url_file b/corpora/curl_fuzzer_file/test_url_file deleted file mode 100644 index 156a8e0df..000000000 Binary files a/corpora/curl_fuzzer_file/test_url_file and /dev/null differ diff --git a/corpora/curl_fuzzer_file/test_wrongproto b/corpora/curl_fuzzer_file/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_file/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_ftp/test_ftp_list b/corpora/curl_fuzzer_ftp/test_ftp_list deleted file mode 100644 index be90ebfe5..000000000 Binary files a/corpora/curl_fuzzer_ftp/test_ftp_list and /dev/null differ diff --git a/corpora/curl_fuzzer_ftp/test_ftp_wildcard b/corpora/curl_fuzzer_ftp/test_ftp_wildcard deleted file mode 100644 index e790dbc49..000000000 Binary files a/corpora/curl_fuzzer_ftp/test_ftp_wildcard and /dev/null differ diff --git a/corpora/curl_fuzzer_ftp/test_url_ftp b/corpora/curl_fuzzer_ftp/test_url_ftp deleted file mode 100644 index 23670bf36..000000000 Binary files a/corpora/curl_fuzzer_ftp/test_url_ftp and /dev/null differ diff --git a/corpora/curl_fuzzer_ftp/test_wrongproto b/corpora/curl_fuzzer_ftp/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_ftp/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_gopher/test1201 b/corpora/curl_fuzzer_gopher/test1201 deleted file mode 100644 index 49a874662..000000000 Binary files a/corpora/curl_fuzzer_gopher/test1201 and /dev/null differ diff --git a/corpora/curl_fuzzer_gopher/test_url_gopher b/corpora/curl_fuzzer_gopher/test_url_gopher deleted file mode 100644 index d35959ff2..000000000 Binary files a/corpora/curl_fuzzer_gopher/test_url_gopher and /dev/null differ diff --git a/corpora/curl_fuzzer_gopher/test_wrongproto b/corpora/curl_fuzzer_gopher/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_gopher/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test1 b/corpora/curl_fuzzer_http/test1 deleted file mode 100644 index f7b734a9c..000000000 Binary files a/corpora/curl_fuzzer_http/test1 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test10 b/corpora/curl_fuzzer_http/test10 deleted file mode 100644 index af1ed53ca..000000000 Binary files a/corpora/curl_fuzzer_http/test10 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test100 b/corpora/curl_fuzzer_http/test100 deleted file mode 100644 index b58d9335a..000000000 Binary files a/corpora/curl_fuzzer_http/test100 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test100_2 b/corpora/curl_fuzzer_http/test100_2 deleted file mode 100644 index 71411963d..000000000 Binary files a/corpora/curl_fuzzer_http/test100_2 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test100_3 b/corpora/curl_fuzzer_http/test100_3 deleted file mode 100644 index 9ba49bda6..000000000 Binary files a/corpora/curl_fuzzer_http/test100_3 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test1011 b/corpora/curl_fuzzer_http/test1011 deleted file mode 100644 index 505070a8e..000000000 Binary files a/corpora/curl_fuzzer_http/test1011 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test12 b/corpora/curl_fuzzer_http/test12 deleted file mode 100644 index 9ad91dc07..000000000 Binary files a/corpora/curl_fuzzer_http/test12 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test1201 b/corpora/curl_fuzzer_http/test1201 deleted file mode 100644 index 49a874662..000000000 Binary files a/corpora/curl_fuzzer_http/test1201 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test13 b/corpora/curl_fuzzer_http/test13 deleted file mode 100644 index 448077dde..000000000 Binary files a/corpora/curl_fuzzer_http/test13 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test1326 b/corpora/curl_fuzzer_http/test1326 deleted file mode 100644 index 8801fac96..000000000 Binary files a/corpora/curl_fuzzer_http/test1326 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test1450 b/corpora/curl_fuzzer_http/test1450 deleted file mode 100644 index 601236168..000000000 Binary files a/corpora/curl_fuzzer_http/test1450 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test2 b/corpora/curl_fuzzer_http/test2 deleted file mode 100644 index 8b44d6719..000000000 Binary files a/corpora/curl_fuzzer_http/test2 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test271 b/corpora/curl_fuzzer_http/test271 deleted file mode 100644 index 3a26767f7..000000000 Binary files a/corpora/curl_fuzzer_http/test271 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test3 b/corpora/curl_fuzzer_http/test3 deleted file mode 100644 index 81c6670aa..000000000 Binary files a/corpora/curl_fuzzer_http/test3 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test39 b/corpora/curl_fuzzer_http/test39 deleted file mode 100644 index 7fdb86743..000000000 Binary files a/corpora/curl_fuzzer_http/test39 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test4 b/corpora/curl_fuzzer_http/test4 deleted file mode 100644 index 3fa395a29..000000000 Binary files a/corpora/curl_fuzzer_http/test4 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test5 b/corpora/curl_fuzzer_http/test5 deleted file mode 100644 index bdaac4e66..000000000 Binary files a/corpora/curl_fuzzer_http/test5 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test567 b/corpora/curl_fuzzer_http/test567 deleted file mode 100644 index 752235435..000000000 Binary files a/corpora/curl_fuzzer_http/test567 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test6 b/corpora/curl_fuzzer_http/test6 deleted file mode 100644 index 98d9be216..000000000 Binary files a/corpora/curl_fuzzer_http/test6 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test64 b/corpora/curl_fuzzer_http/test64 deleted file mode 100644 index 31cfd0f1b..000000000 Binary files a/corpora/curl_fuzzer_http/test64 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test800 b/corpora/curl_fuzzer_http/test800 deleted file mode 100644 index a5899be43..000000000 Binary files a/corpora/curl_fuzzer_http/test800 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test800_2 b/corpora/curl_fuzzer_http/test800_2 deleted file mode 100644 index db1f130ed..000000000 Binary files a/corpora/curl_fuzzer_http/test800_2 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test850 b/corpora/curl_fuzzer_http/test850 deleted file mode 100644 index 22c08dcfc..000000000 Binary files a/corpora/curl_fuzzer_http/test850 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test900 b/corpora/curl_fuzzer_http/test900 deleted file mode 100644 index eecf0cbaf..000000000 Binary files a/corpora/curl_fuzzer_http/test900 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test900_2 b/corpora/curl_fuzzer_http/test900_2 deleted file mode 100644 index c27a76bc4..000000000 Binary files a/corpora/curl_fuzzer_http/test900_2 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_accept_encoding b/corpora/curl_fuzzer_http/test_accept_encoding deleted file mode 100644 index 1ebdb7f71..000000000 Binary files a/corpora/curl_fuzzer_http/test_accept_encoding and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_alt_svc b/corpora/curl_fuzzer_http/test_alt_svc deleted file mode 100644 index 8c32f46e0..000000000 Binary files a/corpora/curl_fuzzer_http/test_alt_svc and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_alt_svc_with_ma b/corpora/curl_fuzzer_http/test_alt_svc_with_ma deleted file mode 100644 index dca084d36..000000000 Binary files a/corpora/curl_fuzzer_http/test_alt_svc_with_ma and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_basic_http2 b/corpora/curl_fuzzer_http/test_basic_http2 deleted file mode 100644 index dc4f94f32..000000000 Binary files a/corpora/curl_fuzzer_http/test_basic_http2 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_cookie_control_code_hackerone_1613943 b/corpora/curl_fuzzer_http/test_cookie_control_code_hackerone_1613943 deleted file mode 100644 index 1c4fd4824..000000000 Binary files a/corpora/curl_fuzzer_http/test_cookie_control_code_hackerone_1613943 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_http_upgrade_to_ws b/corpora/curl_fuzzer_http/test_http_upgrade_to_ws deleted file mode 100644 index efddfedaf..000000000 Binary files a/corpora/curl_fuzzer_http/test_http_upgrade_to_ws and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_http_upgrade_to_ws_and_detach b/corpora/curl_fuzzer_http/test_http_upgrade_to_ws_and_detach deleted file mode 100644 index c04a9fd76..000000000 Binary files a/corpora/curl_fuzzer_http/test_http_upgrade_to_ws_and_detach and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_http_with_hsts b/corpora/curl_fuzzer_http/test_http_with_hsts deleted file mode 100644 index 4771f6b6e..000000000 Binary files a/corpora/curl_fuzzer_http/test_http_with_hsts and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_http_with_hsts_tlv b/corpora/curl_fuzzer_http/test_http_with_hsts_tlv deleted file mode 100644 index 8f06e2cdb..000000000 Binary files a/corpora/curl_fuzzer_http/test_http_with_hsts_tlv and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_invalid_prior_http2 b/corpora/curl_fuzzer_http/test_invalid_prior_http2 deleted file mode 100644 index 19cc2594f..000000000 Binary files a/corpora/curl_fuzzer_http/test_invalid_prior_http2 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_ipv6 b/corpora/curl_fuzzer_http/test_ipv6 deleted file mode 100644 index fd12f402d..000000000 Binary files a/corpora/curl_fuzzer_http/test_ipv6 and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_ntlm b/corpora/curl_fuzzer_http/test_ntlm deleted file mode 100644 index ead206fae..000000000 Binary files a/corpora/curl_fuzzer_http/test_ntlm and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_ntlm_wb b/corpora/curl_fuzzer_http/test_ntlm_wb deleted file mode 100644 index fd87bc15d..000000000 Binary files a/corpora/curl_fuzzer_http/test_ntlm_wb and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_url_http b/corpora/curl_fuzzer_http/test_url_http deleted file mode 100644 index f6d5c39a0..000000000 Binary files a/corpora/curl_fuzzer_http/test_url_http and /dev/null differ diff --git a/corpora/curl_fuzzer_http/test_wrongproto b/corpora/curl_fuzzer_http/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_http/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_alt_svc_with_double_header b/corpora/curl_fuzzer_https/test_alt_svc_with_double_header deleted file mode 100644 index 772df0889..000000000 Binary files a/corpora/curl_fuzzer_https/test_alt_svc_with_double_header and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_alt_svc_with_ma b/corpora/curl_fuzzer_https/test_alt_svc_with_ma deleted file mode 100644 index 3cbce5fa7..000000000 Binary files a/corpora/curl_fuzzer_https/test_alt_svc_with_ma and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_altsvc_with_cache b/corpora/curl_fuzzer_https/test_altsvc_with_cache deleted file mode 100644 index 2b80529e4..000000000 Binary files a/corpora/curl_fuzzer_https/test_altsvc_with_cache and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_hsts_response b/corpora/curl_fuzzer_https/test_hsts_response deleted file mode 100644 index 2fc628c52..000000000 Binary files a/corpora/curl_fuzzer_https/test_hsts_response and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_hsts_response_to_ipv6 b/corpora/curl_fuzzer_https/test_hsts_response_to_ipv6 deleted file mode 100644 index fd3bc439b..000000000 Binary files a/corpora/curl_fuzzer_https/test_hsts_response_to_ipv6 and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_http_version_2 b/corpora/curl_fuzzer_https/test_http_version_2 deleted file mode 100644 index 0e5d4ecb6..000000000 Binary files a/corpora/curl_fuzzer_https/test_http_version_2 and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_https_ntlm b/corpora/curl_fuzzer_https/test_https_ntlm deleted file mode 100644 index cc09dedcb..000000000 Binary files a/corpora/curl_fuzzer_https/test_https_ntlm and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_ipv6 b/corpora/curl_fuzzer_https/test_ipv6 deleted file mode 100644 index 56f05f6e3..000000000 Binary files a/corpora/curl_fuzzer_https/test_ipv6 and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_post_0byte b/corpora/curl_fuzzer_https/test_post_0byte deleted file mode 100644 index 703451b8c..000000000 Binary files a/corpora/curl_fuzzer_https/test_post_0byte and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_simple_httppost b/corpora/curl_fuzzer_https/test_simple_httppost deleted file mode 100644 index e7e295dc7..000000000 Binary files a/corpora/curl_fuzzer_https/test_simple_httppost and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_url b/corpora/curl_fuzzer_https/test_url deleted file mode 100644 index 9071f6b05..000000000 Binary files a/corpora/curl_fuzzer_https/test_url and /dev/null differ diff --git a/corpora/curl_fuzzer_https/test_wrongproto b/corpora/curl_fuzzer_https/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_https/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_imap/test800 b/corpora/curl_fuzzer_imap/test800 deleted file mode 100644 index a5899be43..000000000 Binary files a/corpora/curl_fuzzer_imap/test800 and /dev/null differ diff --git a/corpora/curl_fuzzer_imap/test800_2 b/corpora/curl_fuzzer_imap/test800_2 deleted file mode 100644 index db1f130ed..000000000 Binary files a/corpora/curl_fuzzer_imap/test800_2 and /dev/null differ diff --git a/corpora/curl_fuzzer_imap/test_oauthed_imap b/corpora/curl_fuzzer_imap/test_oauthed_imap deleted file mode 100644 index efbb4b01d..000000000 Binary files a/corpora/curl_fuzzer_imap/test_oauthed_imap and /dev/null differ diff --git a/corpora/curl_fuzzer_imap/test_url_imap b/corpora/curl_fuzzer_imap/test_url_imap deleted file mode 100644 index 3999320d2..000000000 Binary files a/corpora/curl_fuzzer_imap/test_url_imap and /dev/null differ diff --git a/corpora/curl_fuzzer_imap/test_wrongproto b/corpora/curl_fuzzer_imap/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_imap/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_ldap/test_url_fullldap b/corpora/curl_fuzzer_ldap/test_url_fullldap deleted file mode 100644 index 6a85db38e..000000000 Binary files a/corpora/curl_fuzzer_ldap/test_url_fullldap and /dev/null differ diff --git a/corpora/curl_fuzzer_ldap/test_url_ldap b/corpora/curl_fuzzer_ldap/test_url_ldap deleted file mode 100644 index 2ca84b43a..000000000 Binary files a/corpora/curl_fuzzer_ldap/test_url_ldap and /dev/null differ diff --git a/corpora/curl_fuzzer_ldap/test_wrongproto b/corpora/curl_fuzzer_ldap/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_ldap/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_mqtt/test_dummy b/corpora/curl_fuzzer_mqtt/test_dummy deleted file mode 100644 index 22e7a7853..000000000 Binary files a/corpora/curl_fuzzer_mqtt/test_dummy and /dev/null differ diff --git a/corpora/curl_fuzzer_pop3/test850 b/corpora/curl_fuzzer_pop3/test850 deleted file mode 100644 index 22c08dcfc..000000000 Binary files a/corpora/curl_fuzzer_pop3/test850 and /dev/null differ diff --git a/corpora/curl_fuzzer_pop3/test_oauthed_pop3 b/corpora/curl_fuzzer_pop3/test_oauthed_pop3 deleted file mode 100644 index 63fb32147..000000000 Binary files a/corpora/curl_fuzzer_pop3/test_oauthed_pop3 and /dev/null differ diff --git a/corpora/curl_fuzzer_pop3/test_url_pop3 b/corpora/curl_fuzzer_pop3/test_url_pop3 deleted file mode 100644 index 9154cdb93..000000000 Binary files a/corpora/curl_fuzzer_pop3/test_url_pop3 and /dev/null differ diff --git a/corpora/curl_fuzzer_pop3/test_wrongproto b/corpora/curl_fuzzer_pop3/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_pop3/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_rtmp/test_url_rtmp b/corpora/curl_fuzzer_rtmp/test_url_rtmp deleted file mode 100644 index 68eb9b187..000000000 Binary files a/corpora/curl_fuzzer_rtmp/test_url_rtmp and /dev/null differ diff --git a/corpora/curl_fuzzer_rtmp/test_wrongproto b/corpora/curl_fuzzer_rtmp/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_rtmp/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/oss-fuzz-issue-6937 b/corpora/curl_fuzzer_rtsp/oss-fuzz-issue-6937 deleted file mode 100644 index d7e040d3d..000000000 Binary files a/corpora/curl_fuzzer_rtsp/oss-fuzz-issue-6937 and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/test567 b/corpora/curl_fuzzer_rtsp/test567 deleted file mode 100644 index 752235435..000000000 Binary files a/corpora/curl_fuzzer_rtsp/test567 and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/test_rtsp_client_cseq b/corpora/curl_fuzzer_rtsp/test_rtsp_client_cseq deleted file mode 100644 index 6d9845d24..000000000 Binary files a/corpora/curl_fuzzer_rtsp/test_rtsp_client_cseq and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/test_rtsp_request b/corpora/curl_fuzzer_rtsp/test_rtsp_request deleted file mode 100644 index 9641005ea..000000000 Binary files a/corpora/curl_fuzzer_rtsp/test_rtsp_request and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/test_rtsp_request2 b/corpora/curl_fuzzer_rtsp/test_rtsp_request2 deleted file mode 100644 index dfbe7beef..000000000 Binary files a/corpora/curl_fuzzer_rtsp/test_rtsp_request2 and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/test_rtsp_session_id b/corpora/curl_fuzzer_rtsp/test_rtsp_session_id deleted file mode 100644 index 2f26ffc2b..000000000 Binary files a/corpora/curl_fuzzer_rtsp/test_rtsp_session_id and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/test_rtsp_stream_uri b/corpora/curl_fuzzer_rtsp/test_rtsp_stream_uri deleted file mode 100644 index 5e65c531c..000000000 Binary files a/corpora/curl_fuzzer_rtsp/test_rtsp_stream_uri and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/test_rtsp_transport b/corpora/curl_fuzzer_rtsp/test_rtsp_transport deleted file mode 100644 index db26d78e9..000000000 Binary files a/corpora/curl_fuzzer_rtsp/test_rtsp_transport and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/test_url_rtsp b/corpora/curl_fuzzer_rtsp/test_url_rtsp deleted file mode 100644 index ff11ff50a..000000000 Binary files a/corpora/curl_fuzzer_rtsp/test_url_rtsp and /dev/null differ diff --git a/corpora/curl_fuzzer_rtsp/test_wrongproto b/corpora/curl_fuzzer_rtsp/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_rtsp/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_scp/test_url_scp b/corpora/curl_fuzzer_scp/test_url_scp deleted file mode 100644 index 051bdd475..000000000 Binary files a/corpora/curl_fuzzer_scp/test_url_scp and /dev/null differ diff --git a/corpora/curl_fuzzer_scp/test_wrongproto b/corpora/curl_fuzzer_scp/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_scp/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_sftp/test_url_sftp b/corpora/curl_fuzzer_sftp/test_url_sftp deleted file mode 100644 index 2c6762ede..000000000 Binary files a/corpora/curl_fuzzer_sftp/test_url_sftp and /dev/null differ diff --git a/corpora/curl_fuzzer_sftp/test_wrongproto b/corpora/curl_fuzzer_sftp/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_sftp/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_smb/test_url_smb b/corpora/curl_fuzzer_smb/test_url_smb deleted file mode 100644 index 4c69eb28b..000000000 Binary files a/corpora/curl_fuzzer_smb/test_url_smb and /dev/null differ diff --git a/corpora/curl_fuzzer_smb/test_wrongproto b/corpora/curl_fuzzer_smb/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_smb/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_smtp/test900 b/corpora/curl_fuzzer_smtp/test900 deleted file mode 100644 index eecf0cbaf..000000000 Binary files a/corpora/curl_fuzzer_smtp/test900 and /dev/null differ diff --git a/corpora/curl_fuzzer_smtp/test900_2 b/corpora/curl_fuzzer_smtp/test900_2 deleted file mode 100644 index c27a76bc4..000000000 Binary files a/corpora/curl_fuzzer_smtp/test900_2 and /dev/null differ diff --git a/corpora/curl_fuzzer_smtp/test_mail_auth b/corpora/curl_fuzzer_smtp/test_mail_auth deleted file mode 100644 index 5602ac4f2..000000000 Binary files a/corpora/curl_fuzzer_smtp/test_mail_auth and /dev/null differ diff --git a/corpora/curl_fuzzer_smtp/test_smtps_with_oauth b/corpora/curl_fuzzer_smtp/test_smtps_with_oauth deleted file mode 100644 index b7864e9b5..000000000 Binary files a/corpora/curl_fuzzer_smtp/test_smtps_with_oauth and /dev/null differ diff --git a/corpora/curl_fuzzer_smtp/test_url_smtp b/corpora/curl_fuzzer_smtp/test_url_smtp deleted file mode 100644 index c98e4bd6e..000000000 Binary files a/corpora/curl_fuzzer_smtp/test_url_smtp and /dev/null differ diff --git a/corpora/curl_fuzzer_smtp/test_wrongproto b/corpora/curl_fuzzer_smtp/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_smtp/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_tftp/test_url_tftp b/corpora/curl_fuzzer_tftp/test_url_tftp deleted file mode 100644 index 86788d89a..000000000 Binary files a/corpora/curl_fuzzer_tftp/test_url_tftp and /dev/null differ diff --git a/corpora/curl_fuzzer_tftp/test_wrongproto b/corpora/curl_fuzzer_tftp/test_wrongproto deleted file mode 100644 index 711323a26..000000000 Binary files a/corpora/curl_fuzzer_tftp/test_wrongproto and /dev/null differ diff --git a/corpora/curl_fuzzer_ws/basictest b/corpora/curl_fuzzer_ws/basictest deleted file mode 100644 index 89341fb54..000000000 Binary files a/corpora/curl_fuzzer_ws/basictest and /dev/null differ diff --git a/corpora/curl_fuzzer_ws/test_http_upgrade_to_ws b/corpora/curl_fuzzer_ws/test_http_upgrade_to_ws deleted file mode 100644 index a0e449468..000000000 Binary files a/corpora/curl_fuzzer_ws/test_http_upgrade_to_ws and /dev/null differ diff --git a/corpora/curl_fuzzer_ws/ws_with_raw_mode_connect_test b/corpora/curl_fuzzer_ws/ws_with_raw_mode_connect_test deleted file mode 100644 index 6a3c3bfb7..000000000 Binary files a/corpora/curl_fuzzer_ws/ws_with_raw_mode_connect_test and /dev/null differ diff --git a/corpora/curl_fuzzer_ws/ws_with_raw_mode_test b/corpora/curl_fuzzer_ws/ws_with_raw_mode_test deleted file mode 100644 index eb285386e..000000000 Binary files a/corpora/curl_fuzzer_ws/ws_with_raw_mode_test and /dev/null differ diff --git a/corpora/curl_fuzzer_ws/wss_test b/corpora/curl_fuzzer_ws/wss_test deleted file mode 100644 index a44a15801..000000000 Binary files a/corpora/curl_fuzzer_ws/wss_test and /dev/null differ diff --git a/corpora/curl_fuzzer_ws/wss_with_basic_auth_test b/corpora/curl_fuzzer_ws/wss_with_basic_auth_test deleted file mode 100644 index 72003a778..000000000 Binary files a/corpora/curl_fuzzer_ws/wss_with_basic_auth_test and /dev/null differ diff --git a/curl_fuzzer.cc b/curl_fuzzer.cc index 0eccea806..41555041e 100644 --- a/curl_fuzzer.cc +++ b/curl_fuzzer.cc @@ -26,17 +26,32 @@ #include #include #include "curl_fuzzer.h" +#include "curl_fuzzer_scenario.h" -/** - * Fuzzing entry point. This function is passed a buffer containing a test - * case. This test case should drive the CURL API into making a request. - */ -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +#include + +namespace { + +bool FuzzOptionIsSet(const FUZZ_DATA *fuzz, CURLoption opt) +{ + size_t idx = static_cast(opt % 1000); + if(idx >= FUZZ_CURLOPT_TRACKER_SPACE) { + return false; + } + return fuzz->options[idx] != 0; +} + +} // namespace + +DEFINE_BINARY_PROTO_FUZZER(const curl::fuzzer::proto::Scenario &scenario) +{ + CurlFuzzerRunScenario(scenario); +} + +int CurlFuzzerRunScenario(const curl::fuzzer::proto::Scenario &scenario) { int rc = 0; - int tlv_rc; FUZZ_DATA fuzz; - TLV tlv; /* Ignore SIGPIPE errors. We'll handle the errors ourselves. */ signal(SIGPIPE, SIG_IGN); @@ -44,38 +59,33 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) /* Have to set all fields to zero before getting to the terminate function */ memset(&fuzz, 0, sizeof(FUZZ_DATA)); - if(size < sizeof(TLV_RAW)) { - /* Not enough data for a single TLV - don't continue */ - goto EXIT_LABEL; - } - /* Try to initialize the fuzz data */ - FTRY(fuzz_initialize_fuzz_data(&fuzz, data, size)); - - for(tlv_rc = fuzz_get_first_tlv(&fuzz, &tlv); - tlv_rc == 0; - tlv_rc = fuzz_get_next_tlv(&fuzz, &tlv)) { - - /* Have the TLV in hand. Parse the TLV. */ - rc = fuzz_parse_tlv(&fuzz, &tlv); + FTRY(fuzz_initialize_fuzz_data(&fuzz)); - if(rc != 0) { - /* Failed to parse the TLV. Can't continue. */ - goto EXIT_LABEL; - } + rc = curl_fuzzer::ApplyScenario(scenario, &fuzz); + if(rc != 0) { + FV_PRINTF(&fuzz, "SCENARIO: ApplyScenario failed with rc=%d\n", rc); + goto EXIT_LABEL; } - if(tlv_rc != TLV_RC_NO_MORE_TLVS) { - /* A TLV call failed. Can't continue. */ + if(!FuzzOptionIsSet(&fuzz, CURLOPT_URL)) { + FV_PRINTF(&fuzz, "SCENARIO: skipping transfer due to missing CURLOPT_URL\n"); goto EXIT_LABEL; } + FV_PRINTF(&fuzz, + "SCENARIO: successfully applied scenario, starting transfer\n"); + /* Set up the standard easy options. */ - FTRY(fuzz_set_easy_options(&fuzz)); + rc = fuzz_set_easy_options(&fuzz); + if(rc != 0) { + FV_PRINTF(&fuzz, "SCENARIO: fuzz_set_easy_options failed with rc=%d\n", rc); + goto EXIT_LABEL; + } /** - * Add in more curl options that have been accumulated over possibly - * multiple TLVs. + * Add in more curl options that have been accumulated over the scenario + * execution. */ if(fuzz.header_list != NULL) { curl_easy_setopt(fuzz.easy, CURLOPT_HTTPHEADER, fuzz.header_list); @@ -104,6 +114,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) return 0; } + /** * Utility function to convert 4 bytes to a u32 predictably. */ @@ -127,15 +138,15 @@ uint16_t to_u16(const uint8_t b[2]) /** * Initialize the local fuzz data structure. */ -int fuzz_initialize_fuzz_data(FUZZ_DATA *fuzz, - const uint8_t *data, - size_t data_len) +int fuzz_initialize_fuzz_data(FUZZ_DATA *fuzz) { int rc = 0; int ii; /* Initialize the fuzz data. */ memset(fuzz, 0, sizeof(FUZZ_DATA)); + fuzz->scenario_state = NULL; + fuzz->scenario_state_destructor = NULL; /* Create an easy handle. This will have all of the settings configured on it. */ @@ -143,8 +154,9 @@ int fuzz_initialize_fuzz_data(FUZZ_DATA *fuzz, FCHECK(fuzz->easy != NULL); /* Set up the state parser */ - fuzz->state.data = data; - fuzz->state.data_len = data_len; + fuzz->state.data = NULL; + fuzz->state.data_len = 0; + fuzz->state.data_pos = 0; /* Set up the state of the server sockets. */ for(ii = 0; ii < FUZZ_NUM_CONNECTIONS; ii++) { @@ -275,6 +287,12 @@ void fuzz_terminate_fuzz_data(FUZZ_DATA *fuzz) fuzz->easy = NULL; } + if(fuzz->scenario_state_destructor != NULL && fuzz->scenario_state != NULL) { + fuzz->scenario_state_destructor(fuzz->scenario_state); + fuzz->scenario_state = NULL; + fuzz->scenario_state_destructor = NULL; + } + /* When you have passed the struct curl_httppost pointer to curl_easy_setopt * (using the CURLOPT_HTTPPOST option), you must not free the list until after * you have called curl_easy_cleanup for the curl handle. @@ -283,6 +301,7 @@ void fuzz_terminate_fuzz_data(FUZZ_DATA *fuzz) curl_formfree(fuzz->httppost); fuzz->httppost = NULL; } + fuzz->last_post_part = NULL; // free after httppost and last_post_part. if (fuzz->post_body != NULL) { @@ -575,7 +594,7 @@ int fuzz_set_allowed_protocols(FUZZ_DATA *fuzz) allowed_protocols = "http,ws,wss"; FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_CONNECT_ONLY, 2L)); #endif - + FV_PRINTF(fuzz, "allowed_protocols=%s\n", allowed_protocols); FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_PROTOCOLS_STR, allowed_protocols)); EXIT_LABEL: diff --git a/curl_fuzzer.h b/curl_fuzzer.h index 1e13d710b..d45655f3e 100644 --- a/curl_fuzzer.h +++ b/curl_fuzzer.h @@ -1,3 +1,6 @@ +#ifndef CURL_FUZZER_H +#define CURL_FUZZER_H + /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -23,6 +26,14 @@ #include #include "testinput.h" +namespace curl { +namespace fuzzer { +namespace proto { +class Scenario; +} // namespace proto +} // namespace fuzzer +} // namespace curl + /** * TLV types. */ @@ -433,14 +444,16 @@ typedef struct fuzz_data /* Verbose mode. */ int verbose; + /* Optional structured scenario ownership hook. */ + void *scenario_state; + void (*scenario_state_destructor)(void *state); + } FUZZ_DATA; /* Function prototypes */ uint32_t to_u32(const uint8_t b[4]); uint16_t to_u16(const uint8_t b[2]); -int fuzz_initialize_fuzz_data(FUZZ_DATA *fuzz, - const uint8_t *data, - size_t data_len); +int fuzz_initialize_fuzz_data(FUZZ_DATA *fuzz); int fuzz_set_easy_options(FUZZ_DATA *fuzz); void fuzz_terminate_fuzz_data(FUZZ_DATA *fuzz); void fuzz_free(void **ptr); @@ -474,6 +487,7 @@ int fuzz_select(int nfds, fd_set *exceptfds, struct timeval *timeout); int fuzz_set_allowed_protocols(FUZZ_DATA *fuzz); +int CurlFuzzerRunScenario(const curl::fuzzer::proto::Scenario &scenario); /* Macros */ #define FTRY(FUNC) \ @@ -481,6 +495,7 @@ int fuzz_set_allowed_protocols(FUZZ_DATA *fuzz); int _func_rc = (FUNC); \ if (_func_rc) \ { \ + fprintf(stderr, "FTRY failed: %s returned %d\n", #FUNC, _func_rc); \ rc = _func_rc; \ goto EXIT_LABEL; \ } \ @@ -532,3 +547,5 @@ int fuzz_set_allowed_protocols(FUZZ_DATA *fuzz); } #define FUZZ_MAX(A, B) ((A) > (B) ? (A) : (B)) + +#endif /* CURL_FUZZER_H */ diff --git a/curl_fuzzer_scenario.cc b/curl_fuzzer_scenario.cc new file mode 100644 index 000000000..a61ec34ca --- /dev/null +++ b/curl_fuzzer_scenario.cc @@ -0,0 +1,1033 @@ +#include "curl_fuzzer_scenario.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace curl_fuzzer { +namespace { + +enum class OptionValueKind { + kUnknown, + kString, + kUint32, + kUint64, + kBool, + kHttpPost, + kMime, +}; + +struct OptionDescriptor { + curl::fuzzer::proto::CurlOptionId id; + OptionValueKind kind; + bool singleton; + const char *name; + CURLoption curlopt; +}; + +#include "generated/curl_fuzzer_option_manifest.inc" + +const OptionDescriptor *LookupDescriptor(curl::fuzzer::proto::CurlOptionId id) { + for(size_t ii = 0; ii < kOptionManifestSize; ++ii) { + if(kOptionManifest[ii].id == id) { + return &kOptionManifest[ii]; + } + } + return nullptr; +} + +// Human-readable label for logging; keeps prints decipherable instead of raw enums. +const char *OptionScopeName(curl::fuzzer::proto::OptionScope scope) { + switch(scope) { + case curl::fuzzer::proto::OPTION_SCOPE_UNSPECIFIED: + return "unspecified"; + case curl::fuzzer::proto::OPTION_SCOPE_DEFAULT: + return "default"; + case curl::fuzzer::proto::OPTION_SCOPE_PROXY: + return "proxy"; + case curl::fuzzer::proto::OPTION_SCOPE_DOH: + return "doh"; + case curl::fuzzer::proto::OPTION_SCOPE_TLS: + return "tls"; + case curl::fuzzer::proto::OptionScope_INT_MIN_SENTINEL_DO_NOT_USE_: + case curl::fuzzer::proto::OptionScope_INT_MAX_SENTINEL_DO_NOT_USE_: + return "sentinel"; + } + return "unknown"; +} + +// Logs use textual names for transfer kinds so scenario traces stay readable. +const char *TransferKindName(curl::fuzzer::proto::TransferKind kind) { + switch(kind) { + case curl::fuzzer::proto::TRANSFER_KIND_UNSPECIFIED: + return "unspecified"; + case curl::fuzzer::proto::TRANSFER_KIND_UPLOAD: + return "upload"; + case curl::fuzzer::proto::TRANSFER_KIND_POSTFIELDS: + return "postfields"; + case curl::fuzzer::proto::TRANSFER_KIND_SEND: + return "send"; + case curl::fuzzer::proto::TransferKind_INT_MIN_SENTINEL_DO_NOT_USE_: + case curl::fuzzer::proto::TransferKind_INT_MAX_SENTINEL_DO_NOT_USE_: + return "sentinel"; + } + return "unknown"; +} + +// The fuzzer prints stage transitions; mapping the enum keeps diagnostics obvious. +const char *ResponseStageName(curl::fuzzer::proto::ResponseStage stage) { + switch(stage) { + case curl::fuzzer::proto::RESPONSE_STAGE_UNSPECIFIED: + return "unspecified"; + case curl::fuzzer::proto::RESPONSE_STAGE_ON_CONNECT: + return "on_connect"; + case curl::fuzzer::proto::RESPONSE_STAGE_ON_READABLE: + return "on_readable"; + case curl::fuzzer::proto::ResponseStage_INT_MIN_SENTINEL_DO_NOT_USE_: + case curl::fuzzer::proto::ResponseStage_INT_MAX_SENTINEL_DO_NOT_USE_: + return "sentinel"; + } + return "unknown"; +} + +// Shutdown policies surface in verbose traces; stringifying the enum clarifies intent. +const char *ShutdownPolicyName(curl::fuzzer::proto::ShutdownPolicy policy) { + switch(policy) { + case curl::fuzzer::proto::SHUTDOWN_POLICY_UNSPECIFIED: + return "unspecified"; + case curl::fuzzer::proto::SHUTDOWN_POLICY_HALF_CLOSE_AFTER_LAST_RESPONSE: + return "half_close"; + case curl::fuzzer::proto::SHUTDOWN_POLICY_KEEP_OPEN: + return "keep_open"; + case curl::fuzzer::proto::SHUTDOWN_POLICY_CLOSE_IMMEDIATELY: + return "close_immediately"; + case curl::fuzzer::proto::ShutdownPolicy_INT_MIN_SENTINEL_DO_NOT_USE_: + case curl::fuzzer::proto::ShutdownPolicy_INT_MAX_SENTINEL_DO_NOT_USE_: + return "sentinel"; + } + return "unknown"; +} + +std::string SanitizedSnippet(std::string_view data, size_t max_len = 64) { + std::string out; + size_t limit = std::min(data.size(), max_len); + out.reserve(limit * 4); + for(size_t ii = 0; ii < limit; ++ii) { + unsigned char ch = static_cast(data[ii]); + if(std::isprint(ch) && ch != '\\' && ch != '"') { + out.push_back(static_cast(ch)); + } + else { + char buf[5]; + std::snprintf(buf, sizeof(buf), "\\x%02X", ch); + out.append(buf); + } + } + if(data.size() > limit) { + out.append("…"); + } + return out; +} + +std::string HexSnippet(std::string_view data, size_t max_len = 16) { + static constexpr char kHexDigits[] = "0123456789ABCDEF"; + std::string out; + size_t limit = std::min(data.size(), max_len); + out.reserve(limit * 3); + for(size_t ii = 0; ii < limit; ++ii) { + unsigned char ch = static_cast(data[ii]); + if(ii > 0) { + out.push_back(' '); + } + out.push_back(kHexDigits[(ch >> 4) & 0x0F]); + out.push_back(kHexDigits[ch & 0x0F]); + } + if(data.size() > limit) { + out.append(" …"); + } + return out; +} + +// Helper summaries annotate verbose logging without dumping entire buffers. +std::string SummarizeText(std::string_view data) { + std::string summary = "len=" + std::to_string(data.size()); + summary.append(" text=\""); + summary.append(SanitizedSnippet(data, 80)); + summary.push_back('"'); + return summary; +} + +// Presents binary payloads in a compact mixed hex/text form for diagnostics. +std::string SummarizeBinary(std::string_view data) { + std::string summary = "len=" + std::to_string(data.size()); + if(!data.empty()) { + summary.append(" hex=["); + summary.append(HexSnippet(data, 16)); + summary.append("] ascii=\""); + summary.append(SanitizedSnippet(data, 32)); + summary.push_back('"'); + } + return summary; +} + +// Encodes headers for trace logs so we can see what mutator just set. +std::string SummarizeHeaderValue(const curl::fuzzer::proto::HeaderValue &value) { + switch(value.value_case()) { + case curl::fuzzer::proto::HeaderValue::kText: + return std::string("text ") + SummarizeText(value.text()); + case curl::fuzzer::proto::HeaderValue::kBinary: + return std::string("binary ") + SummarizeBinary(value.binary()); + case curl::fuzzer::proto::HeaderValue::VALUE_NOT_SET: + default: + return "unset"; + } +} + +// Distills response payloads plus hints to one log line for replay debugging. +std::string SummarizeResponse(const curl::fuzzer::proto::Response &response) { + std::string summary = SummarizeBinary(response.payload()); + if(response.has_hint()) { + std::string hints; + if(response.hint().chunked()) { + hints.append(hints.empty() ? "chunked" : ",chunked"); + } + if(response.hint().websocket_frame()) { + hints.append(hints.empty() ? "websocket" : ",websocket"); + } + if(response.hint().tls_record()) { + hints.append(hints.empty() ? "tls_record" : ",tls_record"); + } + if(!hints.empty()) { + summary.append(" hints="); + summary.append(hints); + } + } + if(response.has_delay_before()) { + summary.append(" delay_ms="); + summary.append(std::to_string(response.delay_before().milliseconds())); + } + return summary; +} + +// Breaks down MIME parts so verbose output shows the shape of each upload. +std::string SummarizeMimePart(const curl::fuzzer::proto::MimePart &part) { + std::string summary; + if(!part.name().empty()) { + summary.append("name="); + summary.append(SummarizeText(part.name())); + summary.append(" "); + } + if(!part.filename().empty()) { + summary.append("filename="); + summary.append(SummarizeText(part.filename())); + summary.append(" "); + } + if(!part.content_type().empty()) { + summary.append("content_type=\""); + summary.append(part.content_type()); + summary.append("\" "); + } + switch(part.body_case()) { + case curl::fuzzer::proto::MimePart::kBytesValue: + summary.append("body_bytes "); + summary.append(SummarizeBinary(part.bytes_value())); + summary.append(" "); + break; + case curl::fuzzer::proto::MimePart::kInlineData: + summary.append("body_inline "); + summary.append(SummarizeText(part.inline_data())); + summary.append(" "); + break; + case curl::fuzzer::proto::MimePart::BODY_NOT_SET: + default: + break; + } + summary.append("headers="); + summary.append(std::to_string(part.headers_size())); + return summary; +} + +// Similar to MIME summaries but tailored for classic form posts. +std::string SummarizeFormField(const curl::fuzzer::proto::FormField &field) { + std::string summary; + summary.append("name="); + summary.append(SummarizeText(field.name())); + summary.append(" "); + switch(field.body_case()) { + case curl::fuzzer::proto::FormField::kInlineData: + summary.append("inline "); + summary.append(SummarizeText(field.inline_data())); + break; + case curl::fuzzer::proto::FormField::kBytesValue: + summary.append("bytes "); + summary.append(SummarizeBinary(field.bytes_value())); + break; + case curl::fuzzer::proto::FormField::BODY_NOT_SET: + default: + summary.append("empty"); + break; + } + return summary; +} + +// Owns scratch buffers that mirror proto data so libcurl can outlive the message. +class ScenarioState { + public: + ScenarioState() = default; + ScenarioState(const ScenarioState &) = delete; + ScenarioState &operator=(const ScenarioState &) = delete; + + // Curl expects zero-terminated strings that stay valid; copy them into owned storage. + const char *CopyString(std::string_view sv) { + auto owned = std::make_unique(sv.size() + 1); + std::memcpy(owned.get(), sv.data(), sv.size()); + owned[sv.size()] = '\0'; + const char *ptr = owned.get(); + cstrings_.push_back(std::move(owned)); + return ptr; + } + + // Binary blobs need stable backing memory for CURLFORM_PTRCONTENTS and similar paths. + std::pair CopyBytes(std::string_view sv) { + byte_buffers_.emplace_back(); + auto &storage = byte_buffers_.back(); + storage.assign(reinterpret_cast(sv.data()), + reinterpret_cast(sv.data()) + sv.size()); + const uint8_t *ptr = storage.data(); + return {ptr, storage.size()}; + } + + // Converts proto headers to the format curl_slist requires, owning the storage. + int HeaderValueToCString(const curl::fuzzer::proto::HeaderValue &value, + const char **out) { + switch(value.value_case()) { + case curl::fuzzer::proto::HeaderValue::kText: + *out = CopyString(value.text()); + return 0; + case curl::fuzzer::proto::HeaderValue::kBinary: { + auto view = CopyBytes(value.binary()); + if(view.second == 0) { + *out = CopyString(""); + } + else { + *out = CopyString(std::string_view(reinterpret_cast(view.first), view.second)); + } + return 0; + } + case curl::fuzzer::proto::HeaderValue::VALUE_NOT_SET: + default: + *out = CopyString(""); + return 0; + } + } + + private: + std::vector> byte_buffers_; + std::vector> cstrings_; +}; + +// Passed into the fuzz harness so the lifetime of ScenarioState is reference counted. +void DestroyScenarioState(void *ptr) { + delete static_cast(ptr); +} + +// curl_easy_setopt "long" overload accepts several proto numeric types; normalize here. +long ProtoToLong(const curl::fuzzer::proto::SetOption &option) { + switch(option.value_case()) { + case curl::fuzzer::proto::SetOption::kInt32Value: + return static_cast(option.int32_value()); + case curl::fuzzer::proto::SetOption::kUint32Value: + return static_cast(option.uint32_value()); + case curl::fuzzer::proto::SetOption::kInt64Value: + return static_cast(option.int64_value()); + case curl::fuzzer::proto::SetOption::kUint64Value: + return static_cast(option.uint64_value()); + case curl::fuzzer::proto::SetOption::kBoolValue: + return option.bool_value() ? 1L : 0L; + case curl::fuzzer::proto::SetOption::kDoubleValue: + return static_cast(option.double_value()); + case curl::fuzzer::proto::SetOption::kStringValue: + case curl::fuzzer::proto::SetOption::kBytesValue: + case curl::fuzzer::proto::SetOption::VALUE_NOT_SET: + return 0L; + default: + return 0L; + } +} + +// Some CURLOPTs expect curl_off_t; reuse ProtoToLong while preserving native width. +curl_off_t ProtoToOffT(const curl::fuzzer::proto::SetOption &option) { + switch(option.value_case()) { + case curl::fuzzer::proto::SetOption::kUint64Value: + return static_cast(option.uint64_value()); + case curl::fuzzer::proto::SetOption::kInt64Value: + return static_cast(option.int64_value()); + case curl::fuzzer::proto::SetOption::kUint32Value: + return static_cast(option.uint32_value()); + case curl::fuzzer::proto::SetOption::kInt32Value: + return static_cast(option.int32_value()); + case curl::fuzzer::proto::SetOption::kBoolValue: + case curl::fuzzer::proto::SetOption::kDoubleValue: + case curl::fuzzer::proto::SetOption::kStringValue: + case curl::fuzzer::proto::SetOption::kBytesValue: + case curl::fuzzer::proto::SetOption::VALUE_NOT_SET: + return static_cast(ProtoToLong(option)); + default: + return static_cast(ProtoToLong(option)); + } +} + +// Prevents conflicting mutations: once an option is set we refuse to overwrite it. +int EnsureOptionUnset(FUZZ_DATA *fuzz, CURLoption opt, const OptionDescriptor *desc) { + (void)desc; + if(fuzz->options[opt % 1000] != 0) { + return 255; + } + return 0; +} + +// Tracks which curl options have been claimed, so EnsureOptionUnset can police reuse. +void MarkOptionSet(FUZZ_DATA *fuzz, CURLoption opt) { + fuzz->options[opt % 1000] = 1; +} + +// Shared helpers wrap curl_easy_setopt calls and mark bookkeeping on success. +int ApplyStringOption(FUZZ_DATA *fuzz, + const OptionDescriptor *desc, + const char *value) { + CURLcode code = curl_easy_setopt(fuzz->easy, desc->curlopt, value); + if(code != CURLE_OK) { + return static_cast(code); + } + MarkOptionSet(fuzz, desc->curlopt); + return 0; +} + +int ApplyLongOption(FUZZ_DATA *fuzz, + const OptionDescriptor *desc, + long value) { + CURLcode code = curl_easy_setopt(fuzz->easy, desc->curlopt, value); + if(code != CURLE_OK) { + return static_cast(code); + } + MarkOptionSet(fuzz, desc->curlopt); + return 0; +} + +int ApplyOffOption(FUZZ_DATA *fuzz, + const OptionDescriptor *desc, + curl_off_t value) { + CURLcode code = curl_easy_setopt(fuzz->easy, desc->curlopt, value); + if(code != CURLE_OK) { + return static_cast(code); + } + MarkOptionSet(fuzz, desc->curlopt); + return 0; +} + +// Central dispatcher for option mutations: validates descriptor, enforces scope rules, +// and copies data so curl references remain valid after the protobuf message is gone. +int ApplySetOption(const curl::fuzzer::proto::SetOption &option, + ScenarioState *state, + FUZZ_DATA *fuzz) { + const OptionDescriptor *desc = LookupDescriptor(option.option_id()); + if(desc == nullptr) { + return 255; + } + + int rc = 0; + const char *scope_name = OptionScopeName(option.scope()); + switch(desc->kind) { + case OptionValueKind::kString: { + const char *value = nullptr; + std::string detail; + switch(option.value_case()) { + case curl::fuzzer::proto::SetOption::kStringValue: { + detail = std::string("string ") + SummarizeText(option.string_value()); + value = state->CopyString(option.string_value()); + break; + } + case curl::fuzzer::proto::SetOption::kBytesValue: { + detail = std::string("bytes ") + SummarizeBinary(option.bytes_value()); + auto view = state->CopyBytes(option.bytes_value()); + if(view.second == 0 || view.first == nullptr) { + value = state->CopyString(""); + } + else { + value = state->CopyString(std::string_view(reinterpret_cast(view.first), view.second)); + } + break; + } + default: { + detail = "string "; + value = state->CopyString(""); + break; + } + } + rc = EnsureOptionUnset(fuzz, desc->curlopt, desc); + if(rc != 0) { + return rc; + } + rc = ApplyStringOption(fuzz, desc, value); + if(rc == 0 && fuzz->verbose) { + FV_PRINTF(fuzz, + "SCENARIO: set_option %s scope=%s %s\n", + desc->name, + scope_name, + detail.c_str()); + } + return rc; + } + case OptionValueKind::kUint32: { + rc = EnsureOptionUnset(fuzz, desc->curlopt, desc); + if(rc != 0) { + return rc; + } + long value = ProtoToLong(option); + rc = ApplyLongOption(fuzz, desc, value); + if(rc == 0 && fuzz->verbose) { + std::string detail = "uint32=" + std::to_string(static_cast(value)); + FV_PRINTF(fuzz, + "SCENARIO: set_option %s scope=%s %s\n", + desc->name, + scope_name, + detail.c_str()); + } + return rc; + } + case OptionValueKind::kUint64: { + rc = EnsureOptionUnset(fuzz, desc->curlopt, desc); + if(rc != 0) { + return rc; + } + curl_off_t value = ProtoToOffT(option); + rc = ApplyOffOption(fuzz, desc, value); + if(rc == 0 && fuzz->verbose) { + std::string detail = "uint64=" + std::to_string(static_cast(value)); + FV_PRINTF(fuzz, + "SCENARIO: set_option %s scope=%s %s\n", + desc->name, + scope_name, + detail.c_str()); + } + return rc; + } + case OptionValueKind::kBool: { + rc = EnsureOptionUnset(fuzz, desc->curlopt, desc); + if(rc != 0) { + return rc; + } + const bool has_bool_value = + option.value_case() == curl::fuzzer::proto::SetOption::kBoolValue; + long value = has_bool_value ? (option.bool_value() ? 1L : 0L) : ProtoToLong(option); + rc = ApplyLongOption(fuzz, desc, value); + if(rc == 0 && fuzz->verbose) { + std::string detail; + if(has_bool_value) { + detail = std::string("bool=") + (option.bool_value() ? "true" : "false"); + } + else { + detail = "long=" + std::to_string(static_cast(value)); + } + FV_PRINTF(fuzz, + "SCENARIO: set_option %s scope=%s %s\n", + desc->name, + scope_name, + detail.c_str()); + } + return rc; + } + case OptionValueKind::kHttpPost: { + rc = EnsureOptionUnset(fuzz, desc->curlopt, desc); + if(rc != 0) { + return rc; + } + if(fuzz->httppost == NULL) { + return 255; + } + CURLcode code = curl_easy_setopt(fuzz->easy, desc->curlopt, fuzz->httppost); + if(code != CURLE_OK) { + return static_cast(code); + } + MarkOptionSet(fuzz, desc->curlopt); + if(fuzz->verbose) { + FV_PRINTF(fuzz, + "SCENARIO: set_option %s scope=%s httppost attached\n", + desc->name, + scope_name); + } + return 0; + } + case OptionValueKind::kMime: { + rc = EnsureOptionUnset(fuzz, desc->curlopt, desc); + if(rc != 0) { + return rc; + } + if(fuzz->mime == NULL) { + return 255; + } + CURLcode code = curl_easy_setopt(fuzz->easy, desc->curlopt, fuzz->mime); + if(code != CURLE_OK) { + return static_cast(code); + } + MarkOptionSet(fuzz, desc->curlopt); + if(fuzz->verbose) { + FV_PRINTF(fuzz, + "SCENARIO: set_option %s scope=%s mime attached\n", + desc->name, + scope_name); + } + return 0; + } + case OptionValueKind::kUnknown: + default: + return 255; + } +} + +// Adds a header to the easy handle: we store it in a curl_slist the harness will free. +int ApplyHeader(const curl::fuzzer::proto::AddHeader &header, + ScenarioState *state, + FUZZ_DATA *fuzz) { + std::string detail = SummarizeHeaderValue(header.value()); + const char *value = nullptr; + int rc = state->HeaderValueToCString(header.value(), &value); + if(rc != 0) { + return rc; + } + curl_slist *new_list = curl_slist_append(fuzz->header_list, value); + if(new_list == NULL) { + return 255; + } + fuzz->header_list = new_list; + fuzz->header_list_count++; + if(fuzz->verbose) { + FV_PRINTF(fuzz, + "SCENARIO: add_header #%d %s\n", + fuzz->header_list_count, + detail.c_str()); + } + return 0; +} + +// POP3/SMTP fuzzers need dynamic recipient lists; mirror header handling for mail APIs. +int ApplyMailRecipient(const curl::fuzzer::proto::AddMailRecipient &recipient, + ScenarioState *state, + FUZZ_DATA *fuzz) { + std::string detail = SummarizeHeaderValue(recipient.value()); + const char *value = nullptr; + int rc = state->HeaderValueToCString(recipient.value(), &value); + if(rc != 0) { + return rc; + } + curl_slist *new_list = curl_slist_append(fuzz->mail_recipients_list, value); + if(new_list == NULL) { + return 255; + } + fuzz->mail_recipients_list = new_list; + fuzz->header_list_count++; + if(fuzz->verbose) { + FV_PRINTF(fuzz, + "SCENARIO: add_mail_recipient #%d %s\n", + fuzz->header_list_count, + detail.c_str()); + } + return 0; +} + +// Captures upload payloads in ScenarioState buffers and toggles CURLOPTs accordingly. +int ApplyRegisterUpload(const curl::fuzzer::proto::RegisterUpload &upload, + ScenarioState *state, + FUZZ_DATA *fuzz) { + auto view = state->CopyBytes(upload.payload()); + const uint8_t *data = view.first; + size_t length = view.second; + fuzz->upload1_data = data; + fuzz->upload1_data_len = length; + fuzz->upload1_data_written = 0; + const OptionDescriptor *upload_desc = LookupDescriptor(curl::fuzzer::proto::CURLOPT_UPLOAD); + if(upload_desc != nullptr) { + int rc = EnsureOptionUnset(fuzz, upload_desc->curlopt, upload_desc); + if(rc != 0) { + return rc; + } + rc = ApplyLongOption( + fuzz, + upload_desc, + upload.kind() == curl::fuzzer::proto::TRANSFER_KIND_POSTFIELDS ? 0L : 1L); + if(rc != 0) { + return rc; + } + } + + const OptionDescriptor *length_desc = + LookupDescriptor(curl::fuzzer::proto::CURLOPT_INFILESIZE_LARGE); + if(length_desc != nullptr) { + int rc = EnsureOptionUnset(fuzz, length_desc->curlopt, length_desc); + if(rc != 0) { + return rc; + } + rc = ApplyOffOption(fuzz, length_desc, static_cast(length)); + if(rc != 0) { + return rc; + } + } + if(fuzz->verbose) { + std::string detail = SummarizeBinary(upload.payload()); + std::string size_hint = std::to_string(static_cast(upload.size_hint())); + FV_PRINTF(fuzz, + "SCENARIO: register_upload kind=%s %s size_hint=%s\n", + TransferKindName(upload.kind()), + detail.c_str(), + size_hint.c_str()); + } + return 0; +} + +// Builds individual MIME parts while copying proto-managed storage into curl-owned form. +int ApplyMimePart(const curl::fuzzer::proto::MimePart &part, + ScenarioState *state, + curl_mime *mime) { + curl_mimepart *m = curl_mime_addpart(mime); + if(m == NULL) { + return 255; + } + if(!part.name().empty()) { + const char *name = state->CopyString(part.name()); + curl_mime_name(m, name); + } + if(!part.filename().empty()) { + const char *filename = state->CopyString(part.filename()); + curl_mime_filename(m, filename); + } + if(!part.content_type().empty()) { + const char *ctype = state->CopyString(part.content_type()); + curl_mime_type(m, ctype); + } + switch(part.body_case()) { + case curl::fuzzer::proto::MimePart::kBytesValue: { + auto view = state->CopyBytes(part.bytes_value()); + CURLcode code = curl_mime_data(m, reinterpret_cast(view.first), view.second); + if(code != CURLE_OK) { + return static_cast(code); + } + break; + } + case curl::fuzzer::proto::MimePart::kInlineData: { + const char *text = state->CopyString(part.inline_data()); + CURLcode code = curl_mime_data(m, text, CURL_ZERO_TERMINATED); + if(code != CURLE_OK) { + return static_cast(code); + } + break; + } + case curl::fuzzer::proto::MimePart::BODY_NOT_SET: + default: + break; + } + for(const auto &header : part.headers()) { + const char *hv = nullptr; + int rc = state->HeaderValueToCString(header, &hv); + if(rc != 0) { + return rc; + } + struct curl_slist *list = curl_slist_append(nullptr, hv); + if(list == NULL) { + return 255; + } + CURLcode code = curl_mime_headers(m, list, 1); + if(code != CURLE_OK) { + return static_cast(code); + } + } + return 0; +} + +// Lazily allocates a curl_mime handle and appends each proto part for the active request. +int ApplyConfigureMime(const curl::fuzzer::proto::ConfigureMime &config, + ScenarioState *state, + FUZZ_DATA *fuzz) { + if(fuzz->mime == NULL) { + fuzz->mime = curl_mime_init(fuzz->easy); + if(fuzz->mime == NULL) { + return 255; + } + } + size_t index = 0; + for(const auto &part : config.parts()) { + if(fuzz->verbose) { + std::string detail = SummarizeMimePart(part); + FV_PRINTF(fuzz, + "SCENARIO: configure_mime part[%zu] %s\n", + index, + detail.c_str()); + } + int rc = ApplyMimePart(part, state, fuzz->mime); + if(rc != 0) { + return rc; + } + ++index; + } + return 0; +} + +// Recreates the legacy curl_httppost linked list for form submissions, stitching chains +// together across multiple actions so later CURLOPT_HTTPPOST calls see all parts. +int ApplyConfigureHttpPost(const curl::fuzzer::proto::ConfigureHttpPost &config, + ScenarioState *state, + FUZZ_DATA *fuzz) { + struct curl_httppost *post = NULL; + struct curl_httppost *last = NULL; + size_t index = 0; + for(const auto &field : config.fields()) { + if(fuzz->verbose) { + std::string detail = SummarizeFormField(field); + FV_PRINTF(fuzz, + "SCENARIO: configure_http_post field[%zu] %s\n", + index, + detail.c_str()); + } + const char *name = state->CopyString(field.name()); + CURLFORMcode form_rc = CURL_FORMADD_OK; + switch(field.body_case()) { + case curl::fuzzer::proto::FormField::kInlineData: { + const char *data = state->CopyString(field.inline_data()); + form_rc = curl_formadd(&post, &last, + CURLFORM_COPYNAME, name, + CURLFORM_COPYCONTENTS, data, + CURLFORM_END); + break; + } + case curl::fuzzer::proto::FormField::kBytesValue: { + auto view = state->CopyBytes(field.bytes_value()); + form_rc = curl_formadd(&post, &last, + CURLFORM_COPYNAME, name, + CURLFORM_PTRCONTENTS, view.first, + CURLFORM_CONTENTLEN, static_cast(view.second), + CURLFORM_END); + break; + } + case curl::fuzzer::proto::FormField::BODY_NOT_SET: + default: + form_rc = curl_formadd(&post, &last, + CURLFORM_COPYNAME, name, + CURLFORM_END); + break; + } + if(form_rc != CURL_FORMADD_OK) { + if(post != NULL) { + curl_formfree(post); + } + return 255; + } + ++index; + } + if(post == NULL) { + return 0; + } + + if(fuzz->httppost == NULL) { + fuzz->httppost = post; + } + else { + struct curl_httppost *tail = fuzz->last_post_part; + if(tail == NULL) { + tail = fuzz->httppost; + while(tail->next != NULL) { + tail = tail->next; + } + } + tail->next = post; + } + + fuzz->last_post_part = last; + return 0; +} + +// Copies response payloads into ScenarioState buffers so socket managers can replay them. +int ApplyResponse(const curl::fuzzer::proto::Response &response, + ScenarioState *state, + FUZZ_RESPONSE *dest) { + auto view = state->CopyBytes(response.payload()); + dest->data = view.first; + dest->data_len = view.second; + return 0; +} + +// Applies scripted server behaviour: each connection slot gets preset responses and +// optional follow-up messages so the harness can emulate remote peers. +int ApplyConnections(const google::protobuf::RepeatedPtrField &connections, + ScenarioState *state, + FUZZ_DATA *fuzz) { + for(const auto &connection : connections) { + if(connection.id() >= FUZZ_NUM_CONNECTIONS) { + continue; + } + FUZZ_SOCKET_MANAGER *manager = &fuzz->sockman[connection.id()]; + if(fuzz->verbose) { + uint32_t idle_ms = connection.has_idle_after_send() + ? connection.idle_after_send().milliseconds() + : 0U; + FV_PRINTF(fuzz, + "SCENARIO: connection %u policy=%s idle_after_send_ms=%u responses=%d\n", + connection.id(), + ShutdownPolicyName(connection.shutdown_policy()), + idle_ms, + connection.on_readable_size() + (connection.has_initial_response() ? 1 : 0)); + } + if(connection.has_initial_response()) { + int rc = ApplyResponse(connection.initial_response(), state, &manager->responses[0]); + if(rc != 0) { + return rc; + } + if(fuzz->verbose) { + std::string detail = SummarizeResponse(connection.initial_response()); + FV_PRINTF(fuzz, + "SCENARIO: connection %u initial_response %s\n", + connection.id(), + detail.c_str()); + } + } + int idx = 1; + for(const auto &resp : connection.on_readable()) { + if(idx >= TLV_MAX_NUM_RESPONSES) { + break; + } + int rc = ApplyResponse(resp, state, &manager->responses[idx]); + if(rc != 0) { + return rc; + } + if(fuzz->verbose) { + std::string detail = SummarizeResponse(resp); + FV_PRINTF(fuzz, + "SCENARIO: connection %u on_readable[%d] %s\n", + connection.id(), + idx - 1, + detail.c_str()); + } + idx++; + } + } + return 0; +} + +// Allows actions to enqueue additional responses after the scenario starts executing, +// modelling dynamically generated server data. +int ApplyRegisterResponse(const curl::fuzzer::proto::RegisterResponse ®istration, + ScenarioState *state, + FUZZ_DATA *fuzz) { + uint32_t id = registration.connection_id(); + if(id >= FUZZ_NUM_CONNECTIONS) { + return 255; + } + FUZZ_SOCKET_MANAGER *manager = &fuzz->sockman[id]; + int rc = 0; + int stage_index = -1; + switch(registration.stage()) { + case curl::fuzzer::proto::RESPONSE_STAGE_ON_CONNECT: + rc = ApplyResponse(registration.response(), state, &manager->responses[0]); + break; + case curl::fuzzer::proto::RESPONSE_STAGE_ON_READABLE: { + for(int idx = 1; idx < TLV_MAX_NUM_RESPONSES; ++idx) { + if(manager->responses[idx].data_len == 0 && manager->responses[idx].data == NULL) { + rc = ApplyResponse(registration.response(), state, &manager->responses[idx]); + stage_index = idx - 1; + break; + } + } + if(stage_index == -1) { + return 255; + } + break; + } + case curl::fuzzer::proto::RESPONSE_STAGE_UNSPECIFIED: + default: + return 255; + } + if(rc != 0) { + return rc; + } + if(fuzz->verbose) { + std::string detail = SummarizeResponse(registration.response()); + if(registration.stage() == curl::fuzzer::proto::RESPONSE_STAGE_ON_READABLE) { + FV_PRINTF(fuzz, + "SCENARIO: register_response conn=%u stage=%s index=%d %s\n", + id, + ResponseStageName(registration.stage()), + stage_index, + detail.c_str()); + } + else { + FV_PRINTF(fuzz, + "SCENARIO: register_response conn=%u stage=%s %s\n", + id, + ResponseStageName(registration.stage()), + detail.c_str()); + } + } + return 0; +} + +// Dispatches scenario actions in declaration order so state builds up deterministically. +int ApplyAction(const curl::fuzzer::proto::Action &action, + ScenarioState *state, + FUZZ_DATA *fuzz) { + switch(action.kind_case()) { + case curl::fuzzer::proto::Action::kSetOption: + return ApplySetOption(action.set_option(), state, fuzz); + case curl::fuzzer::proto::Action::kAddHeader: + return ApplyHeader(action.add_header(), state, fuzz); + case curl::fuzzer::proto::Action::kAddMailRecipient: + return ApplyMailRecipient(action.add_mail_recipient(), state, fuzz); + case curl::fuzzer::proto::Action::kConfigureMime: + return ApplyConfigureMime(action.configure_mime(), state, fuzz); + case curl::fuzzer::proto::Action::kConfigureHttpPost: + return ApplyConfigureHttpPost(action.configure_http_post(), state, fuzz); + case curl::fuzzer::proto::Action::kRegisterUpload: + return ApplyRegisterUpload(action.register_upload(), state, fuzz); + case curl::fuzzer::proto::Action::kRegisterResponse: + return ApplyRegisterResponse(action.register_response(), state, fuzz); + case curl::fuzzer::proto::Action::KIND_NOT_SET: + default: + return 0; + } +} + +} // namespace + +// Entry point from the fuzz harness: hydrate scenario state, run all actions, then wire +// up scripted connections so the fuzzer sees a complete environment. +int ApplyScenario(const curl::fuzzer::proto::Scenario &scenario, + FUZZ_DATA *fuzz) { + auto state = std::make_unique(); + int rc = 0; + for(const auto &action : scenario.actions()) { + rc = ApplyAction(action, state.get(), fuzz); + if(rc != 0) { + return rc; + } + } + rc = ApplyConnections(scenario.connections(), state.get(), fuzz); + if(rc != 0) { + return rc; + } + + fuzz->scenario_state = state.release(); + fuzz->scenario_state_destructor = DestroyScenarioState; + return 0; +} + +} // namespace curl_fuzzer diff --git a/curl_fuzzer_scenario.h b/curl_fuzzer_scenario.h new file mode 100644 index 000000000..87805630e --- /dev/null +++ b/curl_fuzzer_scenario.h @@ -0,0 +1,28 @@ +#ifndef CURL_FUZZER_SCENARIO_H_ +#define CURL_FUZZER_SCENARIO_H_ + +#include +#include + +#include "curl_fuzzer.h" +#include "curl_fuzzer.pb.h" + +namespace curl_fuzzer { + +// Attempt to parse the input buffer as a structured Scenario proto. Returns +// true on success and writes the decoded scenario to |out|. The parsed data is +// independent of the original buffer once this function returns. +bool TryParseScenario(const uint8_t *data, + size_t size, + curl::fuzzer::proto::Scenario *out); + +// Apply a decoded Scenario onto the existing FUZZ_DATA setup. On success the +// FUZZ_DATA instance is ready for curl option setup (fuzz_set_easy_options) and +// subsequent execution. Returns 0 on success, or a non-zero error code that +// matches the legacy TLV error semantics. +int ApplyScenario(const curl::fuzzer::proto::Scenario &scenario, + FUZZ_DATA *fuzz); + +} // namespace curl_fuzzer + +#endif // CURL_FUZZER_SCENARIO_H_ diff --git a/generated/curl_fuzzer_option_manifest.inc b/generated/curl_fuzzer_option_manifest.inc new file mode 100644 index 000000000..acd115ac5 --- /dev/null +++ b/generated/curl_fuzzer_option_manifest.inc @@ -0,0 +1,215 @@ +// Generated by src/curl_fuzzer_tools/generate_option_manifest.py +static constexpr OptionDescriptor kOptionManifest[] = { + {curl::fuzzer::proto::CURLOPT_ABSTRACT_UNIX_SOCKET, OptionValueKind::kString, true, "CURLOPT_ABSTRACT_UNIX_SOCKET", CURLOPT_ABSTRACT_UNIX_SOCKET}, + {curl::fuzzer::proto::CURLOPT_ACCEPTTIMEOUT_MS, OptionValueKind::kUint32, true, "CURLOPT_ACCEPTTIMEOUT_MS", CURLOPT_ACCEPTTIMEOUT_MS}, + {curl::fuzzer::proto::CURLOPT_ACCEPT_ENCODING, OptionValueKind::kString, true, "CURLOPT_ACCEPT_ENCODING", CURLOPT_ACCEPT_ENCODING}, + {curl::fuzzer::proto::CURLOPT_ADDRESS_SCOPE, OptionValueKind::kUint32, true, "CURLOPT_ADDRESS_SCOPE", CURLOPT_ADDRESS_SCOPE}, + {curl::fuzzer::proto::CURLOPT_ALTSVC_CTRL, OptionValueKind::kUint32, true, "CURLOPT_ALTSVC_CTRL", CURLOPT_ALTSVC_CTRL}, + {curl::fuzzer::proto::CURLOPT_APPEND, OptionValueKind::kUint32, true, "CURLOPT_APPEND", CURLOPT_APPEND}, + {curl::fuzzer::proto::CURLOPT_AUTOREFERER, OptionValueKind::kUint32, true, "CURLOPT_AUTOREFERER", CURLOPT_AUTOREFERER}, + {curl::fuzzer::proto::CURLOPT_AWS_SIGV4, OptionValueKind::kString, true, "CURLOPT_AWS_SIGV4", CURLOPT_AWS_SIGV4}, + {curl::fuzzer::proto::CURLOPT_BUFFERSIZE, OptionValueKind::kUint32, true, "CURLOPT_BUFFERSIZE", CURLOPT_BUFFERSIZE}, + {curl::fuzzer::proto::CURLOPT_CAINFO, OptionValueKind::kString, true, "CURLOPT_CAINFO", CURLOPT_CAINFO}, + {curl::fuzzer::proto::CURLOPT_CAPATH, OptionValueKind::kString, true, "CURLOPT_CAPATH", CURLOPT_CAPATH}, + {curl::fuzzer::proto::CURLOPT_CA_CACHE_TIMEOUT, OptionValueKind::kUint32, true, "CURLOPT_CA_CACHE_TIMEOUT", CURLOPT_CA_CACHE_TIMEOUT}, + {curl::fuzzer::proto::CURLOPT_CERTINFO, OptionValueKind::kUint32, true, "CURLOPT_CERTINFO", CURLOPT_CERTINFO}, + {curl::fuzzer::proto::CURLOPT_CONNECTTIMEOUT, OptionValueKind::kUint32, true, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT}, + {curl::fuzzer::proto::CURLOPT_CONNECTTIMEOUT_MS, OptionValueKind::kUint32, true, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS}, + {curl::fuzzer::proto::CURLOPT_CONNECT_ONLY, OptionValueKind::kUint32, true, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY}, + {curl::fuzzer::proto::CURLOPT_COOKIE, OptionValueKind::kString, true, "CURLOPT_COOKIE", CURLOPT_COOKIE}, + {curl::fuzzer::proto::CURLOPT_COOKIELIST, OptionValueKind::kString, true, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST}, + {curl::fuzzer::proto::CURLOPT_COOKIESESSION, OptionValueKind::kUint32, true, "CURLOPT_COOKIESESSION", CURLOPT_COOKIESESSION}, + {curl::fuzzer::proto::CURLOPT_CUSTOMREQUEST, OptionValueKind::kString, true, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST}, + {curl::fuzzer::proto::CURLOPT_DEFAULT_PROTOCOL, OptionValueKind::kString, true, "CURLOPT_DEFAULT_PROTOCOL", CURLOPT_DEFAULT_PROTOCOL}, + {curl::fuzzer::proto::CURLOPT_DIRLISTONLY, OptionValueKind::kUint32, true, "CURLOPT_DIRLISTONLY", CURLOPT_DIRLISTONLY}, + {curl::fuzzer::proto::CURLOPT_DISALLOW_USERNAME_IN_URL, OptionValueKind::kUint32, true, "CURLOPT_DISALLOW_USERNAME_IN_URL", CURLOPT_DISALLOW_USERNAME_IN_URL}, + {curl::fuzzer::proto::CURLOPT_DNS_CACHE_TIMEOUT, OptionValueKind::kUint32, true, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT}, + {curl::fuzzer::proto::CURLOPT_DNS_INTERFACE, OptionValueKind::kString, true, "CURLOPT_DNS_INTERFACE", CURLOPT_DNS_INTERFACE}, + {curl::fuzzer::proto::CURLOPT_DNS_LOCAL_IP4, OptionValueKind::kString, true, "CURLOPT_DNS_LOCAL_IP4", CURLOPT_DNS_LOCAL_IP4}, + {curl::fuzzer::proto::CURLOPT_DNS_LOCAL_IP6, OptionValueKind::kString, true, "CURLOPT_DNS_LOCAL_IP6", CURLOPT_DNS_LOCAL_IP6}, + {curl::fuzzer::proto::CURLOPT_DNS_SERVERS, OptionValueKind::kString, true, "CURLOPT_DNS_SERVERS", CURLOPT_DNS_SERVERS}, + {curl::fuzzer::proto::CURLOPT_DNS_SHUFFLE_ADDRESSES, OptionValueKind::kUint32, true, "CURLOPT_DNS_SHUFFLE_ADDRESSES", CURLOPT_DNS_SHUFFLE_ADDRESSES}, + {curl::fuzzer::proto::CURLOPT_DOH_SSL_VERIFYHOST, OptionValueKind::kUint32, true, "CURLOPT_DOH_SSL_VERIFYHOST", CURLOPT_DOH_SSL_VERIFYHOST}, + {curl::fuzzer::proto::CURLOPT_DOH_SSL_VERIFYPEER, OptionValueKind::kUint32, true, "CURLOPT_DOH_SSL_VERIFYPEER", CURLOPT_DOH_SSL_VERIFYPEER}, + {curl::fuzzer::proto::CURLOPT_DOH_SSL_VERIFYSTATUS, OptionValueKind::kUint32, true, "CURLOPT_DOH_SSL_VERIFYSTATUS", CURLOPT_DOH_SSL_VERIFYSTATUS}, + {curl::fuzzer::proto::CURLOPT_DOH_URL, OptionValueKind::kString, true, "CURLOPT_DOH_URL", CURLOPT_DOH_URL}, + {curl::fuzzer::proto::CURLOPT_ECH, OptionValueKind::kString, true, "CURLOPT_ECH", CURLOPT_ECH}, + {curl::fuzzer::proto::CURLOPT_EXPECT_100_TIMEOUT_MS, OptionValueKind::kUint32, true, "CURLOPT_EXPECT_100_TIMEOUT_MS", CURLOPT_EXPECT_100_TIMEOUT_MS}, + {curl::fuzzer::proto::CURLOPT_FAILONERROR, OptionValueKind::kUint32, true, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR}, + {curl::fuzzer::proto::CURLOPT_FILETIME, OptionValueKind::kUint32, true, "CURLOPT_FILETIME", CURLOPT_FILETIME}, + {curl::fuzzer::proto::CURLOPT_FOLLOWLOCATION, OptionValueKind::kUint32, true, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION}, + {curl::fuzzer::proto::CURLOPT_FORBID_REUSE, OptionValueKind::kUint32, true, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE}, + {curl::fuzzer::proto::CURLOPT_FRESH_CONNECT, OptionValueKind::kUint32, true, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT}, + {curl::fuzzer::proto::CURLOPT_FTPPORT, OptionValueKind::kString, true, "CURLOPT_FTPPORT", CURLOPT_FTPPORT}, + {curl::fuzzer::proto::CURLOPT_FTPSSLAUTH, OptionValueKind::kUint32, true, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH}, + {curl::fuzzer::proto::CURLOPT_FTP_ACCOUNT, OptionValueKind::kString, true, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT}, + {curl::fuzzer::proto::CURLOPT_FTP_ALTERNATIVE_TO_USER, OptionValueKind::kString, true, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER}, + {curl::fuzzer::proto::CURLOPT_FTP_CREATE_MISSING_DIRS, OptionValueKind::kUint32, true, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS}, + {curl::fuzzer::proto::CURLOPT_FTP_FILEMETHOD, OptionValueKind::kUint32, true, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD}, + {curl::fuzzer::proto::CURLOPT_FTP_SKIP_PASV_IP, OptionValueKind::kUint32, true, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP}, + {curl::fuzzer::proto::CURLOPT_FTP_SSL_CCC, OptionValueKind::kUint32, true, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC}, + {curl::fuzzer::proto::CURLOPT_FTP_USE_EPRT, OptionValueKind::kUint32, true, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT}, + {curl::fuzzer::proto::CURLOPT_FTP_USE_EPSV, OptionValueKind::kUint32, true, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV}, + {curl::fuzzer::proto::CURLOPT_FTP_USE_PRET, OptionValueKind::kUint32, true, "CURLOPT_FTP_USE_PRET", CURLOPT_FTP_USE_PRET}, + {curl::fuzzer::proto::CURLOPT_GSSAPI_DELEGATION, OptionValueKind::kUint32, true, "CURLOPT_GSSAPI_DELEGATION", CURLOPT_GSSAPI_DELEGATION}, + {curl::fuzzer::proto::CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, OptionValueKind::kUint32, true, "CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS", CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS}, + {curl::fuzzer::proto::CURLOPT_HAPROXYPROTOCOL, OptionValueKind::kUint32, true, "CURLOPT_HAPROXYPROTOCOL", CURLOPT_HAPROXYPROTOCOL}, + {curl::fuzzer::proto::CURLOPT_HAPROXY_CLIENT_IP, OptionValueKind::kString, true, "CURLOPT_HAPROXY_CLIENT_IP", CURLOPT_HAPROXY_CLIENT_IP}, + {curl::fuzzer::proto::CURLOPT_HEADER, OptionValueKind::kUint32, true, "CURLOPT_HEADER", CURLOPT_HEADER}, + {curl::fuzzer::proto::CURLOPT_HEADEROPT, OptionValueKind::kUint32, true, "CURLOPT_HEADEROPT", CURLOPT_HEADEROPT}, + {curl::fuzzer::proto::CURLOPT_HSTS_CTRL, OptionValueKind::kUint32, true, "CURLOPT_HSTS_CTRL", CURLOPT_HSTS_CTRL}, + {curl::fuzzer::proto::CURLOPT_HTTP09_ALLOWED, OptionValueKind::kUint32, true, "CURLOPT_HTTP09_ALLOWED", CURLOPT_HTTP09_ALLOWED}, + {curl::fuzzer::proto::CURLOPT_HTTPAUTH, OptionValueKind::kUint32, true, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH}, + {curl::fuzzer::proto::CURLOPT_HTTPGET, OptionValueKind::kUint32, true, "CURLOPT_HTTPGET", CURLOPT_HTTPGET}, + {curl::fuzzer::proto::CURLOPT_HTTPPOST, OptionValueKind::kHttpPost, true, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST}, + {curl::fuzzer::proto::CURLOPT_HTTPPROXYTUNNEL, OptionValueKind::kUint32, true, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL}, + {curl::fuzzer::proto::CURLOPT_HTTP_CONTENT_DECODING, OptionValueKind::kUint32, true, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING}, + {curl::fuzzer::proto::CURLOPT_HTTP_TRANSFER_DECODING, OptionValueKind::kUint32, true, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING}, + {curl::fuzzer::proto::CURLOPT_HTTP_VERSION, OptionValueKind::kUint32, true, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION}, + {curl::fuzzer::proto::CURLOPT_IGNORE_CONTENT_LENGTH, OptionValueKind::kUint32, true, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH}, + {curl::fuzzer::proto::CURLOPT_INFILESIZE_LARGE, OptionValueKind::kUint64, true, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE}, + {curl::fuzzer::proto::CURLOPT_INTERFACE, OptionValueKind::kString, true, "CURLOPT_INTERFACE", CURLOPT_INTERFACE}, + {curl::fuzzer::proto::CURLOPT_IPRESOLVE, OptionValueKind::kUint32, true, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE}, + {curl::fuzzer::proto::CURLOPT_ISSUERCERT, OptionValueKind::kString, true, "CURLOPT_ISSUERCERT", CURLOPT_ISSUERCERT}, + {curl::fuzzer::proto::CURLOPT_KEEP_SENDING_ON_ERROR, OptionValueKind::kUint32, true, "CURLOPT_KEEP_SENDING_ON_ERROR", CURLOPT_KEEP_SENDING_ON_ERROR}, + {curl::fuzzer::proto::CURLOPT_KEYPASSWD, OptionValueKind::kString, true, "CURLOPT_KEYPASSWD", CURLOPT_KEYPASSWD}, + {curl::fuzzer::proto::CURLOPT_KRBLEVEL, OptionValueKind::kString, true, "CURLOPT_KRBLEVEL", CURLOPT_KRBLEVEL}, + {curl::fuzzer::proto::CURLOPT_LOCALPORT, OptionValueKind::kUint32, true, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT}, + {curl::fuzzer::proto::CURLOPT_LOCALPORTRANGE, OptionValueKind::kUint32, true, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE}, + {curl::fuzzer::proto::CURLOPT_LOGIN_OPTIONS, OptionValueKind::kString, true, "CURLOPT_LOGIN_OPTIONS", CURLOPT_LOGIN_OPTIONS}, + {curl::fuzzer::proto::CURLOPT_LOW_SPEED_LIMIT, OptionValueKind::kUint32, true, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT}, + {curl::fuzzer::proto::CURLOPT_LOW_SPEED_TIME, OptionValueKind::kUint32, true, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME}, + {curl::fuzzer::proto::CURLOPT_MAIL_AUTH, OptionValueKind::kString, true, "CURLOPT_MAIL_AUTH", CURLOPT_MAIL_AUTH}, + {curl::fuzzer::proto::CURLOPT_MAIL_FROM, OptionValueKind::kString, true, "CURLOPT_MAIL_FROM", CURLOPT_MAIL_FROM}, + {curl::fuzzer::proto::CURLOPT_MAIL_RCPT_ALLOWFAILS, OptionValueKind::kUint32, true, "CURLOPT_MAIL_RCPT_ALLOWFAILS", CURLOPT_MAIL_RCPT_ALLOWFAILS}, + {curl::fuzzer::proto::CURLOPT_MAXAGE_CONN, OptionValueKind::kUint32, true, "CURLOPT_MAXAGE_CONN", CURLOPT_MAXAGE_CONN}, + {curl::fuzzer::proto::CURLOPT_MAXCONNECTS, OptionValueKind::kUint32, true, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS}, + {curl::fuzzer::proto::CURLOPT_MAXFILESIZE, OptionValueKind::kUint32, true, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE}, + {curl::fuzzer::proto::CURLOPT_MAXFILESIZE_LARGE, OptionValueKind::kUint64, true, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE}, + {curl::fuzzer::proto::CURLOPT_MAXLIFETIME_CONN, OptionValueKind::kUint32, true, "CURLOPT_MAXLIFETIME_CONN", CURLOPT_MAXLIFETIME_CONN}, + {curl::fuzzer::proto::CURLOPT_MAXREDIRS, OptionValueKind::kUint32, true, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS}, + {curl::fuzzer::proto::CURLOPT_MAX_RECV_SPEED_LARGE, OptionValueKind::kUint64, true, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE}, + {curl::fuzzer::proto::CURLOPT_MAX_SEND_SPEED_LARGE, OptionValueKind::kUint64, true, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE}, + {curl::fuzzer::proto::CURLOPT_MIME_OPTIONS, OptionValueKind::kUint32, true, "CURLOPT_MIME_OPTIONS", CURLOPT_MIME_OPTIONS}, + {curl::fuzzer::proto::CURLOPT_NETRC, OptionValueKind::kUint32, true, "CURLOPT_NETRC", CURLOPT_NETRC}, + {curl::fuzzer::proto::CURLOPT_NEW_DIRECTORY_PERMS, OptionValueKind::kUint32, true, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS}, + {curl::fuzzer::proto::CURLOPT_NEW_FILE_PERMS, OptionValueKind::kUint32, true, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS}, + {curl::fuzzer::proto::CURLOPT_NOBODY, OptionValueKind::kUint32, true, "CURLOPT_NOBODY", CURLOPT_NOBODY}, + {curl::fuzzer::proto::CURLOPT_NOPROGRESS, OptionValueKind::kUint32, true, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS}, + {curl::fuzzer::proto::CURLOPT_NOPROXY, OptionValueKind::kString, true, "CURLOPT_NOPROXY", CURLOPT_NOPROXY}, + {curl::fuzzer::proto::CURLOPT_NOSIGNAL, OptionValueKind::kUint32, true, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL}, + {curl::fuzzer::proto::CURLOPT_PASSWORD, OptionValueKind::kString, true, "CURLOPT_PASSWORD", CURLOPT_PASSWORD}, + {curl::fuzzer::proto::CURLOPT_PATH_AS_IS, OptionValueKind::kUint32, true, "CURLOPT_PATH_AS_IS", CURLOPT_PATH_AS_IS}, + {curl::fuzzer::proto::CURLOPT_PINNEDPUBLICKEY, OptionValueKind::kString, true, "CURLOPT_PINNEDPUBLICKEY", CURLOPT_PINNEDPUBLICKEY}, + {curl::fuzzer::proto::CURLOPT_PIPEWAIT, OptionValueKind::kUint32, true, "CURLOPT_PIPEWAIT", CURLOPT_PIPEWAIT}, + {curl::fuzzer::proto::CURLOPT_PORT, OptionValueKind::kUint32, true, "CURLOPT_PORT", CURLOPT_PORT}, + {curl::fuzzer::proto::CURLOPT_POST, OptionValueKind::kUint32, true, "CURLOPT_POST", CURLOPT_POST}, + {curl::fuzzer::proto::CURLOPT_POSTFIELDS, OptionValueKind::kString, true, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS}, + {curl::fuzzer::proto::CURLOPT_POSTFIELDSIZE, OptionValueKind::kUint32, true, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE}, + {curl::fuzzer::proto::CURLOPT_POSTFIELDSIZE_LARGE, OptionValueKind::kUint64, true, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE}, + {curl::fuzzer::proto::CURLOPT_POSTREDIR, OptionValueKind::kUint32, true, "CURLOPT_POSTREDIR", CURLOPT_POSTREDIR}, + {curl::fuzzer::proto::CURLOPT_PRE_PROXY, OptionValueKind::kString, true, "CURLOPT_PRE_PROXY", CURLOPT_PRE_PROXY}, + {curl::fuzzer::proto::CURLOPT_PROXY, OptionValueKind::kString, true, "CURLOPT_PROXY", CURLOPT_PROXY}, + {curl::fuzzer::proto::CURLOPT_PROXYAUTH, OptionValueKind::kUint32, true, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH}, + {curl::fuzzer::proto::CURLOPT_PROXYPASSWORD, OptionValueKind::kString, true, "CURLOPT_PROXYPASSWORD", CURLOPT_PROXYPASSWORD}, + {curl::fuzzer::proto::CURLOPT_PROXYPORT, OptionValueKind::kUint32, true, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT}, + {curl::fuzzer::proto::CURLOPT_PROXYTYPE, OptionValueKind::kUint32, true, "CURLOPT_PROXYTYPE", CURLOPT_PROXYTYPE}, + {curl::fuzzer::proto::CURLOPT_PROXYUSERNAME, OptionValueKind::kString, true, "CURLOPT_PROXYUSERNAME", CURLOPT_PROXYUSERNAME}, + {curl::fuzzer::proto::CURLOPT_PROXYUSERPWD, OptionValueKind::kString, true, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD}, + {curl::fuzzer::proto::CURLOPT_PROXY_CAINFO, OptionValueKind::kString, true, "CURLOPT_PROXY_CAINFO", CURLOPT_PROXY_CAINFO}, + {curl::fuzzer::proto::CURLOPT_PROXY_CAPATH, OptionValueKind::kString, true, "CURLOPT_PROXY_CAPATH", CURLOPT_PROXY_CAPATH}, + {curl::fuzzer::proto::CURLOPT_PROXY_CRLFILE, OptionValueKind::kString, true, "CURLOPT_PROXY_CRLFILE", CURLOPT_PROXY_CRLFILE}, + {curl::fuzzer::proto::CURLOPT_PROXY_ISSUERCERT, OptionValueKind::kString, true, "CURLOPT_PROXY_ISSUERCERT", CURLOPT_PROXY_ISSUERCERT}, + {curl::fuzzer::proto::CURLOPT_PROXY_KEYPASSWD, OptionValueKind::kString, true, "CURLOPT_PROXY_KEYPASSWD", CURLOPT_PROXY_KEYPASSWD}, + {curl::fuzzer::proto::CURLOPT_PROXY_PINNEDPUBLICKEY, OptionValueKind::kString, true, "CURLOPT_PROXY_PINNEDPUBLICKEY", CURLOPT_PROXY_PINNEDPUBLICKEY}, + {curl::fuzzer::proto::CURLOPT_PROXY_SERVICE_NAME, OptionValueKind::kString, true, "CURLOPT_PROXY_SERVICE_NAME", CURLOPT_PROXY_SERVICE_NAME}, + {curl::fuzzer::proto::CURLOPT_PROXY_SSLCERT, OptionValueKind::kString, true, "CURLOPT_PROXY_SSLCERT", CURLOPT_PROXY_SSLCERT}, + {curl::fuzzer::proto::CURLOPT_PROXY_SSLCERTTYPE, OptionValueKind::kString, true, "CURLOPT_PROXY_SSLCERTTYPE", CURLOPT_PROXY_SSLCERTTYPE}, + {curl::fuzzer::proto::CURLOPT_PROXY_SSLKEY, OptionValueKind::kString, true, "CURLOPT_PROXY_SSLKEY", CURLOPT_PROXY_SSLKEY}, + {curl::fuzzer::proto::CURLOPT_PROXY_SSLKEYTYPE, OptionValueKind::kString, true, "CURLOPT_PROXY_SSLKEYTYPE", CURLOPT_PROXY_SSLKEYTYPE}, + {curl::fuzzer::proto::CURLOPT_PROXY_SSLVERSION, OptionValueKind::kUint32, true, "CURLOPT_PROXY_SSLVERSION", CURLOPT_PROXY_SSLVERSION}, + {curl::fuzzer::proto::CURLOPT_PROXY_SSL_CIPHER_LIST, OptionValueKind::kString, true, "CURLOPT_PROXY_SSL_CIPHER_LIST", CURLOPT_PROXY_SSL_CIPHER_LIST}, + {curl::fuzzer::proto::CURLOPT_PROXY_SSL_OPTIONS, OptionValueKind::kUint32, true, "CURLOPT_PROXY_SSL_OPTIONS", CURLOPT_PROXY_SSL_OPTIONS}, + {curl::fuzzer::proto::CURLOPT_PROXY_SSL_VERIFYHOST, OptionValueKind::kUint32, true, "CURLOPT_PROXY_SSL_VERIFYHOST", CURLOPT_PROXY_SSL_VERIFYHOST}, + {curl::fuzzer::proto::CURLOPT_PROXY_SSL_VERIFYPEER, OptionValueKind::kUint32, true, "CURLOPT_PROXY_SSL_VERIFYPEER", CURLOPT_PROXY_SSL_VERIFYPEER}, + {curl::fuzzer::proto::CURLOPT_PROXY_TLS13_CIPHERS, OptionValueKind::kString, true, "CURLOPT_PROXY_TLS13_CIPHERS", CURLOPT_PROXY_TLS13_CIPHERS}, + {curl::fuzzer::proto::CURLOPT_PROXY_TLSAUTH_PASSWORD, OptionValueKind::kString, true, "CURLOPT_PROXY_TLSAUTH_PASSWORD", CURLOPT_PROXY_TLSAUTH_PASSWORD}, + {curl::fuzzer::proto::CURLOPT_PROXY_TLSAUTH_TYPE, OptionValueKind::kString, true, "CURLOPT_PROXY_TLSAUTH_TYPE", CURLOPT_PROXY_TLSAUTH_TYPE}, + {curl::fuzzer::proto::CURLOPT_PROXY_TLSAUTH_USERNAME, OptionValueKind::kString, true, "CURLOPT_PROXY_TLSAUTH_USERNAME", CURLOPT_PROXY_TLSAUTH_USERNAME}, + {curl::fuzzer::proto::CURLOPT_PROXY_TRANSFER_MODE, OptionValueKind::kUint32, true, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE}, + {curl::fuzzer::proto::CURLOPT_QUICK_EXIT, OptionValueKind::kUint32, true, "CURLOPT_QUICK_EXIT", CURLOPT_QUICK_EXIT}, + {curl::fuzzer::proto::CURLOPT_RANGE, OptionValueKind::kString, true, "CURLOPT_RANGE", CURLOPT_RANGE}, + {curl::fuzzer::proto::CURLOPT_REDIR_PROTOCOLS_STR, OptionValueKind::kString, true, "CURLOPT_REDIR_PROTOCOLS_STR", CURLOPT_REDIR_PROTOCOLS_STR}, + {curl::fuzzer::proto::CURLOPT_REFERER, OptionValueKind::kString, true, "CURLOPT_REFERER", CURLOPT_REFERER}, + {curl::fuzzer::proto::CURLOPT_REQUEST_TARGET, OptionValueKind::kString, true, "CURLOPT_REQUEST_TARGET", CURLOPT_REQUEST_TARGET}, + {curl::fuzzer::proto::CURLOPT_RESUME_FROM, OptionValueKind::kUint32, true, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM}, + {curl::fuzzer::proto::CURLOPT_RESUME_FROM_LARGE, OptionValueKind::kUint64, true, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE}, + {curl::fuzzer::proto::CURLOPT_RTSP_CLIENT_CSEQ, OptionValueKind::kUint32, true, "CURLOPT_RTSP_CLIENT_CSEQ", CURLOPT_RTSP_CLIENT_CSEQ}, + {curl::fuzzer::proto::CURLOPT_RTSP_REQUEST, OptionValueKind::kUint32, true, "CURLOPT_RTSP_REQUEST", CURLOPT_RTSP_REQUEST}, + {curl::fuzzer::proto::CURLOPT_RTSP_SERVER_CSEQ, OptionValueKind::kUint32, true, "CURLOPT_RTSP_SERVER_CSEQ", CURLOPT_RTSP_SERVER_CSEQ}, + {curl::fuzzer::proto::CURLOPT_RTSP_SESSION_ID, OptionValueKind::kString, true, "CURLOPT_RTSP_SESSION_ID", CURLOPT_RTSP_SESSION_ID}, + {curl::fuzzer::proto::CURLOPT_RTSP_STREAM_URI, OptionValueKind::kString, true, "CURLOPT_RTSP_STREAM_URI", CURLOPT_RTSP_STREAM_URI}, + {curl::fuzzer::proto::CURLOPT_RTSP_TRANSPORT, OptionValueKind::kString, true, "CURLOPT_RTSP_TRANSPORT", CURLOPT_RTSP_TRANSPORT}, + {curl::fuzzer::proto::CURLOPT_SASL_AUTHZID, OptionValueKind::kString, true, "CURLOPT_SASL_AUTHZID", CURLOPT_SASL_AUTHZID}, + {curl::fuzzer::proto::CURLOPT_SASL_IR, OptionValueKind::kUint32, true, "CURLOPT_SASL_IR", CURLOPT_SASL_IR}, + {curl::fuzzer::proto::CURLOPT_SERVER_RESPONSE_TIMEOUT_MS, OptionValueKind::kUint32, true, "CURLOPT_SERVER_RESPONSE_TIMEOUT_MS", CURLOPT_SERVER_RESPONSE_TIMEOUT_MS}, + {curl::fuzzer::proto::CURLOPT_SERVICE_NAME, OptionValueKind::kString, true, "CURLOPT_SERVICE_NAME", CURLOPT_SERVICE_NAME}, + {curl::fuzzer::proto::CURLOPT_SOCKS5_AUTH, OptionValueKind::kUint32, true, "CURLOPT_SOCKS5_AUTH", CURLOPT_SOCKS5_AUTH}, + {curl::fuzzer::proto::CURLOPT_SOCKS5_GSSAPI_NEC, OptionValueKind::kUint32, true, "CURLOPT_SOCKS5_GSSAPI_NEC", CURLOPT_SOCKS5_GSSAPI_NEC}, + {curl::fuzzer::proto::CURLOPT_SSH_AUTH_TYPES, OptionValueKind::kUint32, true, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES}, + {curl::fuzzer::proto::CURLOPT_SSH_COMPRESSION, OptionValueKind::kUint32, true, "CURLOPT_SSH_COMPRESSION", CURLOPT_SSH_COMPRESSION}, + {curl::fuzzer::proto::CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, OptionValueKind::kString, true, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5}, + {curl::fuzzer::proto::CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, OptionValueKind::kString, true, "CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256", CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256}, + {curl::fuzzer::proto::CURLOPT_SSH_KNOWNHOSTS, OptionValueKind::kString, true, "CURLOPT_SSH_KNOWNHOSTS", CURLOPT_SSH_KNOWNHOSTS}, + {curl::fuzzer::proto::CURLOPT_SSH_PRIVATE_KEYFILE, OptionValueKind::kString, true, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE}, + {curl::fuzzer::proto::CURLOPT_SSH_PUBLIC_KEYFILE, OptionValueKind::kString, true, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE}, + {curl::fuzzer::proto::CURLOPT_SSLCERT, OptionValueKind::kString, true, "CURLOPT_SSLCERT", CURLOPT_SSLCERT}, + {curl::fuzzer::proto::CURLOPT_SSLCERTTYPE, OptionValueKind::kString, true, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE}, + {curl::fuzzer::proto::CURLOPT_SSLENGINE, OptionValueKind::kString, true, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE}, + {curl::fuzzer::proto::CURLOPT_SSLENGINE_DEFAULT, OptionValueKind::kUint32, true, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT}, + {curl::fuzzer::proto::CURLOPT_SSLKEY, OptionValueKind::kString, true, "CURLOPT_SSLKEY", CURLOPT_SSLKEY}, + {curl::fuzzer::proto::CURLOPT_SSLKEYTYPE, OptionValueKind::kString, true, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE}, + {curl::fuzzer::proto::CURLOPT_SSLVERSION, OptionValueKind::kUint32, true, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION}, + {curl::fuzzer::proto::CURLOPT_SSL_CIPHER_LIST, OptionValueKind::kString, true, "CURLOPT_SSL_CIPHER_LIST", CURLOPT_SSL_CIPHER_LIST}, + {curl::fuzzer::proto::CURLOPT_SSL_EC_CURVES, OptionValueKind::kString, true, "CURLOPT_SSL_EC_CURVES", CURLOPT_SSL_EC_CURVES}, + {curl::fuzzer::proto::CURLOPT_SSL_ENABLE_ALPN, OptionValueKind::kUint32, true, "CURLOPT_SSL_ENABLE_ALPN", CURLOPT_SSL_ENABLE_ALPN}, + {curl::fuzzer::proto::CURLOPT_SSL_FALSESTART, OptionValueKind::kUint32, true, "CURLOPT_SSL_FALSESTART", CURLOPT_SSL_FALSESTART}, + {curl::fuzzer::proto::CURLOPT_SSL_OPTIONS, OptionValueKind::kUint32, true, "CURLOPT_SSL_OPTIONS", CURLOPT_SSL_OPTIONS}, + {curl::fuzzer::proto::CURLOPT_SSL_SESSIONID_CACHE, OptionValueKind::kUint32, true, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE}, + {curl::fuzzer::proto::CURLOPT_SSL_VERIFYHOST, OptionValueKind::kUint32, true, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST}, + {curl::fuzzer::proto::CURLOPT_SSL_VERIFYPEER, OptionValueKind::kUint32, true, "CURLOPT_SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER}, + {curl::fuzzer::proto::CURLOPT_SSL_VERIFYSTATUS, OptionValueKind::kUint32, true, "CURLOPT_SSL_VERIFYSTATUS", CURLOPT_SSL_VERIFYSTATUS}, + {curl::fuzzer::proto::CURLOPT_STREAM_WEIGHT, OptionValueKind::kUint32, true, "CURLOPT_STREAM_WEIGHT", CURLOPT_STREAM_WEIGHT}, + {curl::fuzzer::proto::CURLOPT_SUPPRESS_CONNECT_HEADERS, OptionValueKind::kUint32, true, "CURLOPT_SUPPRESS_CONNECT_HEADERS", CURLOPT_SUPPRESS_CONNECT_HEADERS}, + {curl::fuzzer::proto::CURLOPT_TCP_FASTOPEN, OptionValueKind::kUint32, true, "CURLOPT_TCP_FASTOPEN", CURLOPT_TCP_FASTOPEN}, + {curl::fuzzer::proto::CURLOPT_TCP_KEEPALIVE, OptionValueKind::kUint32, true, "CURLOPT_TCP_KEEPALIVE", CURLOPT_TCP_KEEPALIVE}, + {curl::fuzzer::proto::CURLOPT_TCP_KEEPCNT, OptionValueKind::kUint32, true, "CURLOPT_TCP_KEEPCNT", CURLOPT_TCP_KEEPCNT}, + {curl::fuzzer::proto::CURLOPT_TCP_KEEPIDLE, OptionValueKind::kUint32, true, "CURLOPT_TCP_KEEPIDLE", CURLOPT_TCP_KEEPIDLE}, + {curl::fuzzer::proto::CURLOPT_TCP_KEEPINTVL, OptionValueKind::kUint32, true, "CURLOPT_TCP_KEEPINTVL", CURLOPT_TCP_KEEPINTVL}, + {curl::fuzzer::proto::CURLOPT_TCP_NODELAY, OptionValueKind::kUint32, true, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY}, + {curl::fuzzer::proto::CURLOPT_TFTP_BLKSIZE, OptionValueKind::kUint32, true, "CURLOPT_TFTP_BLKSIZE", CURLOPT_TFTP_BLKSIZE}, + {curl::fuzzer::proto::CURLOPT_TFTP_NO_OPTIONS, OptionValueKind::kUint32, true, "CURLOPT_TFTP_NO_OPTIONS", CURLOPT_TFTP_NO_OPTIONS}, + {curl::fuzzer::proto::CURLOPT_TIMECONDITION, OptionValueKind::kUint32, true, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION}, + {curl::fuzzer::proto::CURLOPT_TIMEVALUE, OptionValueKind::kUint32, true, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE}, + {curl::fuzzer::proto::CURLOPT_TIMEVALUE_LARGE, OptionValueKind::kUint64, true, "CURLOPT_TIMEVALUE_LARGE", CURLOPT_TIMEVALUE_LARGE}, + {curl::fuzzer::proto::CURLOPT_TLS13_CIPHERS, OptionValueKind::kString, true, "CURLOPT_TLS13_CIPHERS", CURLOPT_TLS13_CIPHERS}, + {curl::fuzzer::proto::CURLOPT_TLSAUTH_PASSWORD, OptionValueKind::kString, true, "CURLOPT_TLSAUTH_PASSWORD", CURLOPT_TLSAUTH_PASSWORD}, + {curl::fuzzer::proto::CURLOPT_TLSAUTH_TYPE, OptionValueKind::kString, true, "CURLOPT_TLSAUTH_TYPE", CURLOPT_TLSAUTH_TYPE}, + {curl::fuzzer::proto::CURLOPT_TLSAUTH_USERNAME, OptionValueKind::kString, true, "CURLOPT_TLSAUTH_USERNAME", CURLOPT_TLSAUTH_USERNAME}, + {curl::fuzzer::proto::CURLOPT_TRANSFERTEXT, OptionValueKind::kUint32, true, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT}, + {curl::fuzzer::proto::CURLOPT_TRANSFER_ENCODING, OptionValueKind::kUint32, true, "CURLOPT_TRANSFER_ENCODING", CURLOPT_TRANSFER_ENCODING}, + {curl::fuzzer::proto::CURLOPT_UNIX_SOCKET_PATH, OptionValueKind::kString, true, "CURLOPT_UNIX_SOCKET_PATH", CURLOPT_UNIX_SOCKET_PATH}, + {curl::fuzzer::proto::CURLOPT_UNRESTRICTED_AUTH, OptionValueKind::kUint32, true, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH}, + {curl::fuzzer::proto::CURLOPT_UPKEEP_INTERVAL_MS, OptionValueKind::kUint32, true, "CURLOPT_UPKEEP_INTERVAL_MS", CURLOPT_UPKEEP_INTERVAL_MS}, + {curl::fuzzer::proto::CURLOPT_UPLOAD, OptionValueKind::kBool, true, "CURLOPT_UPLOAD", CURLOPT_UPLOAD}, + {curl::fuzzer::proto::CURLOPT_UPLOAD_BUFFERSIZE, OptionValueKind::kUint32, true, "CURLOPT_UPLOAD_BUFFERSIZE", CURLOPT_UPLOAD_BUFFERSIZE}, + {curl::fuzzer::proto::CURLOPT_URL, OptionValueKind::kString, true, "CURLOPT_URL", CURLOPT_URL}, + {curl::fuzzer::proto::CURLOPT_USERAGENT, OptionValueKind::kString, true, "CURLOPT_USERAGENT", CURLOPT_USERAGENT}, + {curl::fuzzer::proto::CURLOPT_USERNAME, OptionValueKind::kString, true, "CURLOPT_USERNAME", CURLOPT_USERNAME}, + {curl::fuzzer::proto::CURLOPT_USERPWD, OptionValueKind::kString, true, "CURLOPT_USERPWD", CURLOPT_USERPWD}, + {curl::fuzzer::proto::CURLOPT_USE_SSL, OptionValueKind::kUint32, true, "CURLOPT_USE_SSL", CURLOPT_USE_SSL}, + {curl::fuzzer::proto::CURLOPT_WILDCARDMATCH, OptionValueKind::kUint32, true, "CURLOPT_WILDCARDMATCH", CURLOPT_WILDCARDMATCH}, + {curl::fuzzer::proto::CURLOPT_WS_OPTIONS, OptionValueKind::kUint32, true, "CURLOPT_WS_OPTIONS", CURLOPT_WS_OPTIONS}, + {curl::fuzzer::proto::CURLOPT_XOAUTH2_BEARER, OptionValueKind::kString, true, "CURLOPT_XOAUTH2_BEARER", CURLOPT_XOAUTH2_BEARER}, +}; +static constexpr size_t kOptionManifestSize = sizeof(kOptionManifest) / sizeof(kOptionManifest[0]); diff --git a/ossfuzz.sh b/ossfuzz.sh index 26f672156..1848e3f29 100755 --- a/ossfuzz.sh +++ b/ossfuzz.sh @@ -38,6 +38,9 @@ export CURL_SOURCE_DIR=/src/curl # Compile the fuzzers. "${SCRIPTDIR}"/compile_target.sh fuzz +# Convert structured scenarios into binary corpora entries. +"${SCRIPTDIR}"/compile_structured_corpora.sh + # Zip up the seed corpus. scripts/create_zip.sh diff --git a/scenarios/curl_fuzzer/oss-fuzz-3327.textproto b/scenarios/curl_fuzzer/oss-fuzz-3327.textproto new file mode 100644 index 000000000..13a89a0b5 --- /dev/null +++ b/scenarios/curl_fuzzer/oss-fuzz-3327.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/oss-fuzz-3327 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "RtSp:/1 " + } +} +connections { + id: 0 + initial_response { + payload: "$ \x00\x00u\x00o" + } +} diff --git a/scenarios/curl_fuzzer/test1.textproto b/scenarios/curl_fuzzer/test1.textproto new file mode 100644 index 000000000..7fa464133 --- /dev/null +++ b/scenarios/curl_fuzzer/test1.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/test1 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:80/1" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake\nLast-Modified: Tue, 13 Jun 2000 12:10:00 GMT\nETag: \x2221025-dc7-39462498\x22\nAccept-Ranges: bytes\nContent-Length: 6\nConnection: close\nContent-Type: text/html\nFunny-head: yesyes\n\n-foo-\n" + } +} diff --git a/scenarios/curl_fuzzer/test10.textproto b/scenarios/curl_fuzzer/test10.textproto new file mode 100644 index 000000000..be56f9d1f --- /dev/null +++ b/scenarios/curl_fuzzer/test10.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer/test10 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/10" + } +} +actions { + register_upload { + payload: "Weird\n file\n to\n upload\nfor\n testing\nthe\n PUT\n feature\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 78 + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.0 200 OK swsclose\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake\n\nblablabla\n\n" + } +} diff --git a/scenarios/curl_fuzzer/test100.textproto b/scenarios/curl_fuzzer/test100.textproto new file mode 100644 index 000000000..41f43a115 --- /dev/null +++ b/scenarios/curl_fuzzer/test100.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/test100 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-100/" + } +} +connections { + id: 0 + initial_response { + payload: "total 20\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 .\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 ..\r\ndrwxr-xr-x 2 98 98 512 May 2 1996 curl-releases\r\n-r--r--r-- 1 0 1 35 Jul 16 1996 README\r\nlrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin\r\ndr-xr-xr-x 2 0 1 512 Oct 1 1997 dev\r\ndrwxrwxrwx 2 98 98 512 May 29 16:04 download.html\r\ndr-xr-xr-x 2 0 1 512 Nov 30 1995 etc\r\ndrwxrwxrwx 2 98 1 512 Oct 30 14:33 pub\r\ndr-xr-xr-x 5 0 1 512 Oct 1 1997 usr\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer/test100_2.textproto b/scenarios/curl_fuzzer/test100_2.textproto new file mode 100644 index 000000000..92ade6d70 --- /dev/null +++ b/scenarios/curl_fuzzer/test100_2.textproto @@ -0,0 +1,30 @@ +# source: corpora/curl_fuzzer/test100_2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-100/" + } +} +connections { + id: 0 + initial_response { + payload: "220 Hello!\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "400 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } +} diff --git a/scenarios/curl_fuzzer/test100_3.textproto b/scenarios/curl_fuzzer/test100_3.textproto new file mode 100644 index 000000000..b84908ce8 --- /dev/null +++ b/scenarios/curl_fuzzer/test100_3.textproto @@ -0,0 +1,48 @@ +# source: corpora/curl_fuzzer/test100_3 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-100" + } +} +connections { + id: 0 + initial_response { + payload: "220 Hello!\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "400 Sure\n" + } + on_readable { + payload: "227 Entering Passive Mode (213,229,112,130,216,4)\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "213 10\n" + } + on_readable { + payload: "125 Already open\n" + } + on_readable { + payload: "226 Sent everything\n" + } +} +connections { + id: 1 + initial_response { + payload: "1234567890" + } + on_readable { + payload: "noworries" + } +} diff --git a/scenarios/curl_fuzzer/test1011.textproto b/scenarios/curl_fuzzer/test1011.textproto new file mode 100644 index 000000000..7d0479471 --- /dev/null +++ b/scenarios/curl_fuzzer/test1011.textproto @@ -0,0 +1,25 @@ +# source: corpora/curl_fuzzer/test1011 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:12345" + } +} +actions { + set_option { + option_id: CURLOPT_FOLLOWLOCATION + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 301 OK\r\nLocation: moo.html&testcase=/10110002\r\nDate: Thu, 09 Nov 2010 14:49:00 GMT\r\nSet-Cookie: firstcookie=want; path=/\r\nContent-Length: 0\r\n\r\n" + } + on_readable { + payload: "HTTP/1.1 200 OK swsclose\r\nLocation: this should be ignored\r\nDate: Thu, 09 Nov 2010 14:49:00 GMT\r\nConnection: close\r\n\r\nbody\r\n" + } +} diff --git a/scenarios/curl_fuzzer/test12.textproto b/scenarios/curl_fuzzer/test12.textproto new file mode 100644 index 000000000..2a6060a35 --- /dev/null +++ b/scenarios/curl_fuzzer/test12.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer/test12 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/12" + } +} +actions { + set_option { + option_id: CURLOPT_RANGE + scope: OPTION_SCOPE_DEFAULT + string_value: "100-200" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 206 Partial Content\r\nDate: Mon, 13 Nov 2000 13:41:09 GMT\r\nServer: Apache/1.3.11 (Unix) PHP/3.0.14\r\nLast-Modified: Tue, 13 Jun 2000 12:10:00 GMT\r\nETag: \x2221025-dc7-39462498\x22\r\nAccept-Ranges: bytes\r\nContent-Length: 101\r\nContent-Range: bytes 100-200/3527\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n..partial data returned from the\nserver as a result of setting an explicit byte range\nin the request\n" + } +} diff --git a/scenarios/curl_fuzzer/test1201.textproto b/scenarios/curl_fuzzer/test1201.textproto new file mode 100644 index 000000000..0931a11b5 --- /dev/null +++ b/scenarios/curl_fuzzer/test1201.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/test1201 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "gopher://127.0.0.1:9009/1/selector/SELECTOR/1201" + } +} +connections { + id: 0 + initial_response { + payload: "iMenu results\t\terror.host\t1\r\n0Selector /selector/SELECTOR\t/bar\tbar.foo.invalid\t70\r\n.\r\n" + } +} diff --git a/scenarios/curl_fuzzer/test13.textproto b/scenarios/curl_fuzzer/test13.textproto new file mode 100644 index 000000000..abadf2819 --- /dev/null +++ b/scenarios/curl_fuzzer/test13.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer/test13 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/13" + } +} +actions { + set_option { + option_id: CURLOPT_CUSTOMREQUEST + scope: OPTION_SCOPE_DEFAULT + string_value: "DELETE" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 Read you\r\nContent-Length: 29\r\nDeleted: suppose we got a header like this! ;-)\r\n\r\nblabla custom request result\n" + } +} diff --git a/scenarios/curl_fuzzer/test1326.textproto b/scenarios/curl_fuzzer/test1326.textproto new file mode 100644 index 000000000..26f9a767e --- /dev/null +++ b/scenarios/curl_fuzzer/test1326.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/test1326 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "telnet://127.0.0.1:8990" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 swsclose\n\nmoo\n" + } +} diff --git a/scenarios/curl_fuzzer/test1450.textproto b/scenarios/curl_fuzzer/test1450.textproto new file mode 100644 index 000000000..d98740cd3 --- /dev/null +++ b/scenarios/curl_fuzzer/test1450.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/test1450 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "dict://127.0.0.1:9016/d:basic" + } +} +connections { + id: 0 + initial_response { + payload: "220 dictserver \n552 no matches\n" + } +} diff --git a/scenarios/curl_fuzzer/test2.textproto b/scenarios/curl_fuzzer/test2.textproto new file mode 100644 index 000000000..68638d515 --- /dev/null +++ b/scenarios/curl_fuzzer/test2.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer/test2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:80/2" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "fake" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake swsclose\nContent-Type: text/html\nFunny-head: yesyes\n" + } +} diff --git a/scenarios/curl_fuzzer/test271.textproto b/scenarios/curl_fuzzer/test271.textproto new file mode 100644 index 000000000..c0481c5ac --- /dev/null +++ b/scenarios/curl_fuzzer/test271.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/test271 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "tftp://127.0.0.1:8997//271" + } +} +connections { + id: 0 + initial_response { + payload: "a chunk of\ndata\nreturned\n to client\n" + } +} diff --git a/scenarios/curl_fuzzer/test3.textproto b/scenarios/curl_fuzzer/test3.textproto new file mode 100644 index 000000000..e7bba25ba --- /dev/null +++ b/scenarios/curl_fuzzer/test3.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer/test3 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/3" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "fake" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_POSTFIELDS + scope: OPTION_SCOPE_DEFAULT + string_value: "fooo=mooo&pooo=clue&doo=%20%20%20++++" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.0 200 OK\r\nServer: test-server/fake\r\nContent-Type: text/html\r\nContent-Length: 0\r\n\r\nthis is data even though Content-Length is set to zero\n" + } +} diff --git a/scenarios/curl_fuzzer/test39.textproto b/scenarios/curl_fuzzer/test39.textproto new file mode 100644 index 000000000..1a75a7966 --- /dev/null +++ b/scenarios/curl_fuzzer/test39.textproto @@ -0,0 +1,23 @@ +# source: corpora/curl_fuzzer/test39 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/39" + } +} +actions { + configure_mime { + parts { + name: "name" + inline_data: "daniel" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\r\nDate: Thu, 09 Nov 2010 14:49:00 GMT\r\nServer: test-server/fake\r\nContent-Length: 10\r\n\r\nblablabla\n" + } +} diff --git a/scenarios/curl_fuzzer/test4.textproto b/scenarios/curl_fuzzer/test4.textproto new file mode 100644 index 000000000..b87a15194 --- /dev/null +++ b/scenarios/curl_fuzzer/test4.textproto @@ -0,0 +1,78 @@ +# source: corpora/curl_fuzzer/test4 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/4" + } +} +actions { + add_header { + value { + text: "extra-header: here" + } + } +} +actions { + add_header { + value { + text: "Accept: replaced" + } + } +} +actions { + add_header { + value { + text: "X-Custom-Header;" + } + } +} +actions { + add_header { + value { + text: "X-Test: foo;" + } + } +} +actions { + add_header { + value { + text: "X-Test:" + } + } +} +actions { + add_header { + value { + text: "X-Test2: foo;" + } + } +} +actions { + add_header { + value { + text: "X-Test3: " + } + } +} +actions { + add_header { + value { + text: "X-Test4; " + } + } +} +actions { + add_header { + value { + text: "X-Test5;ignored" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake swsclose\nContent-Type: text/html\nFunny-head: yesyes\n\n" + } +} diff --git a/corpora/curl_fuzzer/test46 b/scenarios/curl_fuzzer/test46.textproto similarity index 84% rename from corpora/curl_fuzzer/test46 rename to scenarios/curl_fuzzer/test46.textproto index 0523a1dd3..0bda41b01 100644 Binary files a/corpora/curl_fuzzer/test46 and b/scenarios/curl_fuzzer/test46.textproto differ diff --git a/scenarios/curl_fuzzer/test5.textproto b/scenarios/curl_fuzzer/test5.textproto new file mode 100644 index 000000000..407646c4d --- /dev/null +++ b/scenarios/curl_fuzzer/test5.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/test5 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/that/page/5#5" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake swsclose\nContent-Type: text/html\nFunny-head: yesyes\n\n" + } +} diff --git a/scenarios/curl_fuzzer/test567.textproto b/scenarios/curl_fuzzer/test567.textproto new file mode 100644 index 000000000..0280609ee --- /dev/null +++ b/scenarios/curl_fuzzer/test567.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/test567 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1:1234/567" + } +} +connections { + id: 0 + on_readable { + payload: "RTSP/1.0 200 OK\r\nServer: RTSPD/libcurl-test\r\nCSeq: 1\r\nPublic: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE\r\nCurl-Private: swsclose\r\n" + } +} diff --git a/scenarios/curl_fuzzer/test6.textproto b/scenarios/curl_fuzzer/test6.textproto new file mode 100644 index 000000000..5e188c59c --- /dev/null +++ b/scenarios/curl_fuzzer/test6.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer/test6 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/that/page/6" + } +} +actions { + set_option { + option_id: CURLOPT_COOKIE + scope: OPTION_SCOPE_DEFAULT + string_value: "name=contents;name2=content2" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake\nContent-Type: text/html\nFunny-head: yesyes\nswsclose: booo\n\n" + } +} diff --git a/scenarios/curl_fuzzer/test64.textproto b/scenarios/curl_fuzzer/test64.textproto new file mode 100644 index 000000000..ac865ab14 --- /dev/null +++ b/scenarios/curl_fuzzer/test64.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer/test64 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/64" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "james" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "bond" + } +} +actions { + set_option { + option_id: CURLOPT_HTTPAUTH + scope: OPTION_SCOPE_DEFAULT + uint32_value: 2 + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 401 Authorization Required swsclose\r\nServer: Apache/1.3.27 (Darwin) PHP/4.1.2\r\nWWW-Authenticate: Digest realm=\x22testrealm\x22, nonce=\x221053604145\x22\r\nContent-Type: text/html; charset=iso-8859-1\r\nContent-Length: 26\r\n\r\nThis is not the real page\n" + } +} diff --git a/scenarios/curl_fuzzer/test800.textproto b/scenarios/curl_fuzzer/test800.textproto new file mode 100644 index 000000000..f231d3e29 --- /dev/null +++ b/scenarios/curl_fuzzer/test800.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer/test800 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "imap://127.0.0.1:9003/800/;UID=1" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "secret" + } +} +connections { + id: 0 + initial_response { + payload: "From: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n yours sincerely\r\n" + } +} diff --git a/scenarios/curl_fuzzer/test800_2.textproto b/scenarios/curl_fuzzer/test800_2.textproto new file mode 100644 index 000000000..90eec84a6 --- /dev/null +++ b/scenarios/curl_fuzzer/test800_2.textproto @@ -0,0 +1,24 @@ +# source: corpora/curl_fuzzer/test800_2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "imap://127.0.0.1:9003/800/;UID=1" + } +} +connections { + id: 0 + initial_response { + payload: "* OK IMAP4rev1 Service Ready\n" + } + on_readable { + payload: "A001 IMAP4\n" + } + on_readable { + payload: "* 800 EXISTS\nA002 OK [READ-WRITE] SELECT completed\n" + } + on_readable { + payload: "* 1 FETCH (BODY[TEXT] {69}\r\nFrom: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n yours sincerely\r\n)\r\nA003 OK FETCH completed\r\n" + } +} diff --git a/scenarios/curl_fuzzer/test850.textproto b/scenarios/curl_fuzzer/test850.textproto new file mode 100644 index 000000000..fb544decd --- /dev/null +++ b/scenarios/curl_fuzzer/test850.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer/test850 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "pop3://127.0.0.1:9001/850" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "secret" + } +} +connections { + id: 0 + initial_response { + payload: "From: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n yours sincerely\r\n" + } +} diff --git a/scenarios/curl_fuzzer/test900.textproto b/scenarios/curl_fuzzer/test900.textproto new file mode 100644 index 000000000..efb23e3a6 --- /dev/null +++ b/scenarios/curl_fuzzer/test900.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer/test900 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smtp://127.0.0.1:9005/900" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_FROM + scope: OPTION_SCOPE_DEFAULT + string_value: "sender@example.com" + } +} +actions { + register_upload { + payload: "From: different\nTo: another\n\nbody\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 34 + } +} +actions { + add_mail_recipient { + value { + text: "recipient@example.com" + } + } +} +connections { + id: 0 + initial_response { + payload: " " + } +} diff --git a/scenarios/curl_fuzzer/test900_2.textproto b/scenarios/curl_fuzzer/test900_2.textproto new file mode 100644 index 000000000..0576c183d --- /dev/null +++ b/scenarios/curl_fuzzer/test900_2.textproto @@ -0,0 +1,51 @@ +# source: corpora/curl_fuzzer/test900_2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smtp://127.0.0.1:9005/900" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_FROM + scope: OPTION_SCOPE_DEFAULT + string_value: "sender@example.com" + } +} +actions { + register_upload { + payload: "From: different\nTo: another\n\nbody\n.\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 36 + } +} +actions { + add_mail_recipient { + value { + text: "recipient@example.com" + } + } +} +connections { + id: 0 + initial_response { + payload: "220 smtp.example.com ESMTP Postfix\n" + } + on_readable { + payload: "250 SIZE 14680064\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "354 Ok\n" + } + on_readable { + payload: "250 Ok\n" + } +} diff --git a/scenarios/curl_fuzzer/test_accept_encoding.textproto b/scenarios/curl_fuzzer/test_accept_encoding.textproto new file mode 100644 index 000000000..2ecc19930 --- /dev/null +++ b/scenarios/curl_fuzzer/test_accept_encoding.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer/test_accept_encoding + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1/" + } +} +actions { + set_option { + option_id: CURLOPT_ACCEPT_ENCODING + scope: OPTION_SCOPE_DEFAULT + string_value: "" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\r\nDate: Tue, 17 Oct 2017 22:03:56 GMT\r\nContent-Type: application/json\r\nContent-Length: 110\r\nContent-Encoding: gzip\r\n\r\n\x1f\x8b\x08\x00\x08\x7f\xe6Y\x00\x03\xab\xe6RPPJ\xaf\xca,(HMQ\xb2R()*M\xd5Q\x00\x89e\xa4&\xa6\xa4\x16\x15\x03\xc5\xaa\x81\x5c\xa0\x80crrjA\t\x90\xaf\xa4\xa5\xaf\xa5\x04V\x04\x14u\xce\xcf\xcbKM.\xc9\xcc\xcf\x03\xc9$\xe7\xe4\x17\xa7B\xe4j!\xc6\xe4\xa6\x96d\xe4\x83LVrw\r\x01\xc9\xd4r\x01\x00k\x5cH,s\x00\x00\x00" + } +} diff --git a/scenarios/curl_fuzzer/test_file_nobody.textproto b/scenarios/curl_fuzzer/test_file_nobody.textproto new file mode 100644 index 000000000..25884b4fa --- /dev/null +++ b/scenarios/curl_fuzzer/test_file_nobody.textproto @@ -0,0 +1,23 @@ +# source: corpora/curl_fuzzer/test_file_nobody + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "file:///proc/self/status" + } +} +actions { + set_option { + option_id: CURLOPT_HEADER + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} +actions { + set_option { + option_id: CURLOPT_NOBODY + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} diff --git a/scenarios/curl_fuzzer/test_ftp_list.textproto b/scenarios/curl_fuzzer/test_ftp_list.textproto new file mode 100644 index 000000000..2f8f28960 --- /dev/null +++ b/scenarios/curl_fuzzer/test_ftp_list.textproto @@ -0,0 +1,52 @@ +# source: corpora/curl_fuzzer/test_ftp_list + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-list/" + } +} +actions { + set_option { + option_id: CURLOPT_WILDCARDMATCH + scope: OPTION_SCOPE_DEFAULT + uint32_value: 0 + } +} +connections { + id: 0 + initial_response { + payload: "220 Hello!\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "400 Sure\n" + } + on_readable { + payload: "227 Entering Passive Mode (213,229,112,130,216,4)\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "150 Success\r\n226 Everything sent\r\n" + } + on_readable { + payload: "200 Sure\n" + } +} +connections { + id: 1 + initial_response { + payload: "total 20\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 .\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 ..\r\ndrwxr-xr-x 2 98 98 512 May 2 1996 .NeXT\r\n-r--r--r-- 1 0 1 35 Jul 16 1996 README\r\nlrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin\r\ndr-xr-xr-x 2 0 1 512 Oct 1 1997 dev\r\ndrwxrwxrwx 2 98 98 512 May 29 16:04 download.html\r\ndr-xr-xr-x 2 0 1 512 Nov 30 1995 etc\r\ndrwxrwxrwx 2 98 1 512 Oct 30 14:33 pub\r\ndr-xr-xr-x 5 0 1 512 Oct 1 1997 usr\r\n" + } +} diff --git a/scenarios/curl_fuzzer/test_ftp_wildcard.textproto b/scenarios/curl_fuzzer/test_ftp_wildcard.textproto new file mode 100644 index 000000000..104e40170 --- /dev/null +++ b/scenarios/curl_fuzzer/test_ftp_wildcard.textproto @@ -0,0 +1,52 @@ +# source: corpora/curl_fuzzer/test_ftp_wildcard + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-list/*.html" + } +} +actions { + set_option { + option_id: CURLOPT_WILDCARDMATCH + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} +connections { + id: 0 + initial_response { + payload: "220 Hello!\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "400 Sure\n" + } + on_readable { + payload: "227 Entering Passive Mode (213,229,112,130,216,4)\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "150 Success\r\n226 Everything sent\r\n" + } + on_readable { + payload: "200 Sure\n" + } +} +connections { + id: 1 + initial_response { + payload: "total 20\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 .\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 ..\r\ndrwxr-xr-x 2 98 98 512 May 2 1996 .NeXT\r\n-r--r--r-- 1 0 1 35 Jul 16 1996 README\r\nlrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin\r\ndr-xr-xr-x 2 0 1 512 Oct 1 1997 dev\r\ndrwxrwxrwx 2 98 98 512 May 29 16:04 download.html\r\ndr-xr-xr-x 2 0 1 512 Nov 30 1995 etc\r\ndrwxrwxrwx 2 98 1 512 Oct 30 14:33 pub\r\ndr-xr-xr-x 5 0 1 512 Oct 1 1997 usr\r\n" + } +} diff --git a/scenarios/curl_fuzzer/test_wrongproto.textproto b/scenarios/curl_fuzzer/test_wrongproto.textproto new file mode 100644 index 000000000..5619086a6 --- /dev/null +++ b/scenarios/curl_fuzzer/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer/timeout-4625841444093952.textproto b/scenarios/curl_fuzzer/timeout-4625841444093952.textproto new file mode 100644 index 000000000..460706da5 --- /dev/null +++ b/scenarios/curl_fuzzer/timeout-4625841444093952.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer/timeout-4625841444093952 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + bytes_value: "telnet:/0@2\000\000\000>0\xe71:8990" + } +} +connections { + id: 0 + initial_response { + payload: "ttp://1@7.0.0.1:8990/we/want/12\x00\x02\x00\x00\x01\x97HTTP/1.1 206 Partial Content\r\neleases\r\n-r--r--r-- 1 35 Jul 16 19ad.html\r\n000 bin -> usr/bin\r\ndr 1 /1ad.htm9\r'l\n99 b 1 i /1ad.htm\x00\x01\x00\x00\x00\x19pop3)//126.070.0:9\x84#0/850\x00\x02\x00\x00\x00F+\x1c\x00\x00\x00\x00\x00\x00\x00\x9b\xbf\x82omewhke@\xeeowe\rh\n..+\n-E\xb5Rybs oiu\x9a\x8cely\r\n+OKF\n\r\nehn.ow\r.\r\n-E*noswsclose\n;mode= 201 04:149:00 GMT\nS\x00\x00\x00\x04fake\x00\x04\x00\x00\x00\x04use r00 bin -> usr/bin\r\ndr 1 1 35 Jul 16 19ad.html\r\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xef\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xff.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\x00\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff/1.\xfd\xfd\xff\xfb 98 # .htmx 8 98 \x00\x01\x00\x00\x00 http://127.0.0\x00\x01\x00\x06\x00\x17tr 1 1 35 Jul 16 19ad.html\r\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfe\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff # .htmx 8 98 \x00\x01\x00\x00\x00 http://127.0.0\x00\x01\x00\x06\x00\x17tr 1 1 35 Jul 16 19ad.h\xa7ml\r\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\x00\xfa\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%\n000 bi\x00\x01\x00\x00001 \n\xc6002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xff.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/X&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%dSp@/ \x003://127.070.0:9000/850\x00\x02\x00\x00\x00F+OKF\n\rr me@some./whke@nowe\rh\n..\r\n-\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff # .htmx 8 98 \x00\x01\x00\x00\x00 http://127.0.0\x00\x01\x00\x06\x00\x17tr 1 1 35 Jul 16 19ad.h\xa7ml\r\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xef\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xff.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/X&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%\n000 bi\x00\x01\x00\x00001 \nA2 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/X&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%\n000 bi\x00\x01\x00\x00001 \nA2 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb 98 # .htmx5\x00/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb \r\r\r\x00w\xff\xfa\xff\xfasC\r\xffw\x00\r\xfa\xff\xfbsC\r\r\x00w\xff\xfa\xff\xfa200\nm\n0.1:\x00\x01\x00\x00\x00\x08%\n000 bi\x00\x01\x00\x00001 \nA002 OKo\xe6err\xe5s\n\r-\n* \xff\xfa\x18/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\xff\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1.\xfd\xfd\xff\xfb / 98 \x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xff\xfc\xff\xff\xfa\xff/1&\xff\xff\xff\xfd0\x00\x02\x00\x00\x00\n\r\xff\xff\xfb\xff/1.\x8c\xff\xfd\xfd\xff\xfb\x01\x1f\xff\xfc\x01\xffs/1.\xff\xff\xff\xfb\xff/1/ 98 \x00y\xff\x1e\xff\xfc\xff\xef\xfa'\xff/1&\xff\xff\xff\xfd\x1f\x07\xfc\xff\xff\xfa\xff1:\xff\x01\x00\x00y\xff\x1e\xffbytes\n\r00-200/3527\r\nConnectiMTs\nD\r00-200/3527\r\nC/" + } +} diff --git a/scenarios/curl_fuzzer_dict/test1450.textproto b/scenarios/curl_fuzzer_dict/test1450.textproto new file mode 100644 index 000000000..6f09d85f0 --- /dev/null +++ b/scenarios/curl_fuzzer_dict/test1450.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_dict/test1450 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "dict://127.0.0.1:9016/d:basic" + } +} +connections { + id: 0 + initial_response { + payload: "220 dictserver \n552 no matches\n" + } +} diff --git a/scenarios/curl_fuzzer_dict/test_url_dict.textproto b/scenarios/curl_fuzzer_dict/test_url_dict.textproto new file mode 100644 index 000000000..4ac2869a6 --- /dev/null +++ b/scenarios/curl_fuzzer_dict/test_url_dict.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_dict/test_url_dict + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "dict://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_dict/test_wrongproto.textproto b/scenarios/curl_fuzzer_dict/test_wrongproto.textproto new file mode 100644 index 000000000..ce165d5dc --- /dev/null +++ b/scenarios/curl_fuzzer_dict/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_dict/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_file/test_file_nobody.textproto b/scenarios/curl_fuzzer_file/test_file_nobody.textproto new file mode 100644 index 000000000..f5cad9fe3 --- /dev/null +++ b/scenarios/curl_fuzzer_file/test_file_nobody.textproto @@ -0,0 +1,23 @@ +# source: corpora/curl_fuzzer_file/test_file_nobody + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "file:///proc/self/status" + } +} +actions { + set_option { + option_id: CURLOPT_HEADER + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} +actions { + set_option { + option_id: CURLOPT_NOBODY + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} diff --git a/scenarios/curl_fuzzer_file/test_url_file.textproto b/scenarios/curl_fuzzer_file/test_url_file.textproto new file mode 100644 index 000000000..202085a4e --- /dev/null +++ b/scenarios/curl_fuzzer_file/test_url_file.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_file/test_url_file + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "file://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_file/test_wrongproto.textproto b/scenarios/curl_fuzzer_file/test_wrongproto.textproto new file mode 100644 index 000000000..48720e0e7 --- /dev/null +++ b/scenarios/curl_fuzzer_file/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_file/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_ftp/test_ftp_list.textproto b/scenarios/curl_fuzzer_ftp/test_ftp_list.textproto new file mode 100644 index 000000000..76ae8571f --- /dev/null +++ b/scenarios/curl_fuzzer_ftp/test_ftp_list.textproto @@ -0,0 +1,52 @@ +# source: corpora/curl_fuzzer_ftp/test_ftp_list + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-list/" + } +} +actions { + set_option { + option_id: CURLOPT_WILDCARDMATCH + scope: OPTION_SCOPE_DEFAULT + uint32_value: 0 + } +} +connections { + id: 0 + initial_response { + payload: "220 Hello!\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "400 Sure\n" + } + on_readable { + payload: "227 Entering Passive Mode (213,229,112,130,216,4)\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "150 Success\r\n226 Everything sent\r\n" + } + on_readable { + payload: "200 Sure\n" + } +} +connections { + id: 1 + initial_response { + payload: "total 20\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 .\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 ..\r\ndrwxr-xr-x 2 98 98 512 May 2 1996 .NeXT\r\n-r--r--r-- 1 0 1 35 Jul 16 1996 README\r\nlrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin\r\ndr-xr-xr-x 2 0 1 512 Oct 1 1997 dev\r\ndrwxrwxrwx 2 98 98 512 May 29 16:04 download.html\r\ndr-xr-xr-x 2 0 1 512 Nov 30 1995 etc\r\ndrwxrwxrwx 2 98 1 512 Oct 30 14:33 pub\r\ndr-xr-xr-x 5 0 1 512 Oct 1 1997 usr\r\n" + } +} diff --git a/scenarios/curl_fuzzer_ftp/test_ftp_wildcard.textproto b/scenarios/curl_fuzzer_ftp/test_ftp_wildcard.textproto new file mode 100644 index 000000000..cea46f818 --- /dev/null +++ b/scenarios/curl_fuzzer_ftp/test_ftp_wildcard.textproto @@ -0,0 +1,52 @@ +# source: corpora/curl_fuzzer_ftp/test_ftp_wildcard + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-list/*.html" + } +} +actions { + set_option { + option_id: CURLOPT_WILDCARDMATCH + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} +connections { + id: 0 + initial_response { + payload: "220 Hello!\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "400 Sure\n" + } + on_readable { + payload: "227 Entering Passive Mode (213,229,112,130,216,4)\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "150 Success\r\n226 Everything sent\r\n" + } + on_readable { + payload: "200 Sure\n" + } +} +connections { + id: 1 + initial_response { + payload: "total 20\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 .\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 ..\r\ndrwxr-xr-x 2 98 98 512 May 2 1996 .NeXT\r\n-r--r--r-- 1 0 1 35 Jul 16 1996 README\r\nlrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin\r\ndr-xr-xr-x 2 0 1 512 Oct 1 1997 dev\r\ndrwxrwxrwx 2 98 98 512 May 29 16:04 download.html\r\ndr-xr-xr-x 2 0 1 512 Nov 30 1995 etc\r\ndrwxrwxrwx 2 98 1 512 Oct 30 14:33 pub\r\ndr-xr-xr-x 5 0 1 512 Oct 1 1997 usr\r\n" + } +} diff --git a/scenarios/curl_fuzzer_ftp/test_url_ftp.textproto b/scenarios/curl_fuzzer_ftp/test_url_ftp.textproto new file mode 100644 index 000000000..040db114a --- /dev/null +++ b/scenarios/curl_fuzzer_ftp/test_url_ftp.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_ftp/test_url_ftp + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_ftp/test_wrongproto.textproto b/scenarios/curl_fuzzer_ftp/test_wrongproto.textproto new file mode 100644 index 000000000..a71ac2495 --- /dev/null +++ b/scenarios/curl_fuzzer_ftp/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_ftp/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_gopher/test1201.textproto b/scenarios/curl_fuzzer_gopher/test1201.textproto new file mode 100644 index 000000000..502a7076b --- /dev/null +++ b/scenarios/curl_fuzzer_gopher/test1201.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_gopher/test1201 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "gopher://127.0.0.1:9009/1/selector/SELECTOR/1201" + } +} +connections { + id: 0 + initial_response { + payload: "iMenu results\t\terror.host\t1\r\n0Selector /selector/SELECTOR\t/bar\tbar.foo.invalid\t70\r\n.\r\n" + } +} diff --git a/scenarios/curl_fuzzer_gopher/test_url_gopher.textproto b/scenarios/curl_fuzzer_gopher/test_url_gopher.textproto new file mode 100644 index 000000000..ee9ae460e --- /dev/null +++ b/scenarios/curl_fuzzer_gopher/test_url_gopher.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_gopher/test_url_gopher + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "gopher://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_gopher/test_wrongproto.textproto b/scenarios/curl_fuzzer_gopher/test_wrongproto.textproto new file mode 100644 index 000000000..bea2d2a85 --- /dev/null +++ b/scenarios/curl_fuzzer_gopher/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_gopher/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_http/test1.textproto b/scenarios/curl_fuzzer_http/test1.textproto new file mode 100644 index 000000000..bff9d0bcb --- /dev/null +++ b/scenarios/curl_fuzzer_http/test1.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_http/test1 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:80/1" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake\nLast-Modified: Tue, 13 Jun 2000 12:10:00 GMT\nETag: \x2221025-dc7-39462498\x22\nAccept-Ranges: bytes\nContent-Length: 6\nConnection: close\nContent-Type: text/html\nFunny-head: yesyes\n\n-foo-\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test10.textproto b/scenarios/curl_fuzzer_http/test10.textproto new file mode 100644 index 000000000..94913f967 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test10.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_http/test10 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/10" + } +} +actions { + register_upload { + payload: "Weird\n file\n to\n upload\nfor\n testing\nthe\n PUT\n feature\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 78 + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.0 200 OK swsclose\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake\n\nblablabla\n\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test100.textproto b/scenarios/curl_fuzzer_http/test100.textproto new file mode 100644 index 000000000..548cdd2b0 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test100.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_http/test100 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-100/" + } +} +connections { + id: 0 + initial_response { + payload: "total 20\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 .\r\ndrwxr-xr-x 8 98 98 512 Oct 22 13:06 ..\r\ndrwxr-xr-x 2 98 98 512 May 2 1996 curl-releases\r\n-r--r--r-- 1 0 1 35 Jul 16 1996 README\r\nlrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin\r\ndr-xr-xr-x 2 0 1 512 Oct 1 1997 dev\r\ndrwxrwxrwx 2 98 98 512 May 29 16:04 download.html\r\ndr-xr-xr-x 2 0 1 512 Nov 30 1995 etc\r\ndrwxrwxrwx 2 98 1 512 Oct 30 14:33 pub\r\ndr-xr-xr-x 5 0 1 512 Oct 1 1997 usr\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test100_2.textproto b/scenarios/curl_fuzzer_http/test100_2.textproto new file mode 100644 index 000000000..4a93ade96 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test100_2.textproto @@ -0,0 +1,30 @@ +# source: corpora/curl_fuzzer_http/test100_2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-100/" + } +} +connections { + id: 0 + initial_response { + payload: "220 Hello!\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "400 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test100_3.textproto b/scenarios/curl_fuzzer_http/test100_3.textproto new file mode 100644 index 000000000..bc6ae38d8 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test100_3.textproto @@ -0,0 +1,48 @@ +# source: corpora/curl_fuzzer_http/test100_3 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ftp://127.0.0.1:8992/test-100" + } +} +connections { + id: 0 + initial_response { + payload: "220 Hello!\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "400 Sure\n" + } + on_readable { + payload: "227 Entering Passive Mode (213,229,112,130,216,4)\n" + } + on_readable { + payload: "200 Sure\n" + } + on_readable { + payload: "213 10\n" + } + on_readable { + payload: "125 Already open\n" + } + on_readable { + payload: "226 Sent everything\n" + } +} +connections { + id: 1 + initial_response { + payload: "1234567890" + } + on_readable { + payload: "noworries" + } +} diff --git a/scenarios/curl_fuzzer_http/test1011.textproto b/scenarios/curl_fuzzer_http/test1011.textproto new file mode 100644 index 000000000..122406559 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test1011.textproto @@ -0,0 +1,25 @@ +# source: corpora/curl_fuzzer_http/test1011 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:12345" + } +} +actions { + set_option { + option_id: CURLOPT_FOLLOWLOCATION + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 301 OK\r\nLocation: moo.html&testcase=/10110002\r\nDate: Thu, 09 Nov 2010 14:49:00 GMT\r\nSet-Cookie: firstcookie=want; path=/\r\nContent-Length: 0\r\n\r\n" + } + on_readable { + payload: "HTTP/1.1 200 OK swsclose\r\nLocation: this should be ignored\r\nDate: Thu, 09 Nov 2010 14:49:00 GMT\r\nConnection: close\r\n\r\nbody\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test12.textproto b/scenarios/curl_fuzzer_http/test12.textproto new file mode 100644 index 000000000..f51cbaeb3 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test12.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_http/test12 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/12" + } +} +actions { + set_option { + option_id: CURLOPT_RANGE + scope: OPTION_SCOPE_DEFAULT + string_value: "100-200" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 206 Partial Content\r\nDate: Mon, 13 Nov 2000 13:41:09 GMT\r\nServer: Apache/1.3.11 (Unix) PHP/3.0.14\r\nLast-Modified: Tue, 13 Jun 2000 12:10:00 GMT\r\nETag: \x2221025-dc7-39462498\x22\r\nAccept-Ranges: bytes\r\nContent-Length: 101\r\nContent-Range: bytes 100-200/3527\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n..partial data returned from the\nserver as a result of setting an explicit byte range\nin the request\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test1201.textproto b/scenarios/curl_fuzzer_http/test1201.textproto new file mode 100644 index 000000000..9e0905d37 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test1201.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_http/test1201 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "gopher://127.0.0.1:9009/1/selector/SELECTOR/1201" + } +} +connections { + id: 0 + initial_response { + payload: "iMenu results\t\terror.host\t1\r\n0Selector /selector/SELECTOR\t/bar\tbar.foo.invalid\t70\r\n.\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test13.textproto b/scenarios/curl_fuzzer_http/test13.textproto new file mode 100644 index 000000000..9d24bdeff --- /dev/null +++ b/scenarios/curl_fuzzer_http/test13.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_http/test13 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/13" + } +} +actions { + set_option { + option_id: CURLOPT_CUSTOMREQUEST + scope: OPTION_SCOPE_DEFAULT + string_value: "DELETE" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 Read you\r\nContent-Length: 29\r\nDeleted: suppose we got a header like this! ;-)\r\n\r\nblabla custom request result\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test1326.textproto b/scenarios/curl_fuzzer_http/test1326.textproto new file mode 100644 index 000000000..762586bb5 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test1326.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_http/test1326 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "telnet://127.0.0.1:8990" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 swsclose\n\nmoo\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test1450.textproto b/scenarios/curl_fuzzer_http/test1450.textproto new file mode 100644 index 000000000..43728c92f --- /dev/null +++ b/scenarios/curl_fuzzer_http/test1450.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_http/test1450 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "dict://127.0.0.1:9016/d:basic" + } +} +connections { + id: 0 + initial_response { + payload: "220 dictserver \n552 no matches\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test2.textproto b/scenarios/curl_fuzzer_http/test2.textproto new file mode 100644 index 000000000..b69d99bdc --- /dev/null +++ b/scenarios/curl_fuzzer_http/test2.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer_http/test2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:80/2" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "fake" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake swsclose\nContent-Type: text/html\nFunny-head: yesyes\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test271.textproto b/scenarios/curl_fuzzer_http/test271.textproto new file mode 100644 index 000000000..14c1eaa60 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test271.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_http/test271 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "tftp://127.0.0.1:8997//271" + } +} +connections { + id: 0 + initial_response { + payload: "a chunk of\ndata\nreturned\n to client\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test3.textproto b/scenarios/curl_fuzzer_http/test3.textproto new file mode 100644 index 000000000..2089200d4 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test3.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_http/test3 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/3" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "fake" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_POSTFIELDS + scope: OPTION_SCOPE_DEFAULT + string_value: "fooo=mooo&pooo=clue&doo=%20%20%20++++" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.0 200 OK\r\nServer: test-server/fake\r\nContent-Type: text/html\r\nContent-Length: 0\r\n\r\nthis is data even though Content-Length is set to zero\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test39.textproto b/scenarios/curl_fuzzer_http/test39.textproto new file mode 100644 index 000000000..7316f3673 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test39.textproto @@ -0,0 +1,23 @@ +# source: corpora/curl_fuzzer_http/test39 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/39" + } +} +actions { + configure_mime { + parts { + name: "name" + inline_data: "daniel" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\r\nDate: Thu, 09 Nov 2010 14:49:00 GMT\r\nServer: test-server/fake\r\nContent-Length: 10\r\n\r\nblablabla\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test4.textproto b/scenarios/curl_fuzzer_http/test4.textproto new file mode 100644 index 000000000..b569747da --- /dev/null +++ b/scenarios/curl_fuzzer_http/test4.textproto @@ -0,0 +1,78 @@ +# source: corpora/curl_fuzzer_http/test4 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/4" + } +} +actions { + add_header { + value { + text: "extra-header: here" + } + } +} +actions { + add_header { + value { + text: "Accept: replaced" + } + } +} +actions { + add_header { + value { + text: "X-Custom-Header;" + } + } +} +actions { + add_header { + value { + text: "X-Test: foo;" + } + } +} +actions { + add_header { + value { + text: "X-Test:" + } + } +} +actions { + add_header { + value { + text: "X-Test2: foo;" + } + } +} +actions { + add_header { + value { + text: "X-Test3: " + } + } +} +actions { + add_header { + value { + text: "X-Test4; " + } + } +} +actions { + add_header { + value { + text: "X-Test5;ignored" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake swsclose\nContent-Type: text/html\nFunny-head: yesyes\n\n" + } +} diff --git a/corpora/curl_fuzzer_http/test46 b/scenarios/curl_fuzzer_http/test46.textproto similarity index 84% rename from corpora/curl_fuzzer_http/test46 rename to scenarios/curl_fuzzer_http/test46.textproto index 0523a1dd3..c8931db48 100644 Binary files a/corpora/curl_fuzzer_http/test46 and b/scenarios/curl_fuzzer_http/test46.textproto differ diff --git a/scenarios/curl_fuzzer_http/test5.textproto b/scenarios/curl_fuzzer_http/test5.textproto new file mode 100644 index 000000000..cfcfa8204 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test5.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_http/test5 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/that/page/5#5" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake swsclose\nContent-Type: text/html\nFunny-head: yesyes\n\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test567.textproto b/scenarios/curl_fuzzer_http/test567.textproto new file mode 100644 index 000000000..02e21d3a4 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test567.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_http/test567 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1:1234/567" + } +} +connections { + id: 0 + on_readable { + payload: "RTSP/1.0 200 OK\r\nServer: RTSPD/libcurl-test\r\nCSeq: 1\r\nPublic: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE\r\nCurl-Private: swsclose\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test6.textproto b/scenarios/curl_fuzzer_http/test6.textproto new file mode 100644 index 000000000..85088a65f --- /dev/null +++ b/scenarios/curl_fuzzer_http/test6.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_http/test6 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/we/want/that/page/6" + } +} +actions { + set_option { + option_id: CURLOPT_COOKIE + scope: OPTION_SCOPE_DEFAULT + string_value: "name=contents;name2=content2" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\nDate: Thu, 09 Nov 2010 14:49:00 GMT\nServer: test-server/fake\nContent-Type: text/html\nFunny-head: yesyes\nswsclose: booo\n\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test64.textproto b/scenarios/curl_fuzzer_http/test64.textproto new file mode 100644 index 000000000..0f926f80d --- /dev/null +++ b/scenarios/curl_fuzzer_http/test64.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_http/test64 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1:8990/64" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "james" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "bond" + } +} +actions { + set_option { + option_id: CURLOPT_HTTPAUTH + scope: OPTION_SCOPE_DEFAULT + uint32_value: 2 + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 401 Authorization Required swsclose\r\nServer: Apache/1.3.27 (Darwin) PHP/4.1.2\r\nWWW-Authenticate: Digest realm=\x22testrealm\x22, nonce=\x221053604145\x22\r\nContent-Type: text/html; charset=iso-8859-1\r\nContent-Length: 26\r\n\r\nThis is not the real page\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test800.textproto b/scenarios/curl_fuzzer_http/test800.textproto new file mode 100644 index 000000000..a41c06170 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test800.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer_http/test800 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "imap://127.0.0.1:9003/800/;UID=1" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "secret" + } +} +connections { + id: 0 + initial_response { + payload: "From: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n yours sincerely\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test800_2.textproto b/scenarios/curl_fuzzer_http/test800_2.textproto new file mode 100644 index 000000000..baf762609 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test800_2.textproto @@ -0,0 +1,24 @@ +# source: corpora/curl_fuzzer_http/test800_2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "imap://127.0.0.1:9003/800/;UID=1" + } +} +connections { + id: 0 + initial_response { + payload: "* OK IMAP4rev1 Service Ready\n" + } + on_readable { + payload: "A001 IMAP4\n" + } + on_readable { + payload: "* 800 EXISTS\nA002 OK [READ-WRITE] SELECT completed\n" + } + on_readable { + payload: "* 1 FETCH (BODY[TEXT] {69}\r\nFrom: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n yours sincerely\r\n)\r\nA003 OK FETCH completed\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test850.textproto b/scenarios/curl_fuzzer_http/test850.textproto new file mode 100644 index 000000000..8bd44477a --- /dev/null +++ b/scenarios/curl_fuzzer_http/test850.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer_http/test850 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "pop3://127.0.0.1:9001/850" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "secret" + } +} +connections { + id: 0 + initial_response { + payload: "From: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n yours sincerely\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test900.textproto b/scenarios/curl_fuzzer_http/test900.textproto new file mode 100644 index 000000000..60c386465 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test900.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_http/test900 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smtp://127.0.0.1:9005/900" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_FROM + scope: OPTION_SCOPE_DEFAULT + string_value: "sender@example.com" + } +} +actions { + register_upload { + payload: "From: different\nTo: another\n\nbody\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 34 + } +} +actions { + add_mail_recipient { + value { + text: "recipient@example.com" + } + } +} +connections { + id: 0 + initial_response { + payload: " " + } +} diff --git a/scenarios/curl_fuzzer_http/test900_2.textproto b/scenarios/curl_fuzzer_http/test900_2.textproto new file mode 100644 index 000000000..aaff8a73e --- /dev/null +++ b/scenarios/curl_fuzzer_http/test900_2.textproto @@ -0,0 +1,51 @@ +# source: corpora/curl_fuzzer_http/test900_2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smtp://127.0.0.1:9005/900" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_FROM + scope: OPTION_SCOPE_DEFAULT + string_value: "sender@example.com" + } +} +actions { + register_upload { + payload: "From: different\nTo: another\n\nbody\n.\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 36 + } +} +actions { + add_mail_recipient { + value { + text: "recipient@example.com" + } + } +} +connections { + id: 0 + initial_response { + payload: "220 smtp.example.com ESMTP Postfix\n" + } + on_readable { + payload: "250 SIZE 14680064\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "354 Ok\n" + } + on_readable { + payload: "250 Ok\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test_accept_encoding.textproto b/scenarios/curl_fuzzer_http/test_accept_encoding.textproto new file mode 100644 index 000000000..615ce0dd9 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_accept_encoding.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_http/test_accept_encoding + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1/" + } +} +actions { + set_option { + option_id: CURLOPT_ACCEPT_ENCODING + scope: OPTION_SCOPE_DEFAULT + string_value: "" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\r\nDate: Tue, 17 Oct 2017 22:03:56 GMT\r\nContent-Type: application/json\r\nContent-Length: 110\r\nContent-Encoding: gzip\r\n\r\n\x1f\x8b\x08\x00\x08\x7f\xe6Y\x00\x03\xab\xe6RPPJ\xaf\xca,(HMQ\xb2R()*M\xd5Q\x00\x89e\xa4&\xa6\xa4\x16\x15\x03\xc5\xaa\x81\x5c\xa0\x80crrjA\t\x90\xaf\xa4\xa5\xaf\xa5\x04V\x04\x14u\xce\xcf\xcbKM.\xc9\xcc\xcf\x03\xc9$\xe7\xe4\x17\xa7B\xe4j!\xc6\xe4\xa6\x96d\xe4\x83LVrw\r\x01\xc9\xd4r\x01\x00k\x5cH,s\x00\x00\x00" + } +} diff --git a/scenarios/curl_fuzzer_http/test_alt_svc.textproto b/scenarios/curl_fuzzer_http/test_alt_svc.textproto new file mode 100644 index 000000000..4d8422858 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_alt_svc.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_http/test_alt_svc + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://server.example.com" + } +} +actions { + add_header { + value { + text: "Origin: http://example.com" + } + } +} +actions { + add_header { + value { + text: "X-Foo-3: ba\tr" + } + } +} +actions { + add_header { + value { + text: "Cookie: __m=-1" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\r\nHost: server.example.com\r\nAlt-Svc: clear\r\nConnection: Keep-Alive\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test_alt_svc_with_ma.textproto b/scenarios/curl_fuzzer_http/test_alt_svc_with_ma.textproto new file mode 100644 index 000000000..b873daa9e --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_alt_svc_with_ma.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_http/test_alt_svc_with_ma + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://server.example.com" + } +} +actions { + add_header { + value { + text: "Origin: http://example.com" + } + } +} +actions { + add_header { + value { + text: "X-Foo-3: ba\tr" + } + } +} +actions { + add_header { + value { + text: "Cookie: __m=-1" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\r\nHost: server.example.com\r\nAlt-Svc: h2=\x22alt.example.com:443\x22, h2=\x22:443\x22\r\nConnection: Keep-Alive\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test_basic_http2.textproto b/scenarios/curl_fuzzer_http/test_basic_http2.textproto new file mode 100644 index 000000000..41544e9ce --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_basic_http2.textproto @@ -0,0 +1,25 @@ +# source: corpora/curl_fuzzer_http/test_basic_http2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1" + } +} +actions { + set_option { + option_id: CURLOPT_HTTP_VERSION + scope: OPTION_SCOPE_DEFAULT + uint32_value: 5 + } +} +connections { + id: 0 + initial_response { + payload: "\x00\x00\x18\x04\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00d\x00\x04\x00\x10\x00\x00\x00\x08\x00\x00\x00\x01\x00\x01\x00\x00 \x00\x00\x00\xbc\x01\x04\x00\x00\x00\x01\x88a\x96\xdfi~\x94\x0b\xaaC]\x8a\x08\x01y@?p\x0f\x5cm\xc51h\xdf_\x8b\x1du\xd0b\r&=LtA\xea\x0f\r\x82\x10[T\x01*@\x96\x19\x08T!b\x1e\xa4\xd8z\x16\x1d\x14\x1f\xc2\xc4\xb0\xb2\x16\xa4\x98t#\x83M\x96\x97@\x8f\xf2\xb4c'R\xd5\x22\xd3\x94r\x16\xc5\xacJ\x7f\x86\x02\xe0\x03\x22\x03\xbfv\x86\xaai\xd2\x9a\xfc\xff|\x88\n\xe1R\xa9\xa7Jk\xf3@\x8b\xf2\xb4\xb6\x0e\x92\xacz\xd2c\xd4\x8f\x89\xdd\x0e\x8c\x1a\xb6\xe4\xc5\x93O@\x8c\xf2\xb7\x94!j\xec:JD\x98\xf5\x7f\x8a\x0f\xda\x94\x9eB\xc1\x1d\x07'_@\x90\xf2\xb1\x0fRKRVO\xaa\xca\xb1\xebI\x8fR?\x85\xa8\xe8\xa8\xd2\xcb\x00\x00\xd7\x00\x01\x00\x00\x00\x01{\n \x22args\x22: {},\n \x22headers\x22: {\n \x22Accept\x22: \x22*/*\x22,\n \x22Host\x22: \x22nghttp2.org\x22,\n \x22User-Agent\x22: \x22curl/7.60.0-DEV\x22,\n \x22Via\x22: \x222 nghttpx\x22\n },\n \x22origin\x22: \x22127.0.10.10\x22,\n \x22url\x22: \x22http://nghttp2.org/httpbin/get\x22\n}\n" + } + on_readable { + payload: "\x00\x00\x18\x04\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00d\x00\x04\x00\x10\x00\x00\x00\x08\x00\x00\x00\x01\x00\x01\x00\x00 \x00" + } +} diff --git a/scenarios/curl_fuzzer_http/test_cookie_control_code_hackerone_1613943.textproto b/scenarios/curl_fuzzer_http/test_cookie_control_code_hackerone_1613943.textproto new file mode 100644 index 000000000..4e54ac36b --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_cookie_control_code_hackerone_1613943.textproto @@ -0,0 +1,37 @@ +# source: corpora/curl_fuzzer_http/test_cookie_control_code_hackerone_1613943 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://example.com:8080/chat?a=b&c=d" + } +} +actions { + add_header { + value { + text: "Host: server.example.com" + } + } +} +actions { + add_header { + value { + text: "Connection: Close" + } + } +} +actions { + add_header { + value { + text: "Origin: http://example.com" + } + } +} +actions { + add_header { + value { + text: "Cookie: a=b\\f" + } + } +} diff --git a/scenarios/curl_fuzzer_http/test_http_upgrade_to_ws.textproto b/scenarios/curl_fuzzer_http/test_http_upgrade_to_ws.textproto new file mode 100644 index 000000000..2caf64e0e --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_http_upgrade_to_ws.textproto @@ -0,0 +1,64 @@ +# source: corpora/curl_fuzzer_http/test_http_upgrade_to_ws + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://example.com:8080/chat?a=b&c=d" + } +} +actions { + add_header { + value { + text: "Host: server.example.com" + } + } +} +actions { + add_header { + value { + text: "Upgrade: websocket" + } + } +} +actions { + add_header { + value { + text: "Connection: Close" + } + } +} +actions { + add_header { + value { + text: "Sec-WebSocket-Key: Aa01AAaAA1AaAa1900aAAa==" + } + } +} +actions { + add_header { + value { + text: "Sec-WebSocket-Protocol: chat, superchat" + } + } +} +actions { + add_header { + value { + text: "Sec-WebSocket-Version: 13" + } + } +} +actions { + add_header { + value { + text: "Origin: http://localhost.localdomain:80" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 101 SwitchingProtocols\r\nUpgrade:websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: AAAAAAAAAA0000000aaaaaaaaaa=\r\nSec-WebSocket-Protocol: chat\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test_http_upgrade_to_ws_and_detach.textproto b/scenarios/curl_fuzzer_http/test_http_upgrade_to_ws_and_detach.textproto new file mode 100644 index 000000000..dd454c638 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_http_upgrade_to_ws_and_detach.textproto @@ -0,0 +1,78 @@ +# source: corpora/curl_fuzzer_http/test_http_upgrade_to_ws_and_detach + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://example.com:8080/chat?a=b&c=d" + } +} +actions { + set_option { + option_id: CURLOPT_WS_OPTIONS + scope: OPTION_SCOPE_DEFAULT + uint32_value: 2 + } +} +actions { + set_option { + option_id: CURLOPT_POST + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} +actions { + add_header { + value { + text: "Host: server.example.com" + } + } +} +actions { + add_header { + value { + text: "Upgrade: websocket" + } + } +} +actions { + add_header { + value { + text: "Connection: Close" + } + } +} +actions { + add_header { + value { + text: "Sec-WebSocket-Key: Aa01AAaAA1AaAa1900aAAa==" + } + } +} +actions { + add_header { + value { + text: "Sec-WebSocket-Protocol: chat, superchat" + } + } +} +actions { + add_header { + value { + text: "Sec-WebSocket-Version: 13" + } + } +} +actions { + add_header { + value { + text: "Origin: http://localhost.localdomain:80" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 101 SwitchingProtocols\r\nUpgrade:websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: AAAAAAAAAA0000000aaaaaaaaaa=\r\nSec-WebSocket-Protocol: chat\r\nSet-Cookie: aaaaaaaaaaaa=bbbbbbbbbbbbbb; Domain=.example.com; Path=/\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test_http_with_hsts.textproto b/scenarios/curl_fuzzer_http/test_http_with_hsts.textproto new file mode 100644 index 000000000..a3b5b6be5 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_http_with_hsts.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_http/test_http_with_hsts + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://2130706433:8080/chat" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 307 Temporary Redirect\r\nStrict-Transport-Security: max-age=9001; includeSubDomains\r\nLocation: https://2130706433:8443/chat\r\nHost: http://2130706433:8080\r\nContent-Length: 0\r\nContent-Type: text/json\r\n\r\n{ isthisjson: kinda }" + } +} diff --git a/scenarios/curl_fuzzer_http/test_http_with_hsts_tlv.textproto b/scenarios/curl_fuzzer_http/test_http_with_hsts_tlv.textproto new file mode 100644 index 000000000..fb4c02a77 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_http_with_hsts_tlv.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer_http/test_http_with_hsts_tlv + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://google.com" + } +} +actions { + set_option { + option_id: CURLOPT_LOGIN_OPTIONS + scope: OPTION_SCOPE_DEFAULT + string_value: "/tmp/hsts.foobar" + } +} +actions { + set_option { + option_id: CURLOPT_XOAUTH2_BEARER + scope: OPTION_SCOPE_DEFAULT + bytes_value: "\000\000\000\003" + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\r\nServer: foo\r\nContent-Type: text/plain\r\nStrict-Transport-Security: max-age=63072000; includeSubDomains;\r\nContent-Length: 4\r\n\r\nbody" + } +} diff --git a/scenarios/curl_fuzzer_http/test_invalid_prior_http2.textproto b/scenarios/curl_fuzzer_http/test_invalid_prior_http2.textproto new file mode 100644 index 000000000..3ab3458cb --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_invalid_prior_http2.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_http/test_invalid_prior_http2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1" + } +} +actions { + set_option { + option_id: CURLOPT_HTTP_VERSION + scope: OPTION_SCOPE_DEFAULT + uint32_value: 5 + } +} +connections { + id: 0 + initial_response { + payload: "this is not valid" + } +} diff --git a/scenarios/curl_fuzzer_http/test_ipv6.textproto b/scenarios/curl_fuzzer_http/test_ipv6.textproto new file mode 100644 index 000000000..9c7c3c624 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_ipv6.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_http/test_ipv6 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://[::ffff:c0a8:101]/file.txt" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "pass" + } +} +actions { + add_header { + value { + text: "Accept-Encoding: identity" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\t\r\nConnection: Close\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_http/test_ntlm.textproto b/scenarios/curl_fuzzer_http/test_ntlm.textproto new file mode 100644 index 000000000..9f7712801 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_ntlm.textproto @@ -0,0 +1,58 @@ +# source: corpora/curl_fuzzer_http/test_ntlm + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://localhost.localdomain:86/DynamicsNAV80/WS/nasr/Page/Delivery/Incident" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "DOMAIN\\user:" + } +} +actions { + set_option { + option_id: CURLOPT_NETRC + scope: OPTION_SCOPE_DEFAULT + uint32_value: 2 + } +} +actions { + set_option { + option_id: CURLOPT_HTTPAUTH + scope: OPTION_SCOPE_DEFAULT + uint32_value: 8 + } +} +actions { + register_upload { + payload: "TEST" + kind: TRANSFER_KIND_UPLOAD + size_hint: 394 + } +} +actions { + add_header { + value { + text: "Content-Type: text/xml; charset=utf-8" + } + } +} +actions { + add_header { + value { + text: "Origin: http://127.0.0.1:9999" + } + } +} +actions { + add_header { + value { + text: "SOAPAction: http://localhost.localdomain/IncidentMgmtWFWS/StartIncidentByWS" + } + } +} diff --git a/scenarios/curl_fuzzer_http/test_ntlm_wb.textproto b/scenarios/curl_fuzzer_http/test_ntlm_wb.textproto new file mode 100644 index 000000000..db00a78c9 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_ntlm_wb.textproto @@ -0,0 +1,65 @@ +# source: corpora/curl_fuzzer_http/test_ntlm_wb + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://localhost.localdomain:86/DynamicsNAV80/WS/nasr/Page/Delivery/Incident" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "DOMAIN\\user:" + } +} +actions { + set_option { + option_id: CURLOPT_HTTP_VERSION + scope: OPTION_SCOPE_DEFAULT + uint32_value: 2 + } +} +actions { + set_option { + option_id: CURLOPT_NETRC + scope: OPTION_SCOPE_DEFAULT + uint32_value: 2 + } +} +actions { + set_option { + option_id: CURLOPT_HTTPAUTH + scope: OPTION_SCOPE_DEFAULT + uint32_value: 32 + } +} +actions { + register_upload { + payload: "TEST" + kind: TRANSFER_KIND_UPLOAD + size_hint: 394 + } +} +actions { + add_header { + value { + text: "Content-Type: text/xml; charset=utf-8" + } + } +} +actions { + add_header { + value { + text: "Origin: http://127.0.0.1:9999" + } + } +} +actions { + add_header { + value { + text: "SOAPAction: http://localhost.localdomain/IncidentMgmtWFWS/StartIncidentByWS" + } + } +} diff --git a/scenarios/curl_fuzzer_http/test_url_http.textproto b/scenarios/curl_fuzzer_http/test_url_http.textproto new file mode 100644 index 000000000..b92e282ea --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_url_http.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_http/test_url_http + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "http://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_http/test_wrongproto.textproto b/scenarios/curl_fuzzer_http/test_wrongproto.textproto new file mode 100644 index 000000000..9adee5545 --- /dev/null +++ b/scenarios/curl_fuzzer_http/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_http/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_https/test_alt_svc_with_double_header.textproto b/scenarios/curl_fuzzer_https/test_alt_svc_with_double_header.textproto new file mode 100644 index 000000000..e59f04afd --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_alt_svc_with_double_header.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_https/test_alt_svc_with_double_header + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://www2.server.example.com" + } +} +actions { + add_header { + value { + text: "Origin: https://example.com/a/b/path/to/thing/foo" + } + } +} +actions { + add_header { + value { + text: "X-Foo-3: ba\tr" + } + } +} +actions { + add_header { + value { + text: "Cookie: __m=-1" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\r\nHost: server.example.com\r\nAlt-Svc: h3-23=\x22something.example.com:9999\x22\r\nAlt-Svc: h2=\x22alt.example.com:443\x22, h2=\x22:443\x22\r\nConnection: Keep-Alive\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_https/test_alt_svc_with_ma.textproto b/scenarios/curl_fuzzer_https/test_alt_svc_with_ma.textproto new file mode 100644 index 000000000..4ac2f01bf --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_alt_svc_with_ma.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_https/test_alt_svc_with_ma + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://server.example.com" + } +} +actions { + add_header { + value { + text: "Origin: https://example.com/a/b/path/to/thing/foo" + } + } +} +actions { + add_header { + value { + text: "X-Foo-3: ba\tr" + } + } +} +actions { + add_header { + value { + text: "Cookie: __m=-1" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\r\nHost: server.example.com\r\nAlt-Svc: h2=\x22alt.example.com:443\x22, h2=\x22:443\x22\r\nConnection: Keep-Alive\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_https/test_altsvc_with_cache.textproto b/scenarios/curl_fuzzer_https/test_altsvc_with_cache.textproto new file mode 100644 index 000000000..0572d2b2a --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_altsvc_with_cache.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_https/test_altsvc_with_cache + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://0x7F000001?foobar.json" + } +} +actions { + add_header { + value { + text: "Alt-Svc: h3-25=\":4430\"; ma=0" + } + } +} +actions { + add_header { + value { + text: "Connection: Keep-Alive" + } + } +} +actions { + add_header { + value { + text: "Authorization: Basic aaaaaaaaaaaaaaaaaaa" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTPS/2 200 OK" + } +} diff --git a/scenarios/curl_fuzzer_https/test_hsts_response.textproto b/scenarios/curl_fuzzer_https/test_hsts_response.textproto new file mode 100644 index 000000000..34f6363d2 --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_hsts_response.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_https/test_hsts_response + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://0x7F000001?foobar.json" + } +} +connections { + id: 0 + initial_response { + payload: "HTTPS/2 302 Found\r\nConnection: Keep-Alive\r\nLocation: https://foo.co.uk:9999/bar?type=foobar.json\r\nStrict-Transport-Security: max-age 3600; includeSubdomains; persist" + } +} diff --git a/scenarios/curl_fuzzer_https/test_hsts_response_to_ipv6.textproto b/scenarios/curl_fuzzer_https/test_hsts_response_to_ipv6.textproto new file mode 100644 index 000000000..7bdaa8208 --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_hsts_response_to_ipv6.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_https/test_hsts_response_to_ipv6 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://[2001:db8:122:344:c0:2:2100::]:9090/filethings.json?oops=a¶m=tru" + } +} +connections { + id: 0 + initial_response { + payload: "HTTPS/2 200 OK\r\nConnection: Close\r\nStrict-Transport-Security: max-age 60\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_https/test_http_version_2.textproto b/scenarios/curl_fuzzer_https/test_http_version_2.textproto new file mode 100644 index 000000000..d5a6e2166 --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_http_version_2.textproto @@ -0,0 +1,43 @@ +# source: corpora/curl_fuzzer_https/test_http_version_2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://localhost.localdomain?foobar.json" + } +} +actions { + set_option { + option_id: CURLOPT_USERAGENT + scope: OPTION_SCOPE_DEFAULT + string_value: "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1" + } +} +actions { + set_option { + option_id: CURLOPT_HTTP_VERSION + scope: OPTION_SCOPE_DEFAULT + uint32_value: 2 + } +} +actions { + add_header { + value { + text: "Authorization: Basic aaaaaaaaaaaaaaaaaaa" + } + } +} +actions { + add_header { + value { + text: "Connection: Keep-Alive" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/2 403 Forbidden\r\nConnection: close\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_https/test_https_ntlm.textproto b/scenarios/curl_fuzzer_https/test_https_ntlm.textproto new file mode 100644 index 000000000..c02642c3c --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_https_ntlm.textproto @@ -0,0 +1,30 @@ +# source: corpora/curl_fuzzer_https/test_https_ntlm + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://whattheheckisntlm.example.com/Endpoint.wsdl" + } +} +actions { + set_option { + option_id: CURLOPT_HTTPAUTH + scope: OPTION_SCOPE_DEFAULT + uint32_value: 8 + } +} +actions { + add_header { + value { + text: "Connection: Keep-Alive" + } + } +} +actions { + add_header { + value { + text: "Content-Type: application/json" + } + } +} diff --git a/scenarios/curl_fuzzer_https/test_ipv6.textproto b/scenarios/curl_fuzzer_https/test_ipv6.textproto new file mode 100644 index 000000000..e75e26c11 --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_ipv6.textproto @@ -0,0 +1,30 @@ +# source: corpora/curl_fuzzer_https/test_ipv6 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://[::ffff:c0a8:101]/file.txt" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "pass" + } +} +actions { + add_header { + value { + text: "Accept-Encoding: identity" + } + } +} diff --git a/scenarios/curl_fuzzer_https/test_post_0byte.textproto b/scenarios/curl_fuzzer_https/test_post_0byte.textproto new file mode 100644 index 000000000..157659a3f --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_post_0byte.textproto @@ -0,0 +1,67 @@ +# source: corpora/curl_fuzzer_https/test_post_0byte + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://0xff.localdomain/upload" + } +} +actions { + set_option { + option_id: CURLOPT_NOBODY + scope: OPTION_SCOPE_DEFAULT + uint32_value: 0 + } +} +actions { + set_option { + option_id: CURLOPT_CONNECT_ONLY + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} +actions { + add_header { + value { + text: "Content-Length: 0" + } + } +} +actions { + add_header { + value { + text: "Transfer-Encoding: gzip,chunked" + } + } +} +actions { + add_header { + value { + text: "Content-Encoding: gzip" + } + } +} +actions { + add_header { + value { + text: "Content-Type: application/gzip" + } + } +} +actions { + add_header { + value { + text: "Expect: 100-continue" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 100 Continue\r\n\r\n" + } + on_readable { + payload: "HTTP/1.1 415 Unsupported Media Type\r\nConnection: Close\r\nContent-Type: */*\r\nContent-Length: 289\r\nX-Frame-Options: SAMEORIGIN\r\n" + } +} diff --git a/scenarios/curl_fuzzer_https/test_simple_httppost.textproto b/scenarios/curl_fuzzer_https/test_simple_httppost.textproto new file mode 100644 index 000000000..30aa47fa4 --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_simple_httppost.textproto @@ -0,0 +1,44 @@ +# source: corpora/curl_fuzzer_https/test_simple_httppost + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://[::1]/upload/a/thing/here" + } +} +actions { + configure_http_post { + fields { + name: "test" + inline_data: "{ a: b, bar: -1, 3: 2L }" + } + } +} +actions { + set_option { + option_id: CURLOPT_NOBODY + scope: OPTION_SCOPE_DEFAULT + uint32_value: 0 + } +} +actions { + add_header { + value { + text: "Content-Type: text/json" + } + } +} +actions { + add_header { + value { + text: "Connection: Close" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 200 OK\n\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_https/test_url.textproto b/scenarios/curl_fuzzer_https/test_url.textproto new file mode 100644 index 000000000..e6dfc7843 --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_url.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_https/test_url + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "https://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_https/test_wrongproto.textproto b/scenarios/curl_fuzzer_https/test_wrongproto.textproto new file mode 100644 index 000000000..e57854a6c --- /dev/null +++ b/scenarios/curl_fuzzer_https/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_https/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/corpora/curl_fuzzer_imap/clusterfuzz-testcase-minimized-5817192030404608 b/scenarios/curl_fuzzer_imap/clusterfuzz-testcase-minimized-5817192030404608.textproto similarity index 70% rename from corpora/curl_fuzzer_imap/clusterfuzz-testcase-minimized-5817192030404608 rename to scenarios/curl_fuzzer_imap/clusterfuzz-testcase-minimized-5817192030404608.textproto index 7bb66d740..1bfa1c458 100644 Binary files a/corpora/curl_fuzzer_imap/clusterfuzz-testcase-minimized-5817192030404608 and b/scenarios/curl_fuzzer_imap/clusterfuzz-testcase-minimized-5817192030404608.textproto differ diff --git a/scenarios/curl_fuzzer_imap/test800.textproto b/scenarios/curl_fuzzer_imap/test800.textproto new file mode 100644 index 000000000..9be4a4f70 --- /dev/null +++ b/scenarios/curl_fuzzer_imap/test800.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer_imap/test800 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "imap://127.0.0.1:9003/800/;UID=1" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "secret" + } +} +connections { + id: 0 + initial_response { + payload: "From: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n yours sincerely\r\n" + } +} diff --git a/scenarios/curl_fuzzer_imap/test800_2.textproto b/scenarios/curl_fuzzer_imap/test800_2.textproto new file mode 100644 index 000000000..e0fb33aec --- /dev/null +++ b/scenarios/curl_fuzzer_imap/test800_2.textproto @@ -0,0 +1,24 @@ +# source: corpora/curl_fuzzer_imap/test800_2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "imap://127.0.0.1:9003/800/;UID=1" + } +} +connections { + id: 0 + initial_response { + payload: "* OK IMAP4rev1 Service Ready\n" + } + on_readable { + payload: "A001 IMAP4\n" + } + on_readable { + payload: "* 800 EXISTS\nA002 OK [READ-WRITE] SELECT completed\n" + } + on_readable { + payload: "* 1 FETCH (BODY[TEXT] {69}\r\nFrom: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n yours sincerely\r\n)\r\nA003 OK FETCH completed\r\n" + } +} diff --git a/scenarios/curl_fuzzer_imap/test_oauthed_imap.textproto b/scenarios/curl_fuzzer_imap/test_oauthed_imap.textproto new file mode 100644 index 000000000..d9babe45b --- /dev/null +++ b/scenarios/curl_fuzzer_imap/test_oauthed_imap.textproto @@ -0,0 +1,52 @@ +# source: corpora/curl_fuzzer_imap/test_oauthed_imap + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "imap://localhost.localdomain:9999/wow/a/path/1/;MAILINDEX=1" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "sekrit" + } +} +actions { + set_option { + option_id: CURLOPT_LOGIN_OPTIONS + scope: OPTION_SCOPE_DEFAULT + string_value: "AUTH=OAUTHBEARER" + } +} +actions { + set_option { + option_id: CURLOPT_XOAUTH2_BEARER + scope: OPTION_SCOPE_DEFAULT + string_value: "aaaaaaaaaaaaa\tAAAAAAAAAAAAAAAAAAAAA==" + } +} +connections { + id: 0 + initial_response { + payload: "* OK IMAP4rev1 Service Ready" + } + on_readable { + payload: "* OK IMAP4rev1 Service Ready" + } + on_readable { + payload: "* 800 EXISTS\nA002 OK [READ-WRITE] SELECT completed\n" + } + on_readable { + payload: "* 1 FETCH (BODY[TEXT] {69}\r\nFrom: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\n yours sincerely\nA003 OK FETCH completed\r\n" + } +} diff --git a/scenarios/curl_fuzzer_imap/test_url_imap.textproto b/scenarios/curl_fuzzer_imap/test_url_imap.textproto new file mode 100644 index 000000000..5b45d5608 --- /dev/null +++ b/scenarios/curl_fuzzer_imap/test_url_imap.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_imap/test_url_imap + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "imap://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_imap/test_wrongproto.textproto b/scenarios/curl_fuzzer_imap/test_wrongproto.textproto new file mode 100644 index 000000000..b5f51f87c --- /dev/null +++ b/scenarios/curl_fuzzer_imap/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_imap/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_ldap/test_url_fullldap.textproto b/scenarios/curl_fuzzer_ldap/test_url_fullldap.textproto new file mode 100644 index 000000000..b77a8cdf5 --- /dev/null +++ b/scenarios/curl_fuzzer_ldap/test_url_fullldap.textproto @@ -0,0 +1,32 @@ +# source: corpora/curl_fuzzer_ldap/test_url_fullldap + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ldap://localhost:1389/dc=example,dc=com?homephone?sub?cn=*cm2*" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "cn=dirman" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "123456" + } +} +connections { + id: 0 + on_readable { + payload: "123456" + } + on_readable { + payload: "123456" + } +} diff --git a/scenarios/curl_fuzzer_ldap/test_url_ldap.textproto b/scenarios/curl_fuzzer_ldap/test_url_ldap.textproto new file mode 100644 index 000000000..7026ec7b8 --- /dev/null +++ b/scenarios/curl_fuzzer_ldap/test_url_ldap.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_ldap/test_url_ldap + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ldap://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_ldap/test_wrongproto.textproto b/scenarios/curl_fuzzer_ldap/test_wrongproto.textproto new file mode 100644 index 000000000..2972b2f1b --- /dev/null +++ b/scenarios/curl_fuzzer_ldap/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_ldap/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_mqtt/test_dummy.textproto b/scenarios/curl_fuzzer_mqtt/test_dummy.textproto new file mode 100644 index 000000000..e5ff2b775 --- /dev/null +++ b/scenarios/curl_fuzzer_mqtt/test_dummy.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_mqtt/test_dummy + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "mqtt://127.0.0.1/test" + } +} +connections { + id: 0 + initial_response { + payload: "hello" + } +} diff --git a/scenarios/curl_fuzzer_pop3/test850.textproto b/scenarios/curl_fuzzer_pop3/test850.textproto new file mode 100644 index 000000000..464e0c518 --- /dev/null +++ b/scenarios/curl_fuzzer_pop3/test850.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer_pop3/test850 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "pop3://127.0.0.1:9001/850" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_PASSWORD + scope: OPTION_SCOPE_DEFAULT + string_value: "secret" + } +} +connections { + id: 0 + initial_response { + payload: "From: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n yours sincerely\r\n" + } +} diff --git a/scenarios/curl_fuzzer_pop3/test_oauthed_pop3.textproto b/scenarios/curl_fuzzer_pop3/test_oauthed_pop3.textproto new file mode 100644 index 000000000..c602bb5c5 --- /dev/null +++ b/scenarios/curl_fuzzer_pop3/test_oauthed_pop3.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_pop3/test_oauthed_pop3 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "pop3s://localhost.localdomain:9991/wow/a/path/1/;MAILINDEX=1" + } +} +actions { + set_option { + option_id: CURLOPT_USERNAME + scope: OPTION_SCOPE_DEFAULT + string_value: "user" + } +} +actions { + set_option { + option_id: CURLOPT_LOGIN_OPTIONS + scope: OPTION_SCOPE_DEFAULT + string_value: "AUTH=OAUTHBEARER" + } +} +actions { + set_option { + option_id: CURLOPT_XOAUTH2_BEARER + scope: OPTION_SCOPE_DEFAULT + string_value: "a\tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1==" + } +} +connections { + id: 0 + initial_response { + payload: "From: me@somewhere\r\nTo: fake@nowhere\r\n\r\nbody\r\n\r\n--\r\n\tyours sincerely\r\n" + } +} diff --git a/scenarios/curl_fuzzer_pop3/test_url_pop3.textproto b/scenarios/curl_fuzzer_pop3/test_url_pop3.textproto new file mode 100644 index 000000000..e81ce6fd3 --- /dev/null +++ b/scenarios/curl_fuzzer_pop3/test_url_pop3.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_pop3/test_url_pop3 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "pop3://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_pop3/test_wrongproto.textproto b/scenarios/curl_fuzzer_pop3/test_wrongproto.textproto new file mode 100644 index 000000000..72dafabfa --- /dev/null +++ b/scenarios/curl_fuzzer_pop3/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_pop3/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_rtmp/test_url_rtmp.textproto b/scenarios/curl_fuzzer_rtmp/test_url_rtmp.textproto new file mode 100644 index 000000000..d4887c699 --- /dev/null +++ b/scenarios/curl_fuzzer_rtmp/test_url_rtmp.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_rtmp/test_url_rtmp + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtmp://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_rtmp/test_wrongproto.textproto b/scenarios/curl_fuzzer_rtmp/test_wrongproto.textproto new file mode 100644 index 000000000..df7af2d7b --- /dev/null +++ b/scenarios/curl_fuzzer_rtmp/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_rtmp/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_rtsp/test567.textproto b/scenarios/curl_fuzzer_rtsp/test567.textproto new file mode 100644 index 000000000..08efaec7d --- /dev/null +++ b/scenarios/curl_fuzzer_rtsp/test567.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_rtsp/test567 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1:1234/567" + } +} +connections { + id: 0 + on_readable { + payload: "RTSP/1.0 200 OK\r\nServer: RTSPD/libcurl-test\r\nCSeq: 1\r\nPublic: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE\r\nCurl-Private: swsclose\r\n" + } +} diff --git a/scenarios/curl_fuzzer_rtsp/test_rtsp_client_cseq.textproto b/scenarios/curl_fuzzer_rtsp/test_rtsp_client_cseq.textproto new file mode 100644 index 000000000..a2b5b81e7 --- /dev/null +++ b/scenarios/curl_fuzzer_rtsp/test_rtsp_client_cseq.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_rtsp/test_rtsp_client_cseq + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1:1234/567" + } +} +actions { + set_option { + option_id: CURLOPT_RTSP_CLIENT_CSEQ + scope: OPTION_SCOPE_DEFAULT + uint32_value: 4294967295 + } +} +connections { + id: 0 + on_readable { + payload: "RTSP/1.0 200 OK\r\nServer: RTSPD/libcurl-test\r\nCSeq: 4294967295\r\nPublic: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE\r\nCurl-Private: swsclose\r\n" + } +} diff --git a/scenarios/curl_fuzzer_rtsp/test_rtsp_request.textproto b/scenarios/curl_fuzzer_rtsp/test_rtsp_request.textproto new file mode 100644 index 000000000..bf8fbe87c --- /dev/null +++ b/scenarios/curl_fuzzer_rtsp/test_rtsp_request.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_rtsp/test_rtsp_request + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1:1234/567" + } +} +actions { + set_option { + option_id: CURLOPT_RTSP_REQUEST + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} +connections { + id: 0 + on_readable { + payload: "RTSP/1.0 200 OK\r\nServer: RTSPD/libcurl-test\r\nCSeq: 1\r\nPublic: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE\r\nCurl-Private: swsclose\r\n" + } +} diff --git a/scenarios/curl_fuzzer_rtsp/test_rtsp_request2.textproto b/scenarios/curl_fuzzer_rtsp/test_rtsp_request2.textproto new file mode 100644 index 000000000..3bf398f06 --- /dev/null +++ b/scenarios/curl_fuzzer_rtsp/test_rtsp_request2.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_rtsp/test_rtsp_request2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1:1234/567" + } +} +actions { + set_option { + option_id: CURLOPT_RTSP_REQUEST + scope: OPTION_SCOPE_DEFAULT + uint32_value: 2 + } +} +connections { + id: 0 + on_readable { + payload: "RTSP/1.0 200 OK\r\nServer: RTSPD/libcurl-test\r\nCSeq: 1\r\nPublic: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE\r\nCurl-Private: swsclose\r\n" + } +} diff --git a/scenarios/curl_fuzzer_rtsp/test_rtsp_session_id.textproto b/scenarios/curl_fuzzer_rtsp/test_rtsp_session_id.textproto new file mode 100644 index 000000000..d38791918 --- /dev/null +++ b/scenarios/curl_fuzzer_rtsp/test_rtsp_session_id.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer_rtsp/test_rtsp_session_id + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1:1234/567" + } +} +actions { + set_option { + option_id: CURLOPT_RTSP_SESSION_ID + scope: OPTION_SCOPE_DEFAULT + string_value: "12345" + } +} +actions { + set_option { + option_id: CURLOPT_RTSP_REQUEST + scope: OPTION_SCOPE_DEFAULT + uint32_value: 3 + } +} +connections { + id: 0 + on_readable { + payload: "RTSP/1.0 200 OK\r\nServer: RTSPD/libcurl-test\r\nCSeq: 1\r\nPublic: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE\r\nCurl-Private: swsclose\r\n" + } +} diff --git a/scenarios/curl_fuzzer_rtsp/test_rtsp_stream_uri.textproto b/scenarios/curl_fuzzer_rtsp/test_rtsp_stream_uri.textproto new file mode 100644 index 000000000..48370b043 --- /dev/null +++ b/scenarios/curl_fuzzer_rtsp/test_rtsp_stream_uri.textproto @@ -0,0 +1,22 @@ +# source: corpora/curl_fuzzer_rtsp/test_rtsp_stream_uri + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1:1234/567" + } +} +actions { + set_option { + option_id: CURLOPT_RTSP_STREAM_URI + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1/twister/video" + } +} +connections { + id: 0 + on_readable { + payload: "RTSP/1.0 200 OK\r\nServer: RTSPD/libcurl-test\r\nCSeq: 1\r\nPublic: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE\r\nCurl-Private: swsclose\r\n" + } +} diff --git a/scenarios/curl_fuzzer_rtsp/test_rtsp_transport.textproto b/scenarios/curl_fuzzer_rtsp/test_rtsp_transport.textproto new file mode 100644 index 000000000..ac09f2d74 --- /dev/null +++ b/scenarios/curl_fuzzer_rtsp/test_rtsp_transport.textproto @@ -0,0 +1,29 @@ +# source: corpora/curl_fuzzer_rtsp/test_rtsp_transport + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1:1234/567" + } +} +actions { + set_option { + option_id: CURLOPT_RTSP_TRANSPORT + scope: OPTION_SCOPE_DEFAULT + string_value: "RTP/AVP;unicast;client_port=4588-4589" + } +} +actions { + set_option { + option_id: CURLOPT_RTSP_REQUEST + scope: OPTION_SCOPE_DEFAULT + uint32_value: 4 + } +} +connections { + id: 0 + on_readable { + payload: "RTSP/1.0 200 OK\r\nServer: RTSPD/libcurl-test\r\nCSeq: 1\r\nPublic: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE\r\nCurl-Private: swsclose\r\n" + } +} diff --git a/scenarios/curl_fuzzer_rtsp/test_url_rtsp.textproto b/scenarios/curl_fuzzer_rtsp/test_url_rtsp.textproto new file mode 100644 index 000000000..702bda9f2 --- /dev/null +++ b/scenarios/curl_fuzzer_rtsp/test_url_rtsp.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_rtsp/test_url_rtsp + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "rtsp://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_rtsp/test_wrongproto.textproto b/scenarios/curl_fuzzer_rtsp/test_wrongproto.textproto new file mode 100644 index 000000000..7476513a7 --- /dev/null +++ b/scenarios/curl_fuzzer_rtsp/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_rtsp/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_scp/test_url_scp.textproto b/scenarios/curl_fuzzer_scp/test_url_scp.textproto new file mode 100644 index 000000000..103d05e0d --- /dev/null +++ b/scenarios/curl_fuzzer_scp/test_url_scp.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_scp/test_url_scp + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "scp://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_scp/test_wrongproto.textproto b/scenarios/curl_fuzzer_scp/test_wrongproto.textproto new file mode 100644 index 000000000..fe86f8b6d --- /dev/null +++ b/scenarios/curl_fuzzer_scp/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_scp/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_sftp/test_url_sftp.textproto b/scenarios/curl_fuzzer_sftp/test_url_sftp.textproto new file mode 100644 index 000000000..0a0a11857 --- /dev/null +++ b/scenarios/curl_fuzzer_sftp/test_url_sftp.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_sftp/test_url_sftp + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "sftp://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_sftp/test_wrongproto.textproto b/scenarios/curl_fuzzer_sftp/test_wrongproto.textproto new file mode 100644 index 000000000..62806fd75 --- /dev/null +++ b/scenarios/curl_fuzzer_sftp/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_sftp/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_smb/test_url_smb.textproto b/scenarios/curl_fuzzer_smb/test_url_smb.textproto new file mode 100644 index 000000000..fa223f884 --- /dev/null +++ b/scenarios/curl_fuzzer_smb/test_url_smb.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_smb/test_url_smb + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smb://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_smb/test_wrongproto.textproto b/scenarios/curl_fuzzer_smb/test_wrongproto.textproto new file mode 100644 index 000000000..af9517446 --- /dev/null +++ b/scenarios/curl_fuzzer_smb/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_smb/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_smtp/test900.textproto b/scenarios/curl_fuzzer_smtp/test900.textproto new file mode 100644 index 000000000..78fa5ae04 --- /dev/null +++ b/scenarios/curl_fuzzer_smtp/test900.textproto @@ -0,0 +1,36 @@ +# source: corpora/curl_fuzzer_smtp/test900 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smtp://127.0.0.1:9005/900" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_FROM + scope: OPTION_SCOPE_DEFAULT + string_value: "sender@example.com" + } +} +actions { + register_upload { + payload: "From: different\nTo: another\n\nbody\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 34 + } +} +actions { + add_mail_recipient { + value { + text: "recipient@example.com" + } + } +} +connections { + id: 0 + initial_response { + payload: " " + } +} diff --git a/scenarios/curl_fuzzer_smtp/test900_2.textproto b/scenarios/curl_fuzzer_smtp/test900_2.textproto new file mode 100644 index 000000000..f4bad4528 --- /dev/null +++ b/scenarios/curl_fuzzer_smtp/test900_2.textproto @@ -0,0 +1,51 @@ +# source: corpora/curl_fuzzer_smtp/test900_2 + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smtp://127.0.0.1:9005/900" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_FROM + scope: OPTION_SCOPE_DEFAULT + string_value: "sender@example.com" + } +} +actions { + register_upload { + payload: "From: different\nTo: another\n\nbody\n.\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 36 + } +} +actions { + add_mail_recipient { + value { + text: "recipient@example.com" + } + } +} +connections { + id: 0 + initial_response { + payload: "220 smtp.example.com ESMTP Postfix\n" + } + on_readable { + payload: "250 SIZE 14680064\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "354 Ok\n" + } + on_readable { + payload: "250 Ok\n" + } +} diff --git a/scenarios/curl_fuzzer_smtp/test_mail_auth.textproto b/scenarios/curl_fuzzer_smtp/test_mail_auth.textproto new file mode 100644 index 000000000..f2ce67edb --- /dev/null +++ b/scenarios/curl_fuzzer_smtp/test_mail_auth.textproto @@ -0,0 +1,58 @@ +# source: corpora/curl_fuzzer_smtp/test_mail_auth + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smtp://127.0.0.1:9005/900" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_FROM + scope: OPTION_SCOPE_DEFAULT + string_value: "sender@example.com" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_AUTH + scope: OPTION_SCOPE_DEFAULT + string_value: "whatever@secret" + } +} +actions { + register_upload { + payload: "From: different\nTo: another\n\nbody\n\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 35 + } +} +actions { + add_mail_recipient { + value { + text: "recipient@example.com" + } + } +} +connections { + id: 0 + initial_response { + payload: "220 smtp.example.com ESMTP Postfix\n" + } + on_readable { + payload: "250 SIZE 14680064\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "354 Ok\n" + } + on_readable { + payload: "250 Ok" + } +} diff --git a/scenarios/curl_fuzzer_smtp/test_smtps_with_oauth.textproto b/scenarios/curl_fuzzer_smtp/test_smtps_with_oauth.textproto new file mode 100644 index 000000000..3a7315384 --- /dev/null +++ b/scenarios/curl_fuzzer_smtp/test_smtps_with_oauth.textproto @@ -0,0 +1,65 @@ +# source: corpora/curl_fuzzer_smtp/test_smtps_with_oauth + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smtps://localhost.localdomain:9005" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_FROM + scope: OPTION_SCOPE_DEFAULT + string_value: "sender@example.is" + } +} +actions { + set_option { + option_id: CURLOPT_MAIL_AUTH + scope: OPTION_SCOPE_DEFAULT + string_value: "foo@secret" + } +} +actions { + set_option { + option_id: CURLOPT_LOGIN_OPTIONS + scope: OPTION_SCOPE_DEFAULT + string_value: "AUTH=OAUTHBEARER" + } +} +actions { + set_option { + option_id: CURLOPT_XOAUTH2_BEARER + scope: OPTION_SCOPE_DEFAULT + string_value: "abearertokenvalue!" + } +} +actions { + register_upload { + payload: "From: different\nTo: another\n\nbody\n\n" + kind: TRANSFER_KIND_UPLOAD + size_hint: 35 + } +} +connections { + id: 0 + initial_response { + payload: "220 smtp.example.com ESMTP Postfix\n" + } + on_readable { + payload: "250 SIZE 14680064\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "250 Ok\n" + } + on_readable { + payload: "354 Ok\n" + } + on_readable { + payload: "250 Ok\n" + } +} diff --git a/scenarios/curl_fuzzer_smtp/test_url_smtp.textproto b/scenarios/curl_fuzzer_smtp/test_url_smtp.textproto new file mode 100644 index 000000000..6bb353a0f --- /dev/null +++ b/scenarios/curl_fuzzer_smtp/test_url_smtp.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_smtp/test_url_smtp + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "smtp://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_smtp/test_wrongproto.textproto b/scenarios/curl_fuzzer_smtp/test_wrongproto.textproto new file mode 100644 index 000000000..d3af75dfd --- /dev/null +++ b/scenarios/curl_fuzzer_smtp/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_smtp/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_tftp/test_url_tftp.textproto b/scenarios/curl_fuzzer_tftp/test_url_tftp.textproto new file mode 100644 index 000000000..ba67528a8 --- /dev/null +++ b/scenarios/curl_fuzzer_tftp/test_url_tftp.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_tftp/test_url_tftp + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "tftp://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_tftp/test_wrongproto.textproto b/scenarios/curl_fuzzer_tftp/test_wrongproto.textproto new file mode 100644 index 000000000..b62dbef7e --- /dev/null +++ b/scenarios/curl_fuzzer_tftp/test_wrongproto.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_tftp/test_wrongproto + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "thisisnotaproto://127.0.0.1" + } +} diff --git a/scenarios/curl_fuzzer_ws/basictest.textproto b/scenarios/curl_fuzzer_ws/basictest.textproto new file mode 100644 index 000000000..b682c2a12 --- /dev/null +++ b/scenarios/curl_fuzzer_ws/basictest.textproto @@ -0,0 +1,15 @@ +# source: corpora/curl_fuzzer_ws/basictest + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ws://localhost" + } +} +connections { + id: 0 + initial_response { + payload: "test" + } +} diff --git a/scenarios/curl_fuzzer_ws/test_http_upgrade_to_ws.textproto b/scenarios/curl_fuzzer_ws/test_http_upgrade_to_ws.textproto new file mode 100644 index 000000000..85c57ef47 --- /dev/null +++ b/scenarios/curl_fuzzer_ws/test_http_upgrade_to_ws.textproto @@ -0,0 +1,64 @@ +# source: corpora/curl_fuzzer_ws/test_http_upgrade_to_ws + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ws://example.com:8080/wschat?a=b&c=d" + } +} +actions { + add_header { + value { + text: "Host: server.example.com" + } + } +} +actions { + add_header { + value { + text: "Upgrade: websocket" + } + } +} +actions { + add_header { + value { + text: "Connection: Close" + } + } +} +actions { + add_header { + value { + text: "Sec-WebSocket-Key: Aa01AAaAA1AaAa1900aAAa==" + } + } +} +actions { + add_header { + value { + text: "Sec-WebSocket-Protocol: chat, superchat" + } + } +} +actions { + add_header { + value { + text: "Sec-WebSocket-Version: 13" + } + } +} +actions { + add_header { + value { + text: "Origin: http://localhost.localdomain:80" + } + } +} +connections { + id: 0 + initial_response { + payload: "HTTP/1.1 101 SwitchingProtocols\r\nUpgrade:websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: AAAAAAAAAA0000000aaaaaaaaaa=\r\nSec-WebSocket-Protocol: chat\r\n\r\n" + } +} diff --git a/scenarios/curl_fuzzer_ws/ws_with_raw_mode_connect_test.textproto b/scenarios/curl_fuzzer_ws/ws_with_raw_mode_connect_test.textproto new file mode 100644 index 000000000..0122d3475 --- /dev/null +++ b/scenarios/curl_fuzzer_ws/ws_with_raw_mode_connect_test.textproto @@ -0,0 +1,23 @@ +# source: corpora/curl_fuzzer_ws/ws_with_raw_mode_connect_test + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ws://foo.bar.localdomain/this/is/a/path" + } +} +actions { + set_option { + option_id: CURLOPT_WS_OPTIONS + scope: OPTION_SCOPE_DEFAULT + uint32_value: 2 + } +} +actions { + set_option { + option_id: CURLOPT_POST + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} diff --git a/scenarios/curl_fuzzer_ws/ws_with_raw_mode_test.textproto b/scenarios/curl_fuzzer_ws/ws_with_raw_mode_test.textproto new file mode 100644 index 000000000..a40b862f5 --- /dev/null +++ b/scenarios/curl_fuzzer_ws/ws_with_raw_mode_test.textproto @@ -0,0 +1,16 @@ +# source: corpora/curl_fuzzer_ws/ws_with_raw_mode_test + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "ws://foo.bar.localdomain/this/is/a/path" + } +} +actions { + set_option { + option_id: CURLOPT_WS_OPTIONS + scope: OPTION_SCOPE_DEFAULT + uint32_value: 1 + } +} diff --git a/scenarios/curl_fuzzer_ws/wss_test.textproto b/scenarios/curl_fuzzer_ws/wss_test.textproto new file mode 100644 index 000000000..f5588797e --- /dev/null +++ b/scenarios/curl_fuzzer_ws/wss_test.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_ws/wss_test + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "wss://chat.example.is/foo?bar=baz&boop=borp" + } +} diff --git a/scenarios/curl_fuzzer_ws/wss_with_basic_auth_test.textproto b/scenarios/curl_fuzzer_ws/wss_with_basic_auth_test.textproto new file mode 100644 index 000000000..322ddfbed --- /dev/null +++ b/scenarios/curl_fuzzer_ws/wss_with_basic_auth_test.textproto @@ -0,0 +1,9 @@ +# source: corpora/curl_fuzzer_ws/wss_with_basic_auth_test + +actions { + set_option { + option_id: CURLOPT_URL + scope: OPTION_SCOPE_DEFAULT + string_value: "wss://username:password@chat.example.is/foo?bar=baz&boop=borp" + } +} diff --git a/schemas/curl_fuzzer.proto b/schemas/curl_fuzzer.proto new file mode 100644 index 000000000..748f7b99a --- /dev/null +++ b/schemas/curl_fuzzer.proto @@ -0,0 +1,367 @@ +syntax = "proto3"; + +package curl.fuzzer.proto; + +// Structured scenario description for the curl fuzzing harness. Intended for consumption by +// libprotobuf-mutator powered fuzz targets as well as tooling that converts +// between legacy TLV corpora and the structured representation. + +message Scenario { + repeated Action actions = 1; + repeated Connection connections = 2; +} + +message SetOption { + CurlOptionId option_id = 1; + OptionScope scope = 2; + oneof value { + bytes string_value = 10; + bytes bytes_value = 11; + int32 int32_value = 12; + uint32 uint32_value = 13; + int64 int64_value = 14; + uint64 uint64_value = 15; + bool bool_value = 16; + double double_value = 17; + } +} + +// A single configuration step executed before the transfer starts. +message Action { + oneof kind { + SetOption set_option = 1; + AddHeader add_header = 2; + AddMailRecipient add_mail_recipient = 3; + ConfigureMime configure_mime = 4; + ConfigureHttpPost configure_http_post = 5; + RegisterUpload register_upload = 6; + RegisterResponse register_response = 7; + } +} + +message AddHeader { + HeaderValue value = 1; +} + +message AddMailRecipient { + HeaderValue value = 1; +} + +message ConfigureMime { + repeated MimePart parts = 1; +} + +message ConfigureHttpPost { + repeated FormField fields = 1; +} + +message RegisterUpload { + bytes payload = 1; + TransferKind kind = 2; + uint64 size_hint = 3; +} + +message RegisterResponse { + uint32 connection_id = 1; // Default: 0 (primary connection) + ResponseStage stage = 2; + Response response = 3; +} + +// Target connection behaviour once libcurl connects. +message Connection { + uint32 id = 1; // 0 == primary, 1 == secondary, etc. + Response initial_response = 2; + repeated Response on_readable = 3; + ShutdownPolicy shutdown_policy = 4; + OptionalDelay idle_after_send = 5; +} + +message Response { + bytes payload = 1; + ResponseHint hint = 2; + OptionalDelay delay_before = 3; +} + +message ResponseHint { + bool chunked = 1; + bool websocket_frame = 2; + bool tls_record = 3; +} + +message OptionalDelay { + uint32 milliseconds = 1; +} + +message HeaderValue { + oneof value { + bytes text = 1; + bytes binary = 2; + } +} + +message MimePart { + bytes name = 1; + oneof body { + bytes bytes_value = 2; + bytes inline_data = 3; + } + bytes filename = 4; + bytes content_type = 5; + repeated HeaderValue headers = 6; +} + +message FormField { + bytes name = 1; + oneof body { + bytes bytes_value = 2; + bytes inline_data = 3; + } + bytes filename = 4; + bytes content_type = 5; +} + +// Scope for options that support multiple namespaces (e.g. proxy vs easy). +enum OptionScope { + OPTION_SCOPE_UNSPECIFIED = 0; + OPTION_SCOPE_DEFAULT = 1; + OPTION_SCOPE_PROXY = 2; + OPTION_SCOPE_DOH = 3; + OPTION_SCOPE_TLS = 4; +} + +enum TransferKind { + TRANSFER_KIND_UNSPECIFIED = 0; + TRANSFER_KIND_UPLOAD = 1; + TRANSFER_KIND_POSTFIELDS = 2; + TRANSFER_KIND_SEND = 3; +} + +enum ResponseStage { + RESPONSE_STAGE_UNSPECIFIED = 0; + RESPONSE_STAGE_ON_CONNECT = 1; + RESPONSE_STAGE_ON_READABLE = 2; +} + +enum ShutdownPolicy { + SHUTDOWN_POLICY_UNSPECIFIED = 0; + SHUTDOWN_POLICY_HALF_CLOSE_AFTER_LAST_RESPONSE = 1; + SHUTDOWN_POLICY_KEEP_OPEN = 2; + SHUTDOWN_POLICY_CLOSE_IMMEDIATELY = 3; +} + +// Mapping of structured options to libcurl option identifiers. The enum names +// intentionally mirror libcurl's `CURLOPT_*` constants for readability. +enum CurlOptionId { + CURL_OPTION_UNSPECIFIED = 0; + CURLOPT_ABSTRACT_UNIX_SOCKET = 10264; + CURLOPT_ACCEPTTIMEOUT_MS = 212; + CURLOPT_ACCEPT_ENCODING = 10102; + CURLOPT_ADDRESS_SCOPE = 171; + CURLOPT_ALTSVC_CTRL = 286; + CURLOPT_APPEND = 50; + CURLOPT_AUTOREFERER = 58; + CURLOPT_AWS_SIGV4 = 10305; + CURLOPT_BUFFERSIZE = 98; + CURLOPT_CAINFO = 10065; + CURLOPT_CAPATH = 10097; + CURLOPT_CA_CACHE_TIMEOUT = 321; + CURLOPT_CERTINFO = 172; + CURLOPT_CONNECTTIMEOUT = 78; + CURLOPT_CONNECTTIMEOUT_MS = 156; + CURLOPT_CONNECT_ONLY = 141; + CURLOPT_COOKIE = 10022; + CURLOPT_COOKIELIST = 10135; + CURLOPT_COOKIESESSION = 96; + CURLOPT_CUSTOMREQUEST = 10036; + CURLOPT_DEFAULT_PROTOCOL = 10238; + CURLOPT_DIRLISTONLY = 48; + CURLOPT_DISALLOW_USERNAME_IN_URL = 278; + CURLOPT_DNS_CACHE_TIMEOUT = 92; + CURLOPT_DNS_INTERFACE = 10221; + CURLOPT_DNS_LOCAL_IP4 = 10222; + CURLOPT_DNS_LOCAL_IP6 = 10223; + CURLOPT_DNS_SERVERS = 10211; + CURLOPT_DNS_SHUFFLE_ADDRESSES = 275; + CURLOPT_DOH_SSL_VERIFYHOST = 307; + CURLOPT_DOH_SSL_VERIFYPEER = 306; + CURLOPT_DOH_SSL_VERIFYSTATUS = 308; + CURLOPT_DOH_URL = 10279; + CURLOPT_ECH = 10325; + CURLOPT_EXPECT_100_TIMEOUT_MS = 227; + CURLOPT_FAILONERROR = 45; + CURLOPT_FILETIME = 69; + CURLOPT_FOLLOWLOCATION = 52; + CURLOPT_FORBID_REUSE = 75; + CURLOPT_FRESH_CONNECT = 74; + CURLOPT_FTPPORT = 10017; + CURLOPT_FTPSSLAUTH = 129; + CURLOPT_FTP_ACCOUNT = 10134; + CURLOPT_FTP_ALTERNATIVE_TO_USER = 10147; + CURLOPT_FTP_CREATE_MISSING_DIRS = 110; + CURLOPT_FTP_FILEMETHOD = 138; + CURLOPT_FTP_SKIP_PASV_IP = 137; + CURLOPT_FTP_SSL_CCC = 154; + CURLOPT_FTP_USE_EPRT = 106; + CURLOPT_FTP_USE_EPSV = 85; + CURLOPT_FTP_USE_PRET = 188; + CURLOPT_GSSAPI_DELEGATION = 210; + CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS = 271; + CURLOPT_HAPROXYPROTOCOL = 274; + CURLOPT_HAPROXY_CLIENT_IP = 10323; + CURLOPT_HEADER = 42; + CURLOPT_HEADEROPT = 229; + CURLOPT_HSTS_CTRL = 299; + CURLOPT_HTTP09_ALLOWED = 285; + CURLOPT_HTTPAUTH = 107; + CURLOPT_HTTPGET = 80; + CURLOPT_HTTPPOST = 10024; + CURLOPT_HTTPPROXYTUNNEL = 61; + CURLOPT_HTTP_CONTENT_DECODING = 158; + CURLOPT_HTTP_TRANSFER_DECODING = 157; + CURLOPT_HTTP_VERSION = 84; + CURLOPT_IGNORE_CONTENT_LENGTH = 136; + CURLOPT_INFILESIZE_LARGE = 30115; + CURLOPT_INTERFACE = 10062; + CURLOPT_IPRESOLVE = 113; + CURLOPT_ISSUERCERT = 10170; + CURLOPT_KEEP_SENDING_ON_ERROR = 245; + CURLOPT_KEYPASSWD = 10026; + CURLOPT_KRBLEVEL = 10063; + CURLOPT_LOCALPORT = 139; + CURLOPT_LOCALPORTRANGE = 140; + CURLOPT_LOGIN_OPTIONS = 10224; + CURLOPT_LOW_SPEED_LIMIT = 19; + CURLOPT_LOW_SPEED_TIME = 20; + CURLOPT_MAIL_AUTH = 10217; + CURLOPT_MAIL_FROM = 10186; + CURLOPT_MAIL_RCPT_ALLOWFAILS = 290; + CURLOPT_MAXAGE_CONN = 288; + CURLOPT_MAXCONNECTS = 71; + CURLOPT_MAXFILESIZE = 114; + CURLOPT_MAXFILESIZE_LARGE = 30117; + CURLOPT_MAXLIFETIME_CONN = 314; + CURLOPT_MAXREDIRS = 68; + CURLOPT_MAX_RECV_SPEED_LARGE = 30146; + CURLOPT_MAX_SEND_SPEED_LARGE = 30145; + CURLOPT_MIME_OPTIONS = 315; + CURLOPT_NETRC = 51; + CURLOPT_NEW_DIRECTORY_PERMS = 160; + CURLOPT_NEW_FILE_PERMS = 159; + CURLOPT_NOBODY = 44; + CURLOPT_NOPROGRESS = 43; + CURLOPT_NOPROXY = 10177; + CURLOPT_NOSIGNAL = 99; + CURLOPT_PASSWORD = 10174; + CURLOPT_PATH_AS_IS = 234; + CURLOPT_PINNEDPUBLICKEY = 10230; + CURLOPT_PIPEWAIT = 237; + CURLOPT_PORT = 3; + CURLOPT_POST = 47; + CURLOPT_POSTFIELDS = 10015; + CURLOPT_POSTFIELDSIZE = 60; + CURLOPT_POSTFIELDSIZE_LARGE = 30120; + CURLOPT_POSTREDIR = 161; + CURLOPT_PRE_PROXY = 10262; + CURLOPT_PROXY = 10004; + CURLOPT_PROXYAUTH = 111; + CURLOPT_PROXYPASSWORD = 10176; + CURLOPT_PROXYPORT = 59; + CURLOPT_PROXYTYPE = 101; + CURLOPT_PROXYUSERNAME = 10175; + CURLOPT_PROXYUSERPWD = 10006; + CURLOPT_PROXY_CAINFO = 10246; + CURLOPT_PROXY_CAPATH = 10247; + CURLOPT_PROXY_CRLFILE = 10260; + CURLOPT_PROXY_ISSUERCERT = 10296; + CURLOPT_PROXY_KEYPASSWD = 10258; + CURLOPT_PROXY_PINNEDPUBLICKEY = 10263; + CURLOPT_PROXY_SERVICE_NAME = 10235; + CURLOPT_PROXY_SSLCERT = 10254; + CURLOPT_PROXY_SSLCERTTYPE = 10255; + CURLOPT_PROXY_SSLKEY = 10256; + CURLOPT_PROXY_SSLKEYTYPE = 10257; + CURLOPT_PROXY_SSLVERSION = 250; + CURLOPT_PROXY_SSL_CIPHER_LIST = 10259; + CURLOPT_PROXY_SSL_OPTIONS = 261; + CURLOPT_PROXY_SSL_VERIFYHOST = 249; + CURLOPT_PROXY_SSL_VERIFYPEER = 248; + CURLOPT_PROXY_TLS13_CIPHERS = 10277; + CURLOPT_PROXY_TLSAUTH_PASSWORD = 10252; + CURLOPT_PROXY_TLSAUTH_TYPE = 10253; + CURLOPT_PROXY_TLSAUTH_USERNAME = 10251; + CURLOPT_PROXY_TRANSFER_MODE = 166; + CURLOPT_QUICK_EXIT = 322; + CURLOPT_RANGE = 10007; + CURLOPT_REDIR_PROTOCOLS_STR = 10319; + CURLOPT_REFERER = 10016; + CURLOPT_REQUEST_TARGET = 10266; + CURLOPT_RESUME_FROM = 21; + CURLOPT_RESUME_FROM_LARGE = 30116; + CURLOPT_RTSP_CLIENT_CSEQ = 193; + CURLOPT_RTSP_REQUEST = 189; + CURLOPT_RTSP_SERVER_CSEQ = 194; + CURLOPT_RTSP_SESSION_ID = 10190; + CURLOPT_RTSP_STREAM_URI = 10191; + CURLOPT_RTSP_TRANSPORT = 10192; + CURLOPT_SASL_AUTHZID = 10289; + CURLOPT_SASL_IR = 218; + CURLOPT_SERVER_RESPONSE_TIMEOUT_MS = 324; + CURLOPT_SERVICE_NAME = 10236; + CURLOPT_SOCKS5_AUTH = 267; + CURLOPT_SOCKS5_GSSAPI_NEC = 180; + CURLOPT_SSH_AUTH_TYPES = 151; + CURLOPT_SSH_COMPRESSION = 268; + CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 = 10162; + CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 = 10311; + CURLOPT_SSH_KNOWNHOSTS = 10183; + CURLOPT_SSH_PRIVATE_KEYFILE = 10153; + CURLOPT_SSH_PUBLIC_KEYFILE = 10152; + CURLOPT_SSLCERT = 10025; + CURLOPT_SSLCERTTYPE = 10086; + CURLOPT_SSLENGINE = 10089; + CURLOPT_SSLENGINE_DEFAULT = 90; + CURLOPT_SSLKEY = 10087; + CURLOPT_SSLKEYTYPE = 10088; + CURLOPT_SSLVERSION = 32; + CURLOPT_SSL_CIPHER_LIST = 10083; + CURLOPT_SSL_EC_CURVES = 10298; + CURLOPT_SSL_ENABLE_ALPN = 226; + CURLOPT_SSL_FALSESTART = 233; + CURLOPT_SSL_OPTIONS = 216; + CURLOPT_SSL_SESSIONID_CACHE = 150; + CURLOPT_SSL_VERIFYHOST = 81; + CURLOPT_SSL_VERIFYPEER = 64; + CURLOPT_SSL_VERIFYSTATUS = 232; + CURLOPT_STREAM_WEIGHT = 239; + CURLOPT_SUPPRESS_CONNECT_HEADERS = 265; + CURLOPT_TCP_FASTOPEN = 244; + CURLOPT_TCP_KEEPALIVE = 213; + CURLOPT_TCP_KEEPCNT = 326; + CURLOPT_TCP_KEEPIDLE = 214; + CURLOPT_TCP_KEEPINTVL = 215; + CURLOPT_TCP_NODELAY = 121; + CURLOPT_TFTP_BLKSIZE = 178; + CURLOPT_TFTP_NO_OPTIONS = 242; + CURLOPT_TIMECONDITION = 33; + CURLOPT_TIMEVALUE = 34; + CURLOPT_TIMEVALUE_LARGE = 30270; + CURLOPT_TLS13_CIPHERS = 10276; + CURLOPT_TLSAUTH_PASSWORD = 10205; + CURLOPT_TLSAUTH_TYPE = 10206; + CURLOPT_TLSAUTH_USERNAME = 10204; + CURLOPT_TRANSFERTEXT = 53; + CURLOPT_TRANSFER_ENCODING = 207; + CURLOPT_UNIX_SOCKET_PATH = 10231; + CURLOPT_UNRESTRICTED_AUTH = 105; + CURLOPT_UPKEEP_INTERVAL_MS = 281; + CURLOPT_UPLOAD = 46; + CURLOPT_UPLOAD_BUFFERSIZE = 280; + CURLOPT_URL = 10002; + CURLOPT_USERAGENT = 10018; + CURLOPT_USERNAME = 10173; + CURLOPT_USERPWD = 10005; + CURLOPT_USE_SSL = 119; + CURLOPT_WILDCARDMATCH = 197; + CURLOPT_WS_OPTIONS = 320; + CURLOPT_XOAUTH2_BEARER = 10220; +} diff --git a/schemas/curl_fuzzer_supported_curlopts.txt b/schemas/curl_fuzzer_supported_curlopts.txt new file mode 100644 index 000000000..ee9bdd79a --- /dev/null +++ b/schemas/curl_fuzzer_supported_curlopts.txt @@ -0,0 +1,211 @@ +CURLOPT_ABSTRACT_UNIX_SOCKET +CURLOPT_ACCEPTTIMEOUT_MS +CURLOPT_ACCEPT_ENCODING +CURLOPT_ADDRESS_SCOPE +CURLOPT_ALTSVC_CTRL +CURLOPT_APPEND +CURLOPT_AUTOREFERER +CURLOPT_AWS_SIGV4 +CURLOPT_BUFFERSIZE +CURLOPT_CAINFO +CURLOPT_CAPATH +CURLOPT_CA_CACHE_TIMEOUT +CURLOPT_CERTINFO +CURLOPT_CONNECTTIMEOUT +CURLOPT_CONNECTTIMEOUT_MS +CURLOPT_CONNECT_ONLY +CURLOPT_COOKIE +CURLOPT_COOKIELIST +CURLOPT_COOKIESESSION +CURLOPT_CUSTOMREQUEST +CURLOPT_DEFAULT_PROTOCOL +CURLOPT_DIRLISTONLY +CURLOPT_DISALLOW_USERNAME_IN_URL +CURLOPT_DNS_CACHE_TIMEOUT +CURLOPT_DNS_INTERFACE +CURLOPT_DNS_LOCAL_IP4 +CURLOPT_DNS_LOCAL_IP6 +CURLOPT_DNS_SERVERS +CURLOPT_DNS_SHUFFLE_ADDRESSES +CURLOPT_DOH_SSL_VERIFYHOST +CURLOPT_DOH_SSL_VERIFYPEER +CURLOPT_DOH_SSL_VERIFYSTATUS +CURLOPT_DOH_URL +CURLOPT_ECH +CURLOPT_EXPECT_100_TIMEOUT_MS +CURLOPT_FAILONERROR +CURLOPT_FILETIME +CURLOPT_FOLLOWLOCATION +CURLOPT_FORBID_REUSE +CURLOPT_FRESH_CONNECT +CURLOPT_FTPPORT +CURLOPT_FTPSSLAUTH +CURLOPT_FTP_ACCOUNT +CURLOPT_FTP_ALTERNATIVE_TO_USER +CURLOPT_FTP_CREATE_MISSING_DIRS +CURLOPT_FTP_FILEMETHOD +CURLOPT_FTP_SKIP_PASV_IP +CURLOPT_FTP_SSL_CCC +CURLOPT_FTP_USE_EPRT +CURLOPT_FTP_USE_EPSV +CURLOPT_FTP_USE_PRET +CURLOPT_GSSAPI_DELEGATION +CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS +CURLOPT_HAPROXYPROTOCOL +CURLOPT_HAPROXY_CLIENT_IP +CURLOPT_HEADER +CURLOPT_HEADEROPT +CURLOPT_HSTS_CTRL +CURLOPT_HTTP09_ALLOWED +CURLOPT_HTTPAUTH +CURLOPT_HTTPGET +CURLOPT_HTTPPOST +CURLOPT_HTTPPROXYTUNNEL +CURLOPT_HTTP_CONTENT_DECODING +CURLOPT_HTTP_TRANSFER_DECODING +CURLOPT_HTTP_VERSION +CURLOPT_IGNORE_CONTENT_LENGTH +CURLOPT_INFILESIZE_LARGE +CURLOPT_INTERFACE +CURLOPT_IPRESOLVE +CURLOPT_ISSUERCERT +CURLOPT_KEEP_SENDING_ON_ERROR +CURLOPT_KEYPASSWD +CURLOPT_KRBLEVEL +CURLOPT_LOCALPORT +CURLOPT_LOCALPORTRANGE +CURLOPT_LOGIN_OPTIONS +CURLOPT_LOW_SPEED_LIMIT +CURLOPT_LOW_SPEED_TIME +CURLOPT_MAIL_AUTH +CURLOPT_MAIL_FROM +CURLOPT_MAIL_RCPT_ALLOWFAILS +CURLOPT_MAXAGE_CONN +CURLOPT_MAXCONNECTS +CURLOPT_MAXFILESIZE +CURLOPT_MAXFILESIZE_LARGE +CURLOPT_MAXLIFETIME_CONN +CURLOPT_MAXREDIRS +CURLOPT_MAX_RECV_SPEED_LARGE +CURLOPT_MAX_SEND_SPEED_LARGE +CURLOPT_MIME_OPTIONS +CURLOPT_NETRC +CURLOPT_NEW_DIRECTORY_PERMS +CURLOPT_NEW_FILE_PERMS +CURLOPT_NOBODY +CURLOPT_NOPROGRESS +CURLOPT_NOPROXY +CURLOPT_NOSIGNAL +CURLOPT_PASSWORD +CURLOPT_PATH_AS_IS +CURLOPT_PINNEDPUBLICKEY +CURLOPT_PIPEWAIT +CURLOPT_PORT +CURLOPT_POST +CURLOPT_POSTFIELDS +CURLOPT_POSTFIELDSIZE +CURLOPT_POSTFIELDSIZE_LARGE +CURLOPT_POSTREDIR +CURLOPT_PRE_PROXY +CURLOPT_PROXY +CURLOPT_PROXYAUTH +CURLOPT_PROXYPASSWORD +CURLOPT_PROXYPORT +CURLOPT_PROXYTYPE +CURLOPT_PROXYUSERNAME +CURLOPT_PROXYUSERPWD +CURLOPT_PROXY_CAINFO +CURLOPT_PROXY_CAPATH +CURLOPT_PROXY_CRLFILE +CURLOPT_PROXY_ISSUERCERT +CURLOPT_PROXY_KEYPASSWD +CURLOPT_PROXY_PINNEDPUBLICKEY +CURLOPT_PROXY_SERVICE_NAME +CURLOPT_PROXY_SSLCERT +CURLOPT_PROXY_SSLCERTTYPE +CURLOPT_PROXY_SSLKEY +CURLOPT_PROXY_SSLKEYTYPE +CURLOPT_PROXY_SSLVERSION +CURLOPT_PROXY_SSL_CIPHER_LIST +CURLOPT_PROXY_SSL_OPTIONS +CURLOPT_PROXY_SSL_VERIFYHOST +CURLOPT_PROXY_SSL_VERIFYPEER +CURLOPT_PROXY_TLS13_CIPHERS +CURLOPT_PROXY_TLSAUTH_PASSWORD +CURLOPT_PROXY_TLSAUTH_TYPE +CURLOPT_PROXY_TLSAUTH_USERNAME +CURLOPT_PROXY_TRANSFER_MODE +CURLOPT_QUICK_EXIT +CURLOPT_RANGE +CURLOPT_REDIR_PROTOCOLS_STR +CURLOPT_REFERER +CURLOPT_REQUEST_TARGET +CURLOPT_RESUME_FROM +CURLOPT_RESUME_FROM_LARGE +CURLOPT_RTSP_CLIENT_CSEQ +CURLOPT_RTSP_REQUEST +CURLOPT_RTSP_SERVER_CSEQ +CURLOPT_RTSP_SESSION_ID +CURLOPT_RTSP_STREAM_URI +CURLOPT_RTSP_TRANSPORT +CURLOPT_SASL_AUTHZID +CURLOPT_SASL_IR +CURLOPT_SERVER_RESPONSE_TIMEOUT_MS +CURLOPT_SERVICE_NAME +CURLOPT_SOCKS5_AUTH +CURLOPT_SOCKS5_GSSAPI_NEC +CURLOPT_SSH_AUTH_TYPES +CURLOPT_SSH_COMPRESSION +CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 +CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 +CURLOPT_SSH_KNOWNHOSTS +CURLOPT_SSH_PRIVATE_KEYFILE +CURLOPT_SSH_PUBLIC_KEYFILE +CURLOPT_SSLCERT +CURLOPT_SSLCERTTYPE +CURLOPT_SSLENGINE +CURLOPT_SSLENGINE_DEFAULT +CURLOPT_SSLKEY +CURLOPT_SSLKEYTYPE +CURLOPT_SSLVERSION +CURLOPT_SSL_CIPHER_LIST +CURLOPT_SSL_EC_CURVES +CURLOPT_SSL_ENABLE_ALPN +CURLOPT_SSL_FALSESTART +CURLOPT_SSL_OPTIONS +CURLOPT_SSL_SESSIONID_CACHE +CURLOPT_SSL_VERIFYHOST +CURLOPT_SSL_VERIFYPEER +CURLOPT_SSL_VERIFYSTATUS +CURLOPT_STREAM_WEIGHT +CURLOPT_SUPPRESS_CONNECT_HEADERS +CURLOPT_TCP_FASTOPEN +CURLOPT_TCP_KEEPALIVE +CURLOPT_TCP_KEEPCNT +CURLOPT_TCP_KEEPIDLE +CURLOPT_TCP_KEEPINTVL +CURLOPT_TCP_NODELAY +CURLOPT_TFTP_BLKSIZE +CURLOPT_TFTP_NO_OPTIONS +CURLOPT_TIMECONDITION +CURLOPT_TIMEVALUE +CURLOPT_TIMEVALUE_LARGE +CURLOPT_TLS13_CIPHERS +CURLOPT_TLSAUTH_PASSWORD +CURLOPT_TLSAUTH_TYPE +CURLOPT_TLSAUTH_USERNAME +CURLOPT_TRANSFERTEXT +CURLOPT_TRANSFER_ENCODING +CURLOPT_UNIX_SOCKET_PATH +CURLOPT_UNRESTRICTED_AUTH +CURLOPT_UPKEEP_INTERVAL_MS +CURLOPT_UPLOAD +CURLOPT_UPLOAD_BUFFERSIZE +CURLOPT_URL +CURLOPT_USERAGENT +CURLOPT_USERNAME +CURLOPT_USERPWD +CURLOPT_USE_SSL +CURLOPT_WILDCARDMATCH +CURLOPT_WS_OPTIONS +CURLOPT_XOAUTH2_BEARER diff --git a/scripts/32bitdeps.sh b/scripts/32bitdeps.sh new file mode 100755 index 000000000..699abecc1 --- /dev/null +++ b/scripts/32bitdeps.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# +# This script is called in a 32-bit build environment to install necessary +# dependencies. + +set -ex + +# Work out if we need to install with sudo or not. +if [[ $(id -u) -eq 0 ]] +then + # We are root, so we can install without sudo. + echo "Running as root, no sudo required." + export SUDO="" +else + # We are not root, so we need to use sudo. + echo "Running as non-root, using sudo." + export SUDO="sudo" +fi + +# Download dependencies for oss-fuzz +$SUDO dpkg --add-architecture i386 +$SUDO apt-get -o Dpkg::Use-Pty=0 update +$SUDO apt-get -o Dpkg::Use-Pty=0 install -y \ + protobuf-compiler:i386 \ + libprotobuf-dev:i386 \ + libstdc++-9-dev:i386 diff --git a/scripts/compile_structured_corpora.sh b/scripts/compile_structured_corpora.sh new file mode 100755 index 000000000..3f04c4156 --- /dev/null +++ b/scripts/compile_structured_corpora.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPTDIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +ROOT=$(readlink -f "${SCRIPTDIR}/..") + +SCENARIOS_DIR="${ROOT}/scenarios" +CORPORA_DIR="${ROOT}/corpora" +SCHEMAS_DIR="${ROOT}/schemas" +PROTO_FILE="curl_fuzzer.proto" +MESSAGE_TYPE="curl.fuzzer.proto.Scenario" +PROTOC_BIN="${PROTOC:-protoc}" + +if ! command -v "${PROTOC_BIN}" >/dev/null 2>&1; then + echo "error: protoc compiler not found. Set PROTOC to override." >&2 + exit 1 +fi + +if [[ ! -d "${SCENARIOS_DIR}" ]]; then + echo "error: scenarios directory '${SCENARIOS_DIR}' not found" >&2 + exit 1 +fi + +if [[ ! -d "${SCHEMAS_DIR}" ]]; then + echo "error: schemas directory '${SCHEMAS_DIR}' not found" >&2 + exit 1 +fi + +mkdir -p "${CORPORA_DIR}" + +# Prune stale structured corpus entries to keep parity with the scenarios tree. +find "${CORPORA_DIR}" -type f -name '*.scenario' -delete 2>/dev/null || true + +count=0 +while IFS= read -r -d '' textproto ; do + rel_path="${textproto#${SCENARIOS_DIR}/}" + output_path="${CORPORA_DIR}/${rel_path%.textproto}.scenario" + mkdir -p "$(dirname -- "${output_path}")" + if ! "${PROTOC_BIN}" \ + --proto_path="${SCHEMAS_DIR}" \ + --encode="${MESSAGE_TYPE}" \ + "${SCHEMAS_DIR}/${PROTO_FILE}" \ + < "${textproto}" \ + > "${output_path}" ; then + echo "error: failed to compile '${textproto}'" >&2 + exit 1 + fi + printf 'compiled %s -> %s\n' "${rel_path}" "${output_path#${CORPORA_DIR}/}" + count=$((count + 1)) +done < <(find "${SCENARIOS_DIR}" -type f -name '*.textproto' -print0) + +echo "Generated ${count} structured corpus entrie(s) under ${CORPORA_DIR}." diff --git a/scripts/compile_target.sh b/scripts/compile_target.sh index 7cd27ba54..a36a66412 100755 --- a/scripts/compile_target.sh +++ b/scripts/compile_target.sh @@ -28,6 +28,15 @@ TARGET=${1:-fuzz} SCRIPTDIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) export BUILD_ROOT; BUILD_ROOT=$(readlink -f "${SCRIPTDIR}/..") +# shellcheck source=stdlib_flag_utils.sh +source "${SCRIPTDIR}/stdlib_flag_utils.sh" + +# Install any 32-bit dependencies if building for 32-bit. +if [[ "${ARCHITECTURE:-}" == "i386" ]] +then + "${SCRIPTDIR}/32bitdeps.sh" +fi + # Check for GDB-specific behaviour by checking for the GDBMODE flag. # - Compile with -O0 so that DEBUGASSERTs can be debugged in gdb. if [[ -n ${GDBMODE:-} ]] @@ -39,6 +48,16 @@ else CMAKE_GDB_FLAG="-DBUILD_GDB=OFF" fi +# The OSS-Fuzz toolchain injects -stdlib=libc++, but several of our +# dependencies (notably system protobuf) are built against libstdc++. +# Mixing libstdc++ and libc++ results in unresolved symbols with +# std::__1 types, so drop the explicit libc++ request and rely on the +# default toolchain choice instead. +strip_flag CXXFLAGS "-stdlib=libc++" +strip_flag CFLAGS "-stdlib=libc++" + +ensure_libstdcxx_flag CXXFLAGS + echo "BUILD_ROOT: $BUILD_ROOT" echo "SRC: ${SRC:-undefined}" echo "CC: ${CC:-undefined}" diff --git a/scripts/stdlib_flag_utils.sh b/scripts/stdlib_flag_utils.sh new file mode 100644 index 000000000..b780d71e9 --- /dev/null +++ b/scripts/stdlib_flag_utils.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Max Dymond, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +# shellcheck shell=bash + +strip_flag() +{ + local var_name=$1 + local flag=$2 + local current=${!var_name-} + + if [[ -n ${current:-} ]] + then + # shellcheck disable=SC2140 + current=${current//${flag}/} + current=$(echo "${current}" | tr -s ' ') + export "${var_name}"="${current}" + fi +} + +_stdlib_compiler_supports_libstdcxx() +{ + local compiler_words + + if [[ -n ${CXX:-} ]] + then + # shellcheck disable=SC2206 + compiler_words=( ${CXX} ) + else + compiler_words=( c++ ) + fi + + if ! command -v "${compiler_words[0]}" >/dev/null 2>&1 + then + return 1 + fi + + local tmp_src tmp_obj + tmp_src=$(mktemp) + tmp_obj=$(mktemp) + + cat <<'EOF' > "${tmp_src}" +int main() { return 0; } +EOF + + if "${compiler_words[@]}" -x c++ "${tmp_src}" -c -o "${tmp_obj}" -stdlib=libstdc++ >/dev/null 2>&1 + then + rm -f "${tmp_src}" "${tmp_obj}" + return 0 + fi + + rm -f "${tmp_src}" "${tmp_obj}" + return 1 +} + +ensure_libstdcxx_flag() +{ + local var_name=$1 + + if _stdlib_compiler_supports_libstdcxx + then + if [[ ${!var_name:-} != *"-stdlib=libstdc++"* ]] + then + export "${var_name}"="${!var_name:-} -stdlib=libstdc++" + fi + else + strip_flag "${var_name}" "-stdlib=libstdc++" + fi +} \ No newline at end of file diff --git a/src/curl_fuzzer_tools/generate_option_manifest.py b/src/curl_fuzzer_tools/generate_option_manifest.py new file mode 100644 index 000000000..08cd867ed --- /dev/null +++ b/src/curl_fuzzer_tools/generate_option_manifest.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python3 +""" +Regenerate option manifest artefacts from the supported CURLOPT list. + +This script reads a plain-text list of supported CURLOPT identifiers, looks up +metadata in curl.h to determine each option's numeric value and value kind, and +then emits two artefacts: + +* generated/curl_fuzzer_option_manifest.inc – consumed by the runtime harness. +* schemas/curl_fuzzer.proto – the CurlOptionId enum gains the native values. + +It replaces the previous YAML-driven flow with an approach that derives type and +numeric identifiers directly from curl.h so that we remain in sync with the +upstream library. +""" +from __future__ import annotations + +import dataclasses +import pathlib +import re +from typing import Dict, Iterable, List + +REPO_ROOT = pathlib.Path(__file__).resolve().parents[2] +SUPPORTED_LIST = REPO_ROOT / "schemas" / "curl_fuzzer_supported_curlopts.txt" +CURL_HEADER = REPO_ROOT / "build" / "curl-install" / "include" / "curl" / "curl.h" +PROTO_FILE = REPO_ROOT / "schemas" / "curl_fuzzer.proto" +MANIFEST_FILE = REPO_ROOT / "generated" / "curl_fuzzer_option_manifest.inc" + +TYPE_BASE_VALUES: Dict[str, int] = { + "CURLOPTTYPE_LONG": 0, + "CURLOPTTYPE_VALUES": 0, + "CURLOPTTYPE_OBJECTPOINT": 10000, + "CURLOPTTYPE_STRINGPOINT": 10000, + "CURLOPTTYPE_SLISTPOINT": 10000, + "CURLOPTTYPE_CBPOINT": 10000, + "CURLOPTTYPE_FUNCTIONPOINT": 20000, + "CURLOPTTYPE_OFF_T": 30000, + "CURLOPTTYPE_BLOB": 40000, +} + +BASE_KIND: Dict[str, str] = { + "CURLOPTTYPE_LONG": "uint32", + "CURLOPTTYPE_VALUES": "uint32", + "CURLOPTTYPE_STRINGPOINT": "string", + # The remaining pointer-based families require explicit overrides. + "CURLOPTTYPE_OBJECTPOINT": "unknown", + "CURLOPTTYPE_SLISTPOINT": "unknown", + "CURLOPTTYPE_CBPOINT": "unknown", + "CURLOPTTYPE_FUNCTIONPOINT": "unknown", + "CURLOPTTYPE_BLOB": "unknown", + "CURLOPTTYPE_OFF_T": "uint64", +} + +OPTION_KIND_OVERRIDES: Dict[str, str] = { + # Pointers that are treated as specialised structs. + "CURLOPT_HTTPPOST": "http_post", + "CURLOPT_MIMEPOST": "mime", + # Object pointers that hold string-like data. + "CURLOPT_POSTFIELDS": "string", + # Historically modelled as booleans although libcurl exposes them as long. + "CURLOPT_UPLOAD": "bool", +} + +VALUE_KIND_SYMBOLS: Dict[str, str] = { + "string": "OptionValueKind::kString", + "uint32": "OptionValueKind::kUint32", + "uint64": "OptionValueKind::kUint64", + "bool": "OptionValueKind::kBool", + "http_post": "OptionValueKind::kHttpPost", + "mime": "OptionValueKind::kMime", + "unknown": "OptionValueKind::kUnknown", +} + + +@dataclasses.dataclass(frozen=True) +class CurlOption: + name: str + type_token: str + curl_value: int + + @property + def manifest_kind(self) -> str: + base_kind = BASE_KIND.get(self.type_token) + kind = OPTION_KIND_OVERRIDES.get(self.name, base_kind) + if kind is None or kind == "unknown": + raise ValueError( + f"Unsupported type mapping for {self.name}: {self.type_token}. " + "Please extend OPTION_KIND_OVERRIDES or BASE_KIND." + ) + return kind + + +def load_supported_options(path: pathlib.Path) -> List[str]: + if not path.exists(): + raise FileNotFoundError(f"Supported options list missing: {path}") + options: List[str] = [] + for raw_line in path.read_text().splitlines(): + line = raw_line.strip() + if not line or line.startswith("#"): + continue + options.append(line) + if not options: + raise ValueError(f"No options found in {path}") + return options + + +def parse_curl_header(path: pathlib.Path) -> Dict[str, CurlOption]: + if not path.exists(): + raise FileNotFoundError(f"curl.h not found at {path}") + text = path.read_text() + pattern = re.compile( + r"CURLOPT(?:DEPRECATED)?\(\s*(CURLOPT_[A-Z0-9_]+)\s*,\s*(CURLOPTTYPE_[A-Z0-9_]+)\s*,\s*([0-9]+)", + re.MULTILINE, + ) + options: Dict[str, CurlOption] = {} + for match in pattern.finditer(text): + name, type_token, offset_text = match.groups() + if type_token not in TYPE_BASE_VALUES: + raise ValueError(f"Unknown CURLOPT type token: {type_token} for {name}") + base_value = TYPE_BASE_VALUES[type_token] + offset = int(offset_text) + options[name] = CurlOption(name=name, type_token=type_token, curl_value=base_value + offset) + if not options: + raise ValueError("Failed to extract any CURLOPT definitions from curl.h") + return options + + +def emit_manifest(entries: Iterable[CurlOption]) -> str: + lines = [ + "// Generated by src/curl_fuzzer_tools/generate_option_manifest.py", + "static constexpr OptionDescriptor kOptionManifest[] = {", + ] + for option in entries: + kind_symbol = VALUE_KIND_SYMBOLS[option.manifest_kind] + lines.append( + f" {{curl::fuzzer::proto::{option.name}, {kind_symbol}, true, \"{option.name}\", {option.name}}}," + ) + lines.append("};") + lines.append( + "static constexpr size_t kOptionManifestSize = sizeof(kOptionManifest) / sizeof(kOptionManifest[0]);" + ) + return "\n".join(lines) + "\n" + + +def rewrite_proto(entries: Iterable[CurlOption], proto_path: pathlib.Path) -> None: + text = proto_path.read_text() + enum_marker = "enum CurlOptionId" + start_idx = text.find(enum_marker) + if start_idx == -1: + raise ValueError("Unable to locate CurlOptionId enum in curl_fuzzer.proto") + brace_idx = text.find("{", start_idx) + if brace_idx == -1: + raise ValueError("Malformed CurlOptionId enum definition") + depth = 1 + idx = brace_idx + 1 + while idx < len(text) and depth > 0: + char = text[idx] + if char == "{": + depth += 1 + elif char == "}": + depth -= 1 + idx += 1 + if depth != 0: + raise ValueError("Unbalanced braces when parsing CurlOptionId enum") + closing_idx = idx - 1 # Position of the closing brace + + indent = " " + enum_lines = [f"{indent}CURL_OPTION_UNSPECIFIED = 0;"] + enum_lines.extend( + f"{indent}{option.name} = {option.curl_value};" for option in entries + ) + enum_body = "\n".join(enum_lines) + "\n" + + new_text = text[: brace_idx + 1] + "\n" + enum_body + text[closing_idx:] + proto_path.write_text(new_text) + + +def main() -> int: + supported = load_supported_options(SUPPORTED_LIST) + header_options = parse_curl_header(CURL_HEADER) + + ordered_entries: List[CurlOption] = [] + for name in supported: + if name not in header_options: + raise KeyError(f"CURLOPT {name} not found in curl.h") + ordered_entries.append(header_options[name]) + + MANIFEST_FILE.write_text(emit_manifest(ordered_entries)) + rewrite_proto(ordered_entries, PROTO_FILE) + + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())