cjson
.github
workflows CI.yml ci-fuzz.yml
CONTRIBUTING.md
fuzzing
inputs test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9
.gitignore CMakeLists.txt afl-prepare-linux.sh afl.c afl.sh cjson_read_fuzzer.c fuzz_main.c json.dict ossfuzz.sh
library_config cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmake
tests
inputs test1 test1.expected test10 test10.expected test11 test11.expected test2 test2.expected test3 test3.expected test4 test4.expected test5 test5.expected test6 test7 test7.expected test8 test8.expected test9 test9.expected
json-patch-tests .editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.json
unity
auto colour_prompt.rb colour_reporter.rb generate_config.yml generate_module.rb generate_test_runner.rb parse_output.rb stylize_as_junit.rb test_file_filter.rb type_sanitizer.rb unity_test_summary.py unity_test_summary.rb unity_to_junit.py
docs ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txt
examples
example_1
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_2
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_3
helper UnityHelper.c UnityHelper.h
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
rakefile.rb rakefile_helper.rb readme.txt target_gcc_32.yml
unity_config.h
extras
eclipse error_parsers.txt
fixture
src unity_fixture.c unity_fixture.h unity_fixture_internals.h unity_fixture_malloc_overrides.h
rakefile.rb rakefile_helper.rb readme.txt
release build.info version.info
src unity.c unity.h unity_internals.h
.gitattributes .gitignore .travis.yml README.md
CMakeLists.txt cjson_add.c common.h compare_tests.c json_patch_tests.c minify_tests.c misc_tests.c misc_utils_tests.c old_utils_tests.c parse_array.c parse_examples.c parse_hex4.c parse_number.c parse_object.c parse_string.c parse_value.c parse_with_opts.c print_array.c print_number.c print_object.c print_string.c print_value.c readme_examples.c unity_setup.c
.editorconfig .gitattributes .gitignore .travis.yml CHANGELOG.md CMakeLists.txt CONTRIBUTORS.md LICENSE Makefile README.md SECURITY.md appveyor.yml cJSON.c cJSON.h cJSON_Utils.c cJSON_Utils.h test.c valgrind.supp
curl
.circleci config.yml
.github
ISSUE_TEMPLATE bug_report.yml config.yml docs.yml
scripts cleancmd.pl cmp-config.pl cmp-pkg-config.sh codespell-ignore.words codespell.sh distfiles.sh pyspelling.words pyspelling.yaml randcurl.pl requirements-docs.txt requirements-proselint.txt requirements.txt shellcheck-ci.sh shellcheck.sh spellcheck.curl trimmarkdownheader.pl typos.sh typos.toml verify-examples.pl verify-synopsis.pl yamlcheck.sh yamlcheck.yaml
workflows appveyor-status.yml checkdocs.yml checksrc.yml checkurls.yml codeql.yml configure-vs-cmake.yml curl-for-win.yml distcheck.yml fuzz.yml http3-linux.yml label.yml linux-old.yml linux.yml macos.yml non-native.yml windows.yml
CODEOWNERS CONTRIBUTING.md FUNDING.yml dependabot.yml labeler.yml lock.yml stale.yml
CMake CurlSymbolHiding.cmake CurlTests.c FindBrotli.cmake FindCares.cmake FindGSS.cmake FindGnuTLS.cmake FindLDAP.cmake FindLibbacktrace.cmake FindLibgsasl.cmake FindLibidn2.cmake FindLibpsl.cmake FindLibssh.cmake FindLibssh2.cmake FindLibuv.cmake FindMbedTLS.cmake FindNGHTTP2.cmake FindNGHTTP3.cmake FindNGTCP2.cmake FindNettle.cmake FindQuiche.cmake FindRustls.cmake FindWolfSSL.cmake FindZstd.cmake Macros.cmake OtherTests.cmake PickyWarnings.cmake Utilities.cmake cmake_uninstall.in.cmake curl-config.in.cmake unix-cache.cmake win32-cache.cmake
LICENSES BSD-4-Clause-UC.txt ISC.txt curl.txt
docs
cmdline-opts .gitignore CMakeLists.txt MANPAGE.md Makefile.am Makefile.inc _AUTHORS.md _BUGS.md _DESCRIPTION.md _ENVIRONMENT.md _EXITCODES.md _FILES.md _GLOBBING.md _NAME.md _OPTIONS.md _OUTPUT.md _PROGRESS.md _PROTOCOLS.md _PROXYPREFIX.md _SEEALSO.md _SYNOPSIS.md _URL.md _VARIABLES.md _VERSION.md _WWW.md abstract-unix-socket.md alt-svc.md anyauth.md append.md aws-sigv4.md basic.md ca-native.md cacert.md capath.md cert-status.md cert-type.md cert.md ciphers.md compressed-ssh.md compressed.md config.md connect-timeout.md connect-to.md continue-at.md cookie-jar.md cookie.md create-dirs.md create-file-mode.md crlf.md crlfile.md curves.md data-ascii.md data-binary.md data-raw.md data-urlencode.md data.md delegation.md digest.md disable-eprt.md disable-epsv.md disable.md disallow-username-in-url.md dns-interface.md dns-ipv4-addr.md dns-ipv6-addr.md dns-servers.md doh-cert-status.md doh-insecure.md doh-url.md dump-ca-embed.md dump-header.md ech.md egd-file.md engine.md etag-compare.md etag-save.md expect100-timeout.md fail-early.md fail-with-body.md fail.md false-start.md follow.md form-escape.md form-string.md form.md ftp-account.md ftp-alternative-to-user.md ftp-create-dirs.md ftp-method.md ftp-pasv.md ftp-port.md ftp-pret.md ftp-skip-pasv-ip.md ftp-ssl-ccc-mode.md ftp-ssl-ccc.md ftp-ssl-control.md get.md globoff.md happy-eyeballs-timeout-ms.md haproxy-clientip.md haproxy-protocol.md head.md header.md help.md hostpubmd5.md hostpubsha256.md hsts.md http0.9.md http1.0.md http1.1.md http2-prior-knowledge.md http2.md http3-only.md http3.md ignore-content-length.md insecure.md interface.md ip-tos.md ipfs-gateway.md ipv4.md ipv6.md json.md junk-session-cookies.md keepalive-cnt.md keepalive-time.md key-type.md key.md knownhosts.md krb.md libcurl.md limit-rate.md list-only.md local-port.md location-trusted.md location.md login-options.md mail-auth.md mail-from.md mail-rcpt-allowfails.md mail-rcpt.md mainpage.idx manual.md max-filesize.md max-redirs.md max-time.md metalink.md mptcp.md negotiate.md netrc-file.md netrc-optional.md netrc.md next.md no-alpn.md no-buffer.md no-clobber.md no-keepalive.md no-npn.md no-progress-meter.md no-sessionid.md noproxy.md ntlm-wb.md ntlm.md oauth2-bearer.md out-null.md output-dir.md output.md parallel-immediate.md parallel-max-host.md parallel-max.md parallel.md pass.md path-as-is.md pinnedpubkey.md post301.md post302.md post303.md preproxy.md progress-bar.md proto-default.md proto-redir.md proto.md proxy-anyauth.md proxy-basic.md proxy-ca-native.md proxy-cacert.md proxy-capath.md proxy-cert-type.md proxy-cert.md proxy-ciphers.md proxy-crlfile.md proxy-digest.md proxy-header.md proxy-http2.md proxy-insecure.md proxy-key-type.md proxy-key.md proxy-negotiate.md proxy-ntlm.md proxy-pass.md proxy-pinnedpubkey.md proxy-service-name.md proxy-ssl-allow-beast.md proxy-ssl-auto-client-cert.md proxy-tls13-ciphers.md proxy-tlsauthtype.md proxy-tlspassword.md proxy-tlsuser.md proxy-tlsv1.md proxy-user.md proxy.md proxy1.0.md proxytunnel.md pubkey.md quote.md random-file.md range.md rate.md raw.md referer.md remote-header-name.md remote-name-all.md remote-name.md remote-time.md remove-on-error.md request-target.md request.md resolve.md retry-all-errors.md retry-connrefused.md retry-delay.md retry-max-time.md retry.md sasl-authzid.md sasl-ir.md service-name.md show-error.md show-headers.md sigalgs.md silent.md skip-existing.md socks4.md socks4a.md socks5-basic.md socks5-gssapi-nec.md socks5-gssapi-service.md socks5-gssapi.md socks5-hostname.md socks5.md speed-limit.md speed-time.md ssl-allow-beast.md ssl-auto-client-cert.md ssl-no-revoke.md ssl-reqd.md ssl-revoke-best-effort.md ssl-sessions.md ssl.md sslv2.md sslv3.md stderr.md styled-output.md suppress-connect-headers.md tcp-fastopen.md tcp-nodelay.md telnet-option.md tftp-blksize.md tftp-no-options.md time-cond.md tls-earlydata.md tls-max.md tls13-ciphers.md tlsauthtype.md tlspassword.md tlsuser.md tlsv1.0.md tlsv1.1.md tlsv1.2.md tlsv1.3.md tlsv1.md tr-encoding.md trace-ascii.md trace-config.md trace-ids.md trace-time.md trace.md unix-socket.md upload-file.md upload-flags.md url-query.md url.md use-ascii.md user-agent.md user.md variable.md verbose.md version.md vlan-priority.md write-out.md xattr.md
examples .checksrc .gitignore 10-at-a-time.c CMakeLists.txt Makefile.am Makefile.example Makefile.inc README.md adddocsref.pl address-scope.c altsvc.c anyauthput.c block_ip.c cacertinmem.c certinfo.c chkspeed.c connect-to.c cookie_interface.c crawler.c debug.c default-scheme.c ephiperfifo.c evhiperfifo.c externalsocket.c fileupload.c ftp-delete.c ftp-wildcard.c ftpget.c ftpgetinfo.c ftpgetresp.c ftpsget.c ftpupload.c ftpuploadfrommem.c ftpuploadresume.c getinfo.c getinmemory.c getredirect.c getreferrer.c ghiper.c headerapi.c hiperfifo.c hsts-preload.c htmltidy.c htmltitle.cpp http-options.c http-post.c http2-download.c http2-pushinmemory.c http2-serverpush.c http2-upload.c http3-present.c http3.c httpcustomheader.c httpput-postfields.c httpput.c https.c imap-append.c imap-authzid.c imap-copy.c imap-create.c imap-delete.c imap-examine.c imap-fetch.c imap-list.c imap-lsub.c imap-multi.c imap-noop.c imap-search.c imap-ssl.c imap-store.c imap-tls.c interface.c ipv6.c keepalive.c localport.c log_failed_transfers.c maxconnects.c multi-app.c multi-debugcallback.c multi-double.c multi-event.c multi-formadd.c multi-legacy.c multi-post.c multi-single.c multi-uv.c netrc.c parseurl.c persistent.c pop3-authzid.c pop3-dele.c pop3-list.c pop3-multi.c pop3-noop.c pop3-retr.c pop3-ssl.c pop3-stat.c pop3-tls.c pop3-top.c pop3-uidl.c post-callback.c postinmemory.c postit2-formadd.c postit2.c progressfunc.c protofeats.c range.c resolve.c rtsp-options.c sendrecv.c sepheaders.c sessioninfo.c sftpget.c sftpuploadresume.c shared-connection-cache.c simple.c simplepost.c simplessl.c smooth-gtk-thread.c smtp-authzid.c smtp-expn.c smtp-mail.c smtp-mime.c smtp-multi.c smtp-ssl.c smtp-tls.c smtp-vrfy.c sslbackend.c synctime.c threaded.c unixsocket.c url2file.c urlapi.c usercertinmem.c version-check.pl websocket-cb.c websocket-updown.c websocket.c xmlstream.c
internals BUFQ.md BUFREF.md CHECKSRC.md CLIENT-READERS.md CLIENT-WRITERS.md CODE_STYLE.md CONNECTION-FILTERS.md CREDENTIALS.md CURLX.md DYNBUF.md HASH.md LLIST.md MID.md MQTT.md MULTI-EV.md NEW-PROTOCOL.md PEERS.md PORTING.md RATELIMITS.md README.md SCORECARD.md SPLAY.md STRPARSE.md THRDPOOL-AND-QUEUE.md TIME-KEEPING.md TLS-SESSIONS.md UINT_SETS.md WEBSOCKET.md
libcurl
opts CMakeLists.txt CURLINFO_ACTIVESOCKET.md CURLINFO_APPCONNECT_TIME.md CURLINFO_APPCONNECT_TIME_T.md CURLINFO_CAINFO.md CURLINFO_CAPATH.md CURLINFO_CERTINFO.md CURLINFO_CONDITION_UNMET.md CURLINFO_CONNECT_TIME.md CURLINFO_CONNECT_TIME_T.md CURLINFO_CONN_ID.md CURLINFO_CONTENT_LENGTH_DOWNLOAD.md CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md CURLINFO_CONTENT_LENGTH_UPLOAD.md CURLINFO_CONTENT_LENGTH_UPLOAD_T.md CURLINFO_CONTENT_TYPE.md CURLINFO_COOKIELIST.md CURLINFO_EARLYDATA_SENT_T.md CURLINFO_EFFECTIVE_METHOD.md CURLINFO_EFFECTIVE_URL.md CURLINFO_FILETIME.md CURLINFO_FILETIME_T.md CURLINFO_FTP_ENTRY_PATH.md CURLINFO_HEADER_SIZE.md CURLINFO_HTTPAUTH_AVAIL.md CURLINFO_HTTPAUTH_USED.md CURLINFO_HTTP_CONNECTCODE.md CURLINFO_HTTP_VERSION.md CURLINFO_LASTSOCKET.md CURLINFO_LOCAL_IP.md CURLINFO_LOCAL_PORT.md CURLINFO_NAMELOOKUP_TIME.md CURLINFO_NAMELOOKUP_TIME_T.md CURLINFO_NUM_CONNECTS.md CURLINFO_OS_ERRNO.md CURLINFO_POSTTRANSFER_TIME_T.md CURLINFO_PRETRANSFER_TIME.md CURLINFO_PRETRANSFER_TIME_T.md CURLINFO_PRIMARY_IP.md CURLINFO_PRIMARY_PORT.md CURLINFO_PRIVATE.md CURLINFO_PROTOCOL.md CURLINFO_PROXYAUTH_AVAIL.md CURLINFO_PROXYAUTH_USED.md CURLINFO_PROXY_ERROR.md CURLINFO_PROXY_SSL_VERIFYRESULT.md CURLINFO_QUEUE_TIME_T.md CURLINFO_REDIRECT_COUNT.md CURLINFO_REDIRECT_TIME.md CURLINFO_REDIRECT_TIME_T.md CURLINFO_REDIRECT_URL.md CURLINFO_REFERER.md CURLINFO_REQUEST_SIZE.md CURLINFO_RESPONSE_CODE.md CURLINFO_RETRY_AFTER.md CURLINFO_RTSP_CLIENT_CSEQ.md CURLINFO_RTSP_CSEQ_RECV.md CURLINFO_RTSP_SERVER_CSEQ.md CURLINFO_RTSP_SESSION_ID.md CURLINFO_SCHEME.md CURLINFO_SIZE_DELIVERED.md CURLINFO_SIZE_DOWNLOAD.md CURLINFO_SIZE_DOWNLOAD_T.md CURLINFO_SIZE_UPLOAD.md CURLINFO_SIZE_UPLOAD_T.md CURLINFO_SPEED_DOWNLOAD.md CURLINFO_SPEED_DOWNLOAD_T.md CURLINFO_SPEED_UPLOAD.md CURLINFO_SPEED_UPLOAD_T.md CURLINFO_SSL_ENGINES.md CURLINFO_SSL_VERIFYRESULT.md CURLINFO_STARTTRANSFER_TIME.md CURLINFO_STARTTRANSFER_TIME_T.md CURLINFO_TLS_SESSION.md CURLINFO_TLS_SSL_PTR.md CURLINFO_TOTAL_TIME.md CURLINFO_TOTAL_TIME_T.md CURLINFO_USED_PROXY.md CURLINFO_XFER_ID.md CURLMINFO_XFERS_ADDED.md CURLMINFO_XFERS_CURRENT.md CURLMINFO_XFERS_DONE.md CURLMINFO_XFERS_PENDING.md CURLMINFO_XFERS_RUNNING.md CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.md CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.md CURLMOPT_MAXCONNECTS.md CURLMOPT_MAX_CONCURRENT_STREAMS.md CURLMOPT_MAX_HOST_CONNECTIONS.md CURLMOPT_MAX_PIPELINE_LENGTH.md CURLMOPT_MAX_TOTAL_CONNECTIONS.md CURLMOPT_NETWORK_CHANGED.md CURLMOPT_NOTIFYDATA.md CURLMOPT_NOTIFYFUNCTION.md CURLMOPT_PIPELINING.md CURLMOPT_PIPELINING_SERVER_BL.md CURLMOPT_PIPELINING_SITE_BL.md CURLMOPT_PUSHDATA.md CURLMOPT_PUSHFUNCTION.md CURLMOPT_QUICK_EXIT.md CURLMOPT_RESOLVE_THREADS_MAX.md CURLMOPT_SOCKETDATA.md CURLMOPT_SOCKETFUNCTION.md CURLMOPT_TIMERDATA.md CURLMOPT_TIMERFUNCTION.md CURLOPT_ABSTRACT_UNIX_SOCKET.md CURLOPT_ACCEPTTIMEOUT_MS.md CURLOPT_ACCEPT_ENCODING.md CURLOPT_ADDRESS_SCOPE.md CURLOPT_ALTSVC.md CURLOPT_ALTSVC_CTRL.md CURLOPT_APPEND.md CURLOPT_AUTOREFERER.md CURLOPT_AWS_SIGV4.md CURLOPT_BUFFERSIZE.md CURLOPT_CAINFO.md CURLOPT_CAINFO_BLOB.md CURLOPT_CAPATH.md CURLOPT_CA_CACHE_TIMEOUT.md CURLOPT_CERTINFO.md CURLOPT_CHUNK_BGN_FUNCTION.md CURLOPT_CHUNK_DATA.md CURLOPT_CHUNK_END_FUNCTION.md CURLOPT_CLOSESOCKETDATA.md CURLOPT_CLOSESOCKETFUNCTION.md CURLOPT_CONNECTTIMEOUT.md CURLOPT_CONNECTTIMEOUT_MS.md CURLOPT_CONNECT_ONLY.md CURLOPT_CONNECT_TO.md CURLOPT_CONV_FROM_NETWORK_FUNCTION.md CURLOPT_CONV_FROM_UTF8_FUNCTION.md CURLOPT_CONV_TO_NETWORK_FUNCTION.md CURLOPT_COOKIE.md CURLOPT_COOKIEFILE.md CURLOPT_COOKIEJAR.md CURLOPT_COOKIELIST.md CURLOPT_COOKIESESSION.md CURLOPT_COPYPOSTFIELDS.md CURLOPT_CRLF.md CURLOPT_CRLFILE.md CURLOPT_CURLU.md CURLOPT_CUSTOMREQUEST.md CURLOPT_DEBUGDATA.md CURLOPT_DEBUGFUNCTION.md CURLOPT_DEFAULT_PROTOCOL.md CURLOPT_DIRLISTONLY.md CURLOPT_DISALLOW_USERNAME_IN_URL.md CURLOPT_DNS_CACHE_TIMEOUT.md CURLOPT_DNS_INTERFACE.md CURLOPT_DNS_LOCAL_IP4.md CURLOPT_DNS_LOCAL_IP6.md CURLOPT_DNS_SERVERS.md CURLOPT_DNS_SHUFFLE_ADDRESSES.md CURLOPT_DNS_USE_GLOBAL_CACHE.md CURLOPT_DOH_SSL_VERIFYHOST.md CURLOPT_DOH_SSL_VERIFYPEER.md CURLOPT_DOH_SSL_VERIFYSTATUS.md CURLOPT_DOH_URL.md CURLOPT_ECH.md CURLOPT_EGDSOCKET.md CURLOPT_ERRORBUFFER.md CURLOPT_EXPECT_100_TIMEOUT_MS.md CURLOPT_FAILONERROR.md CURLOPT_FILETIME.md CURLOPT_FNMATCH_DATA.md CURLOPT_FNMATCH_FUNCTION.md CURLOPT_FOLLOWLOCATION.md CURLOPT_FORBID_REUSE.md CURLOPT_FRESH_CONNECT.md CURLOPT_FTPPORT.md CURLOPT_FTPSSLAUTH.md CURLOPT_FTP_ACCOUNT.md CURLOPT_FTP_ALTERNATIVE_TO_USER.md CURLOPT_FTP_CREATE_MISSING_DIRS.md CURLOPT_FTP_FILEMETHOD.md CURLOPT_FTP_SKIP_PASV_IP.md CURLOPT_FTP_SSL_CCC.md CURLOPT_FTP_USE_EPRT.md CURLOPT_FTP_USE_EPSV.md CURLOPT_FTP_USE_PRET.md CURLOPT_GSSAPI_DELEGATION.md CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.md CURLOPT_HAPROXYPROTOCOL.md CURLOPT_HAPROXY_CLIENT_IP.md CURLOPT_HEADER.md CURLOPT_HEADERDATA.md CURLOPT_HEADERFUNCTION.md CURLOPT_HEADEROPT.md CURLOPT_HSTS.md CURLOPT_HSTSREADDATA.md CURLOPT_HSTSREADFUNCTION.md CURLOPT_HSTSWRITEDATA.md CURLOPT_HSTSWRITEFUNCTION.md CURLOPT_HSTS_CTRL.md CURLOPT_HTTP09_ALLOWED.md CURLOPT_HTTP200ALIASES.md CURLOPT_HTTPAUTH.md CURLOPT_HTTPGET.md CURLOPT_HTTPHEADER.md CURLOPT_HTTPPOST.md CURLOPT_HTTPPROXYTUNNEL.md CURLOPT_HTTP_CONTENT_DECODING.md CURLOPT_HTTP_TRANSFER_DECODING.md CURLOPT_HTTP_VERSION.md CURLOPT_IGNORE_CONTENT_LENGTH.md CURLOPT_INFILESIZE.md CURLOPT_INFILESIZE_LARGE.md CURLOPT_INTERFACE.md CURLOPT_INTERLEAVEDATA.md CURLOPT_INTERLEAVEFUNCTION.md CURLOPT_IOCTLDATA.md CURLOPT_IOCTLFUNCTION.md CURLOPT_IPRESOLVE.md CURLOPT_ISSUERCERT.md CURLOPT_ISSUERCERT_BLOB.md CURLOPT_KEEP_SENDING_ON_ERROR.md CURLOPT_KEYPASSWD.md CURLOPT_KRBLEVEL.md CURLOPT_LOCALPORT.md CURLOPT_LOCALPORTRANGE.md CURLOPT_LOGIN_OPTIONS.md CURLOPT_LOW_SPEED_LIMIT.md CURLOPT_LOW_SPEED_TIME.md CURLOPT_MAIL_AUTH.md CURLOPT_MAIL_FROM.md CURLOPT_MAIL_RCPT.md CURLOPT_MAIL_RCPT_ALLOWFAILS.md CURLOPT_MAXAGE_CONN.md CURLOPT_MAXCONNECTS.md CURLOPT_MAXFILESIZE.md CURLOPT_MAXFILESIZE_LARGE.md CURLOPT_MAXLIFETIME_CONN.md CURLOPT_MAXREDIRS.md CURLOPT_MAX_RECV_SPEED_LARGE.md CURLOPT_MAX_SEND_SPEED_LARGE.md CURLOPT_MIMEPOST.md CURLOPT_MIME_OPTIONS.md CURLOPT_NETRC.md CURLOPT_NETRC_FILE.md CURLOPT_NEW_DIRECTORY_PERMS.md CURLOPT_NEW_FILE_PERMS.md CURLOPT_NOBODY.md CURLOPT_NOPROGRESS.md CURLOPT_NOPROXY.md CURLOPT_NOSIGNAL.md CURLOPT_OPENSOCKETDATA.md CURLOPT_OPENSOCKETFUNCTION.md CURLOPT_PASSWORD.md CURLOPT_PATH_AS_IS.md CURLOPT_PINNEDPUBLICKEY.md CURLOPT_PIPEWAIT.md CURLOPT_PORT.md CURLOPT_POST.md CURLOPT_POSTFIELDS.md CURLOPT_POSTFIELDSIZE.md CURLOPT_POSTFIELDSIZE_LARGE.md CURLOPT_POSTQUOTE.md CURLOPT_POSTREDIR.md CURLOPT_PREQUOTE.md CURLOPT_PREREQDATA.md CURLOPT_PREREQFUNCTION.md CURLOPT_PRE_PROXY.md CURLOPT_PRIVATE.md CURLOPT_PROGRESSDATA.md CURLOPT_PROGRESSFUNCTION.md CURLOPT_PROTOCOLS.md CURLOPT_PROTOCOLS_STR.md CURLOPT_PROXY.md CURLOPT_PROXYAUTH.md CURLOPT_PROXYHEADER.md CURLOPT_PROXYPASSWORD.md CURLOPT_PROXYPORT.md CURLOPT_PROXYTYPE.md CURLOPT_PROXYUSERNAME.md CURLOPT_PROXYUSERPWD.md CURLOPT_PROXY_CAINFO.md CURLOPT_PROXY_CAINFO_BLOB.md CURLOPT_PROXY_CAPATH.md CURLOPT_PROXY_CRLFILE.md CURLOPT_PROXY_ISSUERCERT.md CURLOPT_PROXY_ISSUERCERT_BLOB.md CURLOPT_PROXY_KEYPASSWD.md CURLOPT_PROXY_PINNEDPUBLICKEY.md CURLOPT_PROXY_SERVICE_NAME.md CURLOPT_PROXY_SSLCERT.md CURLOPT_PROXY_SSLCERTTYPE.md CURLOPT_PROXY_SSLCERT_BLOB.md CURLOPT_PROXY_SSLKEY.md CURLOPT_PROXY_SSLKEYTYPE.md CURLOPT_PROXY_SSLKEY_BLOB.md CURLOPT_PROXY_SSLVERSION.md CURLOPT_PROXY_SSL_CIPHER_LIST.md CURLOPT_PROXY_SSL_OPTIONS.md CURLOPT_PROXY_SSL_VERIFYHOST.md CURLOPT_PROXY_SSL_VERIFYPEER.md CURLOPT_PROXY_TLS13_CIPHERS.md CURLOPT_PROXY_TLSAUTH_PASSWORD.md CURLOPT_PROXY_TLSAUTH_TYPE.md CURLOPT_PROXY_TLSAUTH_USERNAME.md CURLOPT_PROXY_TRANSFER_MODE.md CURLOPT_PUT.md CURLOPT_QUICK_EXIT.md CURLOPT_QUOTE.md CURLOPT_RANDOM_FILE.md CURLOPT_RANGE.md CURLOPT_READDATA.md CURLOPT_READFUNCTION.md CURLOPT_REDIR_PROTOCOLS.md CURLOPT_REDIR_PROTOCOLS_STR.md CURLOPT_REFERER.md CURLOPT_REQUEST_TARGET.md CURLOPT_RESOLVE.md CURLOPT_RESOLVER_START_DATA.md CURLOPT_RESOLVER_START_FUNCTION.md CURLOPT_RESUME_FROM.md CURLOPT_RESUME_FROM_LARGE.md CURLOPT_RTSP_CLIENT_CSEQ.md CURLOPT_RTSP_REQUEST.md CURLOPT_RTSP_SERVER_CSEQ.md CURLOPT_RTSP_SESSION_ID.md CURLOPT_RTSP_STREAM_URI.md CURLOPT_RTSP_TRANSPORT.md CURLOPT_SASL_AUTHZID.md CURLOPT_SASL_IR.md CURLOPT_SEEKDATA.md CURLOPT_SEEKFUNCTION.md CURLOPT_SERVER_RESPONSE_TIMEOUT.md CURLOPT_SERVER_RESPONSE_TIMEOUT_MS.md CURLOPT_SERVICE_NAME.md CURLOPT_SHARE.md CURLOPT_SOCKOPTDATA.md CURLOPT_SOCKOPTFUNCTION.md CURLOPT_SOCKS5_AUTH.md CURLOPT_SOCKS5_GSSAPI_NEC.md CURLOPT_SOCKS5_GSSAPI_SERVICE.md CURLOPT_SSH_AUTH_TYPES.md CURLOPT_SSH_COMPRESSION.md CURLOPT_SSH_HOSTKEYDATA.md CURLOPT_SSH_HOSTKEYFUNCTION.md CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md CURLOPT_SSH_KEYDATA.md CURLOPT_SSH_KEYFUNCTION.md CURLOPT_SSH_KNOWNHOSTS.md CURLOPT_SSH_PRIVATE_KEYFILE.md CURLOPT_SSH_PUBLIC_KEYFILE.md CURLOPT_SSLCERT.md CURLOPT_SSLCERTTYPE.md CURLOPT_SSLCERT_BLOB.md CURLOPT_SSLENGINE.md CURLOPT_SSLENGINE_DEFAULT.md CURLOPT_SSLKEY.md CURLOPT_SSLKEYTYPE.md CURLOPT_SSLKEY_BLOB.md CURLOPT_SSLVERSION.md CURLOPT_SSL_CIPHER_LIST.md CURLOPT_SSL_CTX_DATA.md CURLOPT_SSL_CTX_FUNCTION.md CURLOPT_SSL_EC_CURVES.md CURLOPT_SSL_ENABLE_ALPN.md CURLOPT_SSL_ENABLE_NPN.md CURLOPT_SSL_FALSESTART.md CURLOPT_SSL_OPTIONS.md CURLOPT_SSL_SESSIONID_CACHE.md CURLOPT_SSL_SIGNATURE_ALGORITHMS.md CURLOPT_SSL_VERIFYHOST.md CURLOPT_SSL_VERIFYPEER.md CURLOPT_SSL_VERIFYSTATUS.md CURLOPT_STDERR.md CURLOPT_STREAM_DEPENDS.md CURLOPT_STREAM_DEPENDS_E.md CURLOPT_STREAM_WEIGHT.md CURLOPT_SUPPRESS_CONNECT_HEADERS.md CURLOPT_TCP_FASTOPEN.md CURLOPT_TCP_KEEPALIVE.md CURLOPT_TCP_KEEPCNT.md CURLOPT_TCP_KEEPIDLE.md CURLOPT_TCP_KEEPINTVL.md CURLOPT_TCP_NODELAY.md CURLOPT_TELNETOPTIONS.md CURLOPT_TFTP_BLKSIZE.md CURLOPT_TFTP_NO_OPTIONS.md CURLOPT_TIMECONDITION.md CURLOPT_TIMEOUT.md CURLOPT_TIMEOUT_MS.md CURLOPT_TIMEVALUE.md CURLOPT_TIMEVALUE_LARGE.md CURLOPT_TLS13_CIPHERS.md CURLOPT_TLSAUTH_PASSWORD.md CURLOPT_TLSAUTH_TYPE.md CURLOPT_TLSAUTH_USERNAME.md CURLOPT_TRAILERDATA.md CURLOPT_TRAILERFUNCTION.md CURLOPT_TRANSFERTEXT.md CURLOPT_TRANSFER_ENCODING.md CURLOPT_UNIX_SOCKET_PATH.md CURLOPT_UNRESTRICTED_AUTH.md CURLOPT_UPKEEP_INTERVAL_MS.md CURLOPT_UPLOAD.md CURLOPT_UPLOAD_BUFFERSIZE.md CURLOPT_UPLOAD_FLAGS.md CURLOPT_URL.md CURLOPT_USERAGENT.md CURLOPT_USERNAME.md CURLOPT_USERPWD.md CURLOPT_USE_SSL.md CURLOPT_VERBOSE.md CURLOPT_WILDCARDMATCH.md CURLOPT_WRITEDATA.md CURLOPT_WRITEFUNCTION.md CURLOPT_WS_OPTIONS.md CURLOPT_XFERINFODATA.md CURLOPT_XFERINFOFUNCTION.md CURLOPT_XOAUTH2_BEARER.md CURLSHOPT_LOCKFUNC.md CURLSHOPT_SHARE.md CURLSHOPT_UNLOCKFUNC.md CURLSHOPT_UNSHARE.md CURLSHOPT_USERDATA.md Makefile.am Makefile.inc
.gitignore ABI.md CMakeLists.txt Makefile.am Makefile.inc curl_easy_cleanup.md curl_easy_duphandle.md curl_easy_escape.md curl_easy_getinfo.md curl_easy_header.md curl_easy_init.md curl_easy_nextheader.md curl_easy_option_by_id.md curl_easy_option_by_name.md curl_easy_option_next.md curl_easy_pause.md curl_easy_perform.md curl_easy_recv.md curl_easy_reset.md curl_easy_send.md curl_easy_setopt.md curl_easy_ssls_export.md curl_easy_ssls_import.md curl_easy_strerror.md curl_easy_unescape.md curl_easy_upkeep.md curl_escape.md curl_formadd.md curl_formfree.md curl_formget.md curl_free.md curl_getdate.md curl_getenv.md curl_global_cleanup.md curl_global_init.md curl_global_init_mem.md curl_global_sslset.md curl_global_trace.md curl_mime_addpart.md curl_mime_data.md curl_mime_data_cb.md curl_mime_encoder.md curl_mime_filedata.md curl_mime_filename.md curl_mime_free.md curl_mime_headers.md curl_mime_init.md curl_mime_name.md curl_mime_subparts.md curl_mime_type.md curl_mprintf.md curl_multi_add_handle.md curl_multi_assign.md curl_multi_cleanup.md curl_multi_fdset.md curl_multi_get_handles.md curl_multi_get_offt.md curl_multi_info_read.md curl_multi_init.md curl_multi_notify_disable.md curl_multi_notify_enable.md curl_multi_perform.md curl_multi_poll.md curl_multi_remove_handle.md curl_multi_setopt.md curl_multi_socket.md curl_multi_socket_action.md curl_multi_socket_all.md curl_multi_strerror.md curl_multi_timeout.md curl_multi_wait.md curl_multi_waitfds.md curl_multi_wakeup.md curl_pushheader_byname.md curl_pushheader_bynum.md curl_share_cleanup.md curl_share_init.md curl_share_setopt.md curl_share_strerror.md curl_slist_append.md curl_slist_free_all.md curl_strequal.md curl_strnequal.md curl_unescape.md curl_url.md curl_url_cleanup.md curl_url_dup.md curl_url_get.md curl_url_set.md curl_url_strerror.md curl_version.md curl_version_info.md curl_ws_meta.md curl_ws_recv.md curl_ws_send.md curl_ws_start_frame.md libcurl-easy.md libcurl-env-dbg.md libcurl-env.md libcurl-errors.md libcurl-multi.md libcurl-security.md libcurl-share.md libcurl-thread.md libcurl-tutorial.md libcurl-url.md libcurl-ws.md libcurl.m4 libcurl.md mksymbolsmanpage.pl symbols-in-versions symbols.pl
tests CI.md FILEFORMAT.md HTTP.md TEST-SUITE.md
.gitignore ALTSVC.md BINDINGS.md BUG-BOUNTY.md BUGS.md CIPHERS-TLS12.md CIPHERS.md CMakeLists.txt CODE_OF_CONDUCT.md CODE_REVIEW.md CONTRIBUTE.md CURL-DISABLE.md CURLDOWN.md DEPRECATE.md DISTROS.md EARLY-RELEASE.md ECH.md EXPERIMENTAL.md FAQ.md FEATURES.md GOVERNANCE.md HELP-US.md HISTORY.md HSTS.md HTTP-COOKIES.md HTTP3.md HTTPSRR.md INFRASTRUCTURE.md INSTALL-CMAKE.md INSTALL.md INTERNALS.md IPFS.md KNOWN_BUGS.md KNOWN_RISKS.md MAIL-ETIQUETTE.md MANUAL.md Makefile.am README.md RELEASE-PROCEDURE.md ROADMAP.md RUSTLS.md SECURITY-ADVISORY.md SPONSORS.md SSL-PROBLEMS.md SSLCERTS.md THANKS THANKS-filter TODO.md TheArtOfHttpScripting.md URL-SYNTAX.md VERIFY.md VERSIONS.md VULN-DISCLOSURE-POLICY.md curl-config.md mk-ca-bundle.md options-in-versions runtests.md testcurl.md wcurl.md
include
curl Makefile.am curl.h curlver.h easy.h header.h mprintf.h multi.h options.h stdcheaders.h system.h typecheck-gcc.h urlapi.h websockets.h
Makefile.am README.md
lib
curlx base64.c base64.h basename.c basename.h dynbuf.c dynbuf.h fopen.c fopen.h inet_ntop.c inet_ntop.h inet_pton.c inet_pton.h multibyte.c multibyte.h nonblock.c nonblock.h snprintf.c snprintf.h strcopy.c strcopy.h strdup.c strdup.h strerr.c strerr.h strparse.c strparse.h timediff.c timediff.h timeval.c timeval.h version_win32.c version_win32.h wait.c wait.h warnless.c warnless.h winapi.c winapi.h
vauth cleartext.c cram.c digest.c digest.h digest_sspi.c gsasl.c krb5_gssapi.c krb5_sspi.c ntlm.c ntlm_sspi.c oauth2.c spnego_gssapi.c spnego_sspi.c vauth.c vauth.h
vquic curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.h
vssh libssh.c libssh2.c ssh.h vssh.c vssh.h
vtls apple.c apple.h cipher_suite.c cipher_suite.h gtls.c gtls.h hostcheck.c hostcheck.h keylog.c keylog.h mbedtls.c mbedtls.h openssl.c openssl.h rustls.c rustls.h schannel.c schannel.h schannel_int.h schannel_verify.c vtls.c vtls.h vtls_int.h vtls_scache.c vtls_scache.h vtls_spack.c vtls_spack.h wolfssl.c wolfssl.h x509asn1.c x509asn1.h
.gitignore CMakeLists.txt Makefile.am Makefile.inc Makefile.soname altsvc.c altsvc.h amigaos.c amigaos.h arpa_telnet.h asyn-ares.c asyn-base.c asyn-thrdd.c asyn.h bufq.c bufq.h bufref.c bufref.h cf-dns.c cf-dns.h cf-h1-proxy.c cf-h1-proxy.h cf-h2-proxy.c cf-h2-proxy.h cf-haproxy.c cf-haproxy.h cf-https-connect.c cf-https-connect.h cf-ip-happy.c cf-ip-happy.h cf-socket.c cf-socket.h cfilters.c cfilters.h config-mac.h config-os400.h config-riscos.h config-win32.h conncache.c conncache.h connect.c connect.h content_encoding.c content_encoding.h cookie.c cookie.h creds.c creds.h cshutdn.c cshutdn.h curl_addrinfo.c curl_addrinfo.h curl_config-cmake.h.in curl_ctype.h curl_endian.c curl_endian.h curl_fnmatch.c curl_fnmatch.h curl_fopen.c curl_fopen.h curl_get_line.c curl_get_line.h curl_gethostname.c curl_gethostname.h curl_gssapi.c curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memrchr.c curl_memrchr.h curl_ntlm_core.c curl_ntlm_core.h curl_printf.h curl_range.c curl_range.h curl_sasl.c curl_sasl.h curl_setup.h curl_sha256.h curl_sha512_256.c curl_sha512_256.h curl_share.c curl_share.h curl_sspi.c curl_sspi.h curl_threads.c curl_threads.h curl_trc.c curl_trc.h cw-out.c cw-out.h cw-pause.c cw-pause.h dict.c dict.h dllmain.c dnscache.c dnscache.h doh.c doh.h dynhds.c dynhds.h easy.c easy_lock.h easygetopt.c easyif.h easyoptions.c easyoptions.h escape.c escape.h fake_addrinfo.c fake_addrinfo.h file.c file.h fileinfo.c fileinfo.h formdata.c formdata.h ftp-int.h ftp.c ftp.h ftplistparser.c ftplistparser.h functypes.h getenv.c getinfo.c getinfo.h gopher.c gopher.h hash.c hash.h headers.c headers.h hmac.c hostip.c hostip.h hostip4.c hostip6.c hsts.c hsts.h http.c http.h http1.c http1.h http2.c http2.h http_aws_sigv4.c http_aws_sigv4.h http_chunks.c http_chunks.h http_digest.c http_digest.h http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h http_proxy.c http_proxy.h httpsrr.c httpsrr.h idn.c idn.h if2ip.c if2ip.h imap.c imap.h ldap.c libcurl.def libcurl.rc libcurl.vers.in llist.c llist.h macos.c macos.h md4.c md5.c memdebug.c mime.c mime.h mprintf.c mqtt.c mqtt.h multi.c multi_ev.c multi_ev.h multi_ntfy.c multi_ntfy.h multihandle.h multiif.h netrc.c netrc.h noproxy.c noproxy.h openldap.c optiontable.pl parsedate.c parsedate.h peer.c peer.h pingpong.c pingpong.h pop3.c pop3.h progress.c progress.h protocol.c protocol.h psl.c psl.h rand.c rand.h ratelimit.c ratelimit.h request.c request.h rtsp.c rtsp.h select.c select.h sendf.c sendf.h setopt.c setopt.h setup-os400.h setup-vms.h setup-win32.h sha256.c sigpipe.h slist.c slist.h smb.c smb.h smtp.c smtp.h sockaddr.h socketpair.c socketpair.h socks.c socks.h socks_gssapi.c socks_sspi.c splay.c splay.h strcase.c strcase.h strequal.c strerror.c strerror.h system_win32.c system_win32.h telnet.c telnet.h tftp.c tftp.h thrdpool.c thrdpool.h thrdqueue.c thrdqueue.h transfer.c transfer.h uint-bset.c uint-bset.h uint-hash.c uint-hash.h uint-spbset.c uint-spbset.h uint-table.c uint-table.h url.c url.h urlapi-int.h urlapi.c urldata.h version.c ws.c ws.h
m4 .gitignore curl-amissl.m4 curl-apple-sectrust.m4 curl-compilers.m4 curl-confopts.m4 curl-functions.m4 curl-gnutls.m4 curl-mbedtls.m4 curl-openssl.m4 curl-override.m4 curl-reentrant.m4 curl-rustls.m4 curl-schannel.m4 curl-sysconfig.m4 curl-wolfssl.m4 xc-am-iface.m4 xc-cc-check.m4 xc-lt-iface.m4 xc-val-flgs.m4 zz40-xc-ovr.m4 zz50-xc-ovr.m4
projects
OS400
rpg-examples HEADERAPI HTTPPOST INMEMORY SIMPLE1 SIMPLE2 SMTPSRCMBR
.checksrc README.OS400 ccsidcurl.c ccsidcurl.h config400.default curl.cmd curl.inc.in curlcl.c curlmain.c initscript.sh make-docs.sh make-include.sh make-lib.sh make-src.sh make-tests.sh makefile.sh os400sys.c os400sys.h
Windows
tmpl .gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filters
.gitignore README.md generate.bat
vms Makefile.am backup_gnv_curl_src.com build_curl-config_script.com build_gnv_curl.com build_gnv_curl_pcsi_desc.com build_gnv_curl_pcsi_text.com build_gnv_curl_release_notes.com build_libcurl_pc.com build_vms.com clean_gnv_curl.com compare_curl_source.com config_h.com curl_crtl_init.c curl_gnv_build_steps.txt curl_release_note_start.txt curl_startup.com curlmsg.h curlmsg.msg curlmsg.sdl curlmsg_vms.h generate_config_vms_h_curl.com generate_vax_transfer.com gnv_conftest.c_first gnv_curl_configure.sh gnv_libcurl_symbols.opt gnv_link_curl.com macro32_exactcase.patch make_gnv_curl_install.sh make_pcsi_curl_kit_name.com pcsi_gnv_curl_file_list.txt pcsi_product_gnv_curl.com readme report_openssl_version.c setup_gnv_curl_build.com stage_curl_install.com vms_eco_level.h
Makefile.am README.md
scripts .checksrc CMakeLists.txt Makefile.am badwords badwords-all badwords.txt cd2cd cd2nroff cdall checksrc-all.pl checksrc.pl cmakelint.sh completion.pl contributors.sh contrithanks.sh coverage.sh delta dmaketgz extract-unit-protos firefox-db2pem.sh installcheck.sh maketgz managen mdlinkcheck mk-ca-bundle.pl mk-unity.pl nroff2cd perlcheck.sh pythonlint.sh randdisable release-notes.pl release-tools.sh schemetable.c singleuse.pl spacecheck.pl top-complexity top-length verify-release wcurl
src
toolx tool_time.c tool_time.h
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc config2setopts.c config2setopts.h curl.rc curlinfo.c mk-file-embed.pl mkhelp.pl slist_wc.c slist_wc.h terminal.c terminal.h tool_cb_dbg.c tool_cb_dbg.h tool_cb_hdr.c tool_cb_hdr.h tool_cb_prg.c tool_cb_prg.h tool_cb_rea.c tool_cb_rea.h tool_cb_see.c tool_cb_see.h tool_cb_soc.c tool_cb_soc.h tool_cb_wrt.c tool_cb_wrt.h tool_cfgable.c tool_cfgable.h tool_dirhie.c tool_dirhie.h tool_doswin.c tool_doswin.h tool_easysrc.c tool_easysrc.h tool_filetime.c tool_filetime.h tool_findfile.c tool_findfile.h tool_formparse.c tool_formparse.h tool_getparam.c tool_getparam.h tool_getpass.c tool_getpass.h tool_help.c tool_help.h tool_helpers.c tool_helpers.h tool_hugehelp.h tool_ipfs.c tool_ipfs.h tool_libinfo.c tool_libinfo.h tool_listhelp.c tool_main.c tool_main.h tool_msgs.c tool_msgs.h tool_operate.c tool_operate.h tool_operhlp.c tool_operhlp.h tool_paramhlp.c tool_paramhlp.h tool_parsecfg.c tool_parsecfg.h tool_progress.c tool_progress.h tool_sdecls.h tool_setopt.c tool_setopt.h tool_setup.h tool_ssls.c tool_ssls.h tool_stderr.c tool_stderr.h tool_urlglob.c tool_urlglob.h tool_util.c tool_util.h tool_version.h tool_vms.c tool_vms.h tool_writeout.c tool_writeout.h tool_writeout_json.c tool_writeout_json.h tool_xattr.c tool_xattr.h var.c var.h
tests
certs .gitignore CMakeLists.txt Makefile.am Makefile.inc genserv.pl srp-verifier-conf srp-verifier-db test-ca.cnf test-ca.prm test-client-cert.prm test-client-eku-only.prm test-localhost-san-first.prm test-localhost-san-last.prm test-localhost.nn.prm test-localhost.prm test-localhost0h.prm
cmake CMakeLists.txt test.c test.cpp test.sh
data .gitignore DISABLED Makefile.am data-xml1 data1400.c data1401.c data1402.c data1403.c data1404.c data1405.c data1406.c data1407.c data1420.c data1461.txt data1463.txt data1465.c data1481.c data1705-1.md data1705-2.md data1705-3.md data1705-4.md data1705-stdout.1 data1706-1.md data1706-2.md data1706-3.md data1706-4.md data1706-stdout.txt data320.html test1 test10 test100 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 test1008 test1009 test101 test1010 test1011 test1012 test1013 test1014 test1015 test1016 test1017 test1018 test1019 test102 test1020 test1021 test1022 test1023 test1024 test1025 test1026 test1027 test1028 test1029 test103 test1030 test1031 test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 test104 test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 test1048 test1049 test105 test1050 test1051 test1052 test1053 test1054 test1055 test1056 test1057 test1058 test1059 test106 test1060 test1061 test1062 test1063 test1064 test1065 test1066 test1067 test1068 test1069 test107 test1070 test1071 test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 test108 test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 test1088 test1089 test109 test1090 test1091 test1092 test1093 test1094 test1095 test1096 test1097 test1098 test1099 test11 test110 test1100 test1101 test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 test111 test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 test112 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 test1128 test1129 test113 test1130 test1131 test1132 test1133 test1134 test1135 test1136 test1137 test1138 test1139 test114 test1140 test1141 test1142 test1143 test1144 test1145 test1146 test1147 test1148 test1149 test115 test1150 test1151 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 test116 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 test1168 test1169 test117 test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 test1178 test1179 test118 test1180 test1181 test1182 test1183 test1184 test1185 test1186 test1187 test1188 test1189 test119 test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 test1199 test12 test120 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 test1208 test1209 test121 test1210 test1211 test1212 test1213 test1214 test1215 test1216 test1217 test1218 test1219 test122 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 test1228 test1229 test123 test1230 test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 test124 test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 test1248 test1249 test125 test1250 test1251 test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 test126 test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 test1268 test1269 test127 test1270 test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 test1279 test128 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 test1288 test1289 test129 test1290 test1291 test1292 test1293 test1294 test1295 test1296 test1297 test1298 test1299 test13 test130 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 test1309 test131 test1310 test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 test132 test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 test133 test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 test134 test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 test1348 test1349 test135 test1350 test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 test136 test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 test137 test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 test138 test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 test1388 test1389 test139 test1390 test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 test14 test140 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 test141 test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 test1418 test1419 test142 test1420 test1421 test1422 test1423 test1424 test1425 test1426 test1427 test1428 test1429 test143 test1430 test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 test144 test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 test145 test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 test146 test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 test1468 test1469 test147 test1470 test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 test1479 test148 test1480 test1481 test1482 test1483 test1484 test1485 test1486 test1487 test1488 test1489 test149 test1490 test1491 test1492 test1493 test1494 test1495 test1496 test1497 test1498 test1499 test15 test150 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 test1508 test1509 test151 test1510 test1511 test1512 test1513 test1514 test1515 test1516 test1517 test1518 test1519 test152 test1520 test1521 test1522 test1523 test1524 test1525 test1526 test1527 test1528 test1529 test153 test1530 test1531 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 test154 test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 test1548 test1549 test155 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 test1558 test1559 test156 test1560 test1561 test1562 test1563 test1564 test1565 test1566 test1567 test1568 test1569 test157 test1570 test1571 test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 test158 test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 test1589 test159 test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 test1598 test1599 test16 test160 test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 test1608 test1609 test161 test1610 test1611 test1612 test1613 test1614 test1615 test1616 test1617 test1618 test1619 test162 test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 test163 test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 test1638 test1639 test164 test1640 test1641 test1642 test1643 test1644 test1645 test165 test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 test1658 test1659 test166 test1660 test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 test1669 test167 test1670 test1671 test1672 test1673 test1674 test1675 test1676 test168 test1680 test1681 test1682 test1683 test1684 test1685 test169 test17 test170 test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 test1708 test1709 test171 test1710 test1711 test1712 test1713 test1714 test1715 test172 test1720 test1721 test173 test174 test175 test176 test177 test178 test179 test18 test180 test1800 test1801 test1802 test181 test182 test183 test184 test1847 test1848 test1849 test185 test1850 test1851 test186 test187 test188 test189 test19 test190 test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 test1908 test1909 test191 test1910 test1911 test1912 test1913 test1914 test1915 test1916 test1917 test1918 test1919 test192 test1920 test1921 test193 test1933 test1934 test1935 test1936 test1937 test1938 test1939 test194 test1940 test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 test195 test1955 test1956 test1957 test1958 test1959 test196 test1960 test1964 test1965 test1966 test197 test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 test1978 test1979 test198 test1980 test1981 test1982 test1983 test1984 test199 test2 test20 test200 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 test2008 test2009 test201 test2010 test2011 test2012 test2013 test2014 test202 test2023 test2024 test2025 test2026 test2027 test2028 test2029 test203 test2030 test2031 test2032 test2033 test2034 test2035 test2037 test2038 test2039 test204 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 test2048 test2049 test205 test2050 test2051 test2052 test2053 test2054 test2055 test2056 test2057 test2058 test2059 test206 test2060 test2061 test2062 test2063 test2064 test2065 test2066 test2067 test2068 test2069 test207 test2070 test2071 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 test208 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 test2088 test2089 test209 test2090 test2091 test2092 test21 test210 test2100 test2101 test2102 test2103 test2104 test211 test212 test213 test214 test215 test216 test217 test218 test219 test22 test220 test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 test221 test222 test223 test224 test225 test226 test227 test228 test229 test23 test230 test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 test2309 test231 test232 test233 test234 test235 test236 test237 test238 test239 test24 test240 test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 test2408 test2409 test241 test2410 test2411 test242 test243 test244 test245 test246 test247 test248 test249 test25 test250 test2500 test2501 test2502 test2503 test2504 test2505 test2506 test251 test252 test253 test254 test255 test256 test257 test258 test259 test26 test260 test2600 test2601 test2602 test2603 test2604 test2605 test261 test262 test263 test264 test265 test266 test267 test268 test269 test27 test270 test2700 test2701 test2702 test2703 test2704 test2705 test2706 test2707 test2708 test2709 test271 test2710 test2711 test2712 test2713 test2714 test2715 test2716 test2717 test2718 test2719 test272 test2720 test2721 test2722 test2723 test273 test274 test275 test276 test277 test278 test279 test28 test280 test281 test282 test283 test284 test285 test286 test287 test288 test289 test29 test290 test291 test292 test293 test294 test295 test296 test297 test298 test299 test3 test30 test300 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 test3008 test3009 test301 test3010 test3011 test3012 test3013 test3014 test3015 test3016 test3017 test3018 test3019 test302 test3020 test3021 test3022 test3023 test3024 test3025 test3026 test3027 test3028 test3029 test303 test3030 test3031 test3032 test3033 test3034 test3035 test3036 test304 test305 test306 test307 test308 test309 test31 test310 test3100 test3101 test3102 test3103 test3104 test3105 test3106 test311 test312 test313 test314 test315 test316 test317 test318 test319 test32 test320 test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 test3209 test321 test3210 test3211 test3212 test3213 test3214 test3215 test3216 test3217 test3218 test3219 test322 test3220 test323 test324 test325 test326 test327 test328 test329 test33 test330 test3300 test3301 test3302 test331 test332 test333 test334 test335 test336 test337 test338 test339 test34 test340 test341 test342 test343 test344 test345 test346 test347 test348 test349 test35 test350 test351 test352 test353 test354 test355 test356 test357 test358 test359 test36 test360 test361 test362 test363 test364 test365 test366 test367 test368 test369 test37 test370 test371 test372 test373 test374 test375 test376 test378 test379 test38 test380 test381 test383 test384 test385 test386 test387 test388 test389 test39 test390 test391 test392 test393 test394 test395 test396 test397 test398 test399 test4 test40 test400 test4000 test4001 test401 test402 test403 test404 test405 test406 test407 test408 test409 test41 test410 test411 test412 test413 test414 test415 test416 test417 test418 test419 test42 test420 test421 test422 test423 test424 test425 test426 test427 test428 test429 test43 test430 test431 test432 test433 test434 test435 test436 test437 test438 test439 test44 test440 test441 test442 test443 test444 test445 test446 test447 test448 test449 test45 test450 test451 test452 test453 test454 test455 test456 test457 test458 test459 test46 test460 test461 test462 test463 test467 test468 test469 test47 test470 test471 test472 test473 test474 test475 test476 test477 test478 test479 test48 test480 test481 test482 test483 test484 test485 test486 test487 test488 test489 test49 test490 test491 test492 test493 test494 test495 test496 test497 test498 test499 test5 test50 test500 test501 test502 test503 test504 test505 test506 test507 test508 test509 test51 test510 test511 test512 test513 test514 test515 test516 test517 test518 test519 test52 test520 test521 test522 test523 test524 test525 test526 test527 test528 test529 test53 test530 test531 test532 test533 test534 test535 test536 test537 test538 test539 test54 test540 test541 test542 test543 test544 test545 test546 test547 test548 test549 test55 test550 test551 test552 test553 test554 test555 test556 test557 test558 test559 test56 test560 test561 test562 test563 test564 test565 test566 test567 test568 test569 test57 test570 test571 test572 test573 test574 test575 test576 test577 test578 test579 test58 test580 test581 test582 test583 test584 test585 test586 test587 test588 test589 test59 test590 test591 test592 test593 test594 test595 test596 test597 test598 test599 test6 test60 test600 test601 test602 test603 test604 test605 test606 test607 test608 test609 test61 test610 test611 test612 test613 test614 test615 test616 test617 test618 test619 test62 test620 test621 test622 test623 test624 test625 test626 test627 test628 test629 test63 test630 test631 test632 test633 test634 test635 test636 test637 test638 test639 test64 test640 test641 test642 test643 test644 test645 test646 test647 test648 test649 test65 test650 test651 test652 test653 test654 test655 test656 test658 test659 test66 test660 test661 test662 test663 test664 test665 test666 test667 test668 test669 test67 test670 test671 test672 test673 test674 test675 test676 test677 test678 test679 test68 test680 test681 test682 test683 test684 test685 test686 test687 test688 test689 test69 test690 test691 test692 test693 test694 test695 test696 test697 test698 test699 test7 test70 test700 test701 test702 test703 test704 test705 test706 test707 test708 test709 test71 test710 test711 test712 test713 test714 test715 test716 test717 test718 test719 test72 test720 test721 test722 test723 test724 test725 test726 test727 test728 test729 test73 test730 test731 test732 test733 test734 test735 test736 test737 test738 test739 test74 test740 test741 test742 test743 test744 test745 test746 test747 test748 test749 test75 test750 test751 test752 test753 test754 test755 test756 test757 test758 test759 test76 test760 test761 test762 test763 test764 test765 test766 test767 test768 test769 test77 test770 test771 test772 test773 test774 test775 test776 test777 test778 test779 test78 test780 test781 test782 test783 test784 test785 test786 test787 test788 test789 test79 test790 test791 test792 test793 test794 test795 test796 test797 test798 test799 test8 test80 test800 test801 test802 test803 test804 test805 test806 test807 test808 test809 test81 test810 test811 test812 test813 test814 test815 test816 test817 test818 test819 test82 test820 test821 test822 test823 test824 test825 test826 test827 test828 test829 test83 test830 test831 test832 test833 test834 test835 test836 test837 test838 test839 test84 test840 test841 test842 test843 test844 test845 test846 test847 test848 test849 test85 test850 test851 test852 test853 test854 test855 test856 test857 test858 test859 test86 test860 test861 test862 test863 test864 test865 test866 test867 test868 test869 test87 test870 test871 test872 test873 test874 test875 test876 test877 test878 test879 test88 test880 test881 test882 test883 test884 test885 test886 test887 test888 test889 test89 test890 test891 test892 test893 test894 test895 test896 test897 test898 test899 test9 test90 test900 test901 test902 test903 test904 test905 test906 test907 test908 test909 test91 test910 test911 test912 test913 test914 test915 test916 test917 test918 test919 test92 test920 test921 test922 test923 test924 test925 test926 test927 test928 test929 test93 test930 test931 test932 test933 test934 test935 test936 test937 test938 test939 test94 test940 test941 test942 test943 test944 test945 test946 test947 test948 test949 test95 test950 test951 test952 test953 test954 test955 test956 test957 test958 test959 test96 test960 test961 test962 test963 test964 test965 test966 test967 test968 test969 test97 test970 test971 test972 test973 test974 test975 test976 test977 test978 test979 test98 test980 test981 test982 test983 test984 test985 test986 test987 test988 test989 test99 test990 test991 test992 test993 test994 test995 test996 test997 test998 test999
http
testenv
mod_curltest .gitignore mod_curltest.c
__init__.py caddy.py certs.py client.py curl.py dante.py dnsd.py env.py httpd.py nghttpx.py ports.py sshd.py vsftpd.py ws_echo_server.py
.gitignore CMakeLists.txt Makefile.am config.ini.in conftest.py requirements.txt scorecard.py test_01_basic.py test_02_download.py test_03_goaway.py test_04_stuttered.py test_05_errors.py test_06_eyeballs.py test_07_upload.py test_08_caddy.py test_09_push.py test_10_proxy.py test_11_unix.py test_12_reuse.py test_13_proxy_auth.py test_14_auth.py test_15_tracing.py test_16_info.py test_17_ssl_use.py test_18_methods.py test_19_shutdown.py test_20_websockets.py test_21_resolve.py test_22_httpsrr.py test_30_vsftpd.py test_31_vsftpds.py test_32_ftps_vsftpd.py test_40_socks.py test_50_scp.py test_51_sftp.py
libtest .gitignore CMakeLists.txt Makefile.am Makefile.inc cli_ftp_upload.c cli_h2_pausing.c cli_h2_serverpush.c cli_h2_upgrade_extreme.c cli_hx_download.c cli_hx_upload.c cli_tls_session_reuse.c cli_upload_pausing.c cli_ws_data.c cli_ws_pingpong.c first.c first.h lib1156.c lib1301.c lib1308.c lib1485.c lib1500.c lib1501.c lib1502.c lib1506.c lib1507.c lib1508.c lib1509.c lib1510.c lib1511.c lib1512.c lib1513.c lib1514.c lib1515.c lib1517.c lib1518.c lib1520.c lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c lib1545.c lib1549.c lib1550.c lib1551.c lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c lib1559.c lib1560.c lib1564.c lib1565.c lib1567.c lib1568.c lib1569.c lib1571.c lib1576.c lib1582.c lib1587.c lib1588.c lib1589.c lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c lib1598.c lib1599.c lib1662.c lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c lib1933.c lib1934.c lib1935.c lib1936.c lib1937.c lib1938.c lib1939.c lib1940.c lib1945.c lib1947.c lib1948.c lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c lib1964.c lib1965.c lib1970.c lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c lib2023.c lib2032.c lib2082.c lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c lib2402.c lib2404.c lib2405.c lib2502.c lib2504.c lib2505.c lib2506.c lib2700.c lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c lib3207.c lib3208.c lib500.c lib501.c lib502.c lib503.c lib504.c lib505.c lib506.c lib507.c lib508.c lib509.c lib510.c lib511.c lib512.c lib513.c lib514.c lib515.c lib516.c lib517.c lib518.c lib519.c lib520.c lib521.c lib523.c lib524.c lib525.c lib526.c lib530.c lib533.c lib536.c lib537.c lib539.c lib540.c lib541.c lib542.c lib543.c lib544.c lib547.c lib549.c lib552.c lib553.c lib554.c lib555.c lib556.c lib557.c lib558.c lib559.c lib560.c lib562.c lib564.c lib566.c lib567.c lib568.c lib569.c lib570.c lib571.c lib572.c lib573.c lib574.c lib575.c lib576.c lib578.c lib579.c lib582.c lib583.c lib586.c lib589.c lib590.c lib591.c lib597.c lib598.c lib599.c lib643.c lib650.c lib651.c lib652.c lib653.c lib654.c lib655.c lib658.c lib659.c lib661.c lib666.c lib667.c lib668.c lib670.c lib674.c lib676.c lib677.c lib678.c lib694.c lib695.c lib751.c lib753.c lib757.c lib758.c lib766.c memptr.c mk-lib1521.pl test1013.pl test1022.pl test307.pl test610.pl test613.pl testtrace.c testtrace.h testutil.c testutil.h unitcheck.h
server .checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc dnsd.c first.c first.h getpart.c mqttd.c resolve.c rtspd.c sockfilt.c socksd.c sws.c tftpd.c util.c
tunit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.c
unit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md unit1300.c unit1302.c unit1303.c unit1304.c unit1305.c unit1307.c unit1309.c unit1323.c unit1330.c unit1395.c unit1396.c unit1397.c unit1398.c unit1399.c unit1600.c unit1601.c unit1602.c unit1603.c unit1605.c unit1606.c unit1607.c unit1608.c unit1609.c unit1610.c unit1611.c unit1612.c unit1614.c unit1615.c unit1616.c unit1620.c unit1625.c unit1626.c unit1627.c unit1636.c unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c unit1666.c unit1667.c unit1668.c unit1669.c unit1674.c unit1675.c unit1676.c unit1979.c unit1980.c unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c unit3200.c unit3205.c unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c unit3219.c unit3300.c unit3301.c unit3302.c
.gitignore CMakeLists.txt Makefile.am allversions.pm appveyor.pm azure.pm config.in configurehelp.pm.in devtest.pl dictserver.py directories.pm ech_combos.py ech_tests.sh ftpserver.pl getpart.pm globalconfig.pm http-server.pl http2-server.pl http3-server.pl memanalyze.pl memanalyzer.pm negtelnetserver.py nghttpx.conf pathhelp.pm processhelp.pm requirements.txt rtspserver.pl runner.pm runtests.pl secureserver.pl serverhelp.pm servers.pm smbserver.py sshhelp.pm sshserver.pl test1119.pl test1135.pl test1139.pl test1140.pl test1165.pl test1167.pl test1173.pl test1175.pl test1177.pl test1222.pl test1275.pl test1276.pl test1477.pl test1486.pl test1488.pl test1544.pl test1707.pl test745.pl test971.pl testcurl.pl testutil.pm tftpserver.pl util.py valgrind.pm valgrind.supp
.clang-tidy.yml .dir-locals.el .editorconfig .git-blame-ignore-revs .gitattributes .gitignore .mailmap CHANGES.md CMakeLists.txt COPYING Dockerfile GIT-INFO.md Makefile.am README README.md RELEASE-NOTES REUSE.toml SECURITY.md acinclude.m4 appveyor.sh appveyor.yml configure.ac curl-config.in libcurl.pc.in renovate.json
examples .env config.ini crypto_test.lua env_test.lua fs_example.lua http_server.lua https_test.lua ini_example.lua json.lua log.lua path_fs_example.lua process_example.lua request_download.lua request_test.lua run_all.lua sqlite_example.lua sqlite_http_template.lua stash_test.lua template_test.lua timer.lua websocket.lua
iniparser
.github
ISSUE_TEMPLATE config.yml
workflows disable-pull-requests.yml trigger-gitlab-ci.yml
cmake JoinPaths.cmake config.cmake.in pc.in
example iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.ini
src dictionary.c dictionary.h iniparser.c iniparser.h
test
ressources
bad_ini ends_well.ini twisted-errors.ini twisted-ofkey.ini twisted-ofval.ini
good_ini empty.ini spaced.ini spaced2.ini twisted.ini
gruezi.ini old.ini quotes.ini utf8.ini
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.h
.cmake-format.py .gitignore .gitlab-ci.yml .gitmessage .travis.yml AUTHORS CMakeLists.txt FAQ-en.md FAQ-zhcn.md INSTALL LICENSE README.md compile_commands.json
jinjac
example CMakeLists.txt example.c
jinjac_test_app CMakeLists.txt jinjac_test_app.c
libjinjac
include jinjac.h
src CMakeLists.txt ast.c ast.h block_statement.c block_statement.h buffer.c buffer.h buildin.c buildin.h common.h convert.c convert.h flex_decl.h jfunction.c jfunction.h jinja_expression.l jinja_expression.y jinjac_parse.c jinjac_parse.h jinjac_stream.c jinjac_stream.h jlist.c jlist.h jobject.c jobject.h parameter.c parameter.h str_obj.c str_obj.h trace.c trace.h
CMakeLists.txt
test .gitignore CMakeLists.txt autotest.rb test_01.expected test_01.jinja test_01b.expected test_01b.jinja test_01c.expected test_01c.jinja test_01d.expected test_01d.jinja test_02.expected test_02.jinja test_03.expected test_03.jinja test_04.expected test_04.jinja test_05.expected test_05.jinja test_06.expected test_06.jinja test_07.expected test_07.jinja test_08.expected test_08.jinja test_08b.expected test_08b.jinja test_09.expected test_09.jinja test_10.expected test_10.jinja test_11.expected test_11.jinja test_12.expected test_12.jinja test_13.expected test_13.jinja test_14.expected test_14.jinja test_15.expected test_15.jinja test_16.expected test_16.jinja test_17.expected test_17.jinja test_18.expected test_18.jinja test_18b.expected test_18b.jinja test_18c.expected test_18c.jinja test_19.expected test_19.jinja test_19b.expected test_19b.jinja test_19c.expected test_19c.jinja test_19d.expected test_19d.jinja test_19e.expected test_19e.jinja test_19f.expected test_19f.jinja test_20.expected test_20.jinja test_21.expected test_21.jinja test_22.expected test_22.jinja test_22a.expected test_22a.jinja test_22b.expected test_22b.jinja test_23.expected test_23.jinja test_24.expected test_24.jinja
.gitignore CMakeLists.txt LICENSE.txt README.md build_coverage.sh build_debug.sh build_release.sh cppcheck_analysis.sh
libev Changes LICENSE Makefile Makefile.am Makefile.in README Symbols.ev Symbols.event aclocal.m4 autogen.sh compile config.guess config.h config.h.in config.status config.sub configure configure.ac depcomp ev++.h ev.3 ev.c ev.h ev.pod ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_vars.h ev_win32.c ev_wrap.h event.c event.h install-sh libev.m4 libtool ltmain.sh missing mkinstalldirs stamp-h1
luajit
doc
img contact.png
bluequad-print.css bluequad.css contact.html ext_buffer.html ext_c_api.html ext_ffi.html ext_ffi_api.html ext_ffi_semantics.html ext_ffi_tutorial.html ext_jit.html ext_profiler.html extensions.html install.html luajit.html running.html
dynasm dasm_arm.h dasm_arm.lua dasm_arm64.h dasm_arm64.lua dasm_mips.h dasm_mips.lua dasm_mips64.lua dasm_ppc.h dasm_ppc.lua dasm_proto.h dasm_x64.lua dasm_x86.h dasm_x86.lua dynasm.lua
etc luajit.1 luajit.pc
src
host .gitignore README buildvm.c buildvm.h buildvm_asm.c buildvm_fold.c buildvm_lib.c buildvm_libbc.h buildvm_peobj.c genlibbc.lua genminilua.lua genversion.lua minilua.c
jit .gitignore bc.lua bcsave.lua dis_arm.lua dis_arm64.lua dis_arm64be.lua dis_mips.lua dis_mips64.lua dis_mips64el.lua dis_mips64r6.lua dis_mips64r6el.lua dis_mipsel.lua dis_ppc.lua dis_x64.lua dis_x86.lua dump.lua p.lua v.lua zone.lua
.gitignore Makefile Makefile.dep lauxlib.h lib_aux.c lib_base.c lib_bit.c lib_buffer.c lib_debug.c lib_ffi.c lib_init.c lib_io.c lib_jit.c lib_math.c lib_os.c lib_package.c lib_string.c lib_table.c lj_alloc.c lj_alloc.h lj_api.c lj_arch.h lj_asm.c lj_asm.h lj_asm_arm.h lj_asm_arm64.h lj_asm_mips.h lj_asm_ppc.h lj_asm_x86.h lj_assert.c lj_bc.c lj_bc.h lj_bcdump.h lj_bcread.c lj_bcwrite.c lj_buf.c lj_buf.h lj_carith.c lj_carith.h lj_ccall.c lj_ccall.h lj_ccallback.c lj_ccallback.h lj_cconv.c lj_cconv.h lj_cdata.c lj_cdata.h lj_char.c lj_char.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_crecord.c lj_crecord.h lj_ctype.c lj_ctype.h lj_debug.c lj_debug.h lj_def.h lj_dispatch.c lj_dispatch.h lj_emit_arm.h lj_emit_arm64.h lj_emit_mips.h lj_emit_ppc.h lj_emit_x86.h lj_err.c lj_err.h lj_errmsg.h lj_ff.h lj_ffrecord.c lj_ffrecord.h lj_frame.h lj_func.c lj_func.h lj_gc.c lj_gc.h lj_gdbjit.c lj_gdbjit.h lj_ir.c lj_ir.h lj_ircall.h lj_iropt.h lj_jit.h lj_lex.c lj_lex.h lj_lib.c lj_lib.h lj_load.c lj_mcode.c lj_mcode.h lj_meta.c lj_meta.h lj_obj.c lj_obj.h lj_opt_dce.c lj_opt_fold.c lj_opt_loop.c lj_opt_mem.c lj_opt_narrow.c lj_opt_sink.c lj_opt_split.c lj_parse.c lj_parse.h lj_prng.c lj_prng.h lj_profile.c lj_profile.h lj_record.c lj_record.h lj_serialize.c lj_serialize.h lj_snap.c lj_snap.h lj_state.c lj_state.h lj_str.c lj_str.h lj_strfmt.c lj_strfmt.h lj_strfmt_num.c lj_strscan.c lj_strscan.h lj_tab.c lj_tab.h lj_target.h lj_target_arm.h lj_target_arm64.h lj_target_mips.h lj_target_ppc.h lj_target_x86.h lj_trace.c lj_trace.h lj_traceerr.h lj_udata.c lj_udata.h lj_vm.h lj_vmevent.c lj_vmevent.h lj_vmmath.c ljamalg.c lua.h lua.hpp luaconf.h luajit.c luajit_rolling.h lualib.h msvcbuild.bat nxbuild.bat ps4build.bat ps5build.bat psvitabuild.bat vm_arm.dasc vm_arm64.dasc vm_mips.dasc vm_mips64.dasc vm_ppc.dasc vm_x64.dasc vm_x86.dasc xb1build.bat xedkbuild.bat
.gitattributes .gitignore .relver COPYRIGHT Makefile README
sqlite shell.c sqlite3.c sqlite3.h sqlite3ext.h
wolfssl
.github
ISSUE_TEMPLATE bug_report.yaml other.yaml
actions
install-apt-deps action.yml
scripts
zephyr-4.x external_libc.conf zephyr-test.sh
openssl-ech.sh tls-anvil-test.sh
workflows
disabled haproxy.yml hitch.yml hostap.yml
hostap-files
configs
07c9f183ea744ac04585fb6dd10220c75a5e2e74 hostapd.config tests wpa_supplicant.config
b607d2723e927a3446d89aed813f1aa6068186bb hostapd.config tests wpa_supplicant.config
hostap_2_10 extra.patch hostapd.config tests wpa_supplicant.config
Makefile README dbus-wpa_supplicant.conf
ada.yml arduino.yml async-examples.yml async.yml atecc608-sim.yml bind.yml cmake-autoconf.yml cmake.yml codespell.yml coverity-scan-fixes.yml cryptocb-only.yml curl.yml cyrus-sasl.yml disable-pk-algs.yml docker-Espressif.yml docker-OpenWrt.yml emnet-nonblock.yml fil-c.yml freertos-mem-track.yml gencertbuf.yml grpc.yml haproxy.yml hostap-vm.yml intelasm-c-fallback.yml ipmitool.yml jwt-cpp.yml krb5.yml libspdm.yml libssh2.yml libvncserver.yml linuxkm.yml macos-apple-native-cert-validation.yml mbedtls.sh mbedtls.yml membrowse-comment.yml membrowse-onboard.yml membrowse-report.yml memcached.sh memcached.yml mono.yml mosquitto.yml msmtp.yml msys2.yml multi-arch.yml multi-compiler.yml net-snmp.yml nginx.yml no-malloc.yml no-tls.yml nss.sh nss.yml ntp.yml ocsp.yml openldap.yml openssh.yml openssl-ech.yml opensslcoexist.yml openvpn.yml os-check.yml packaging.yml pam-ipmi.yml pq-all.yml pr-commit-check.yml psk.yml puf.yml python.yml rng-tools.yml rust-wrapper.yml se050-sim.yml smallStackSize.yml socat.yml softhsm.yml sssd.yml stm32-sim.yml stsafe-a120-sim.yml stunnel.yml symbol-prefixes.yml threadx.yml tls-anvil.yml trackmemory.yml watcomc.yml win-csharp-test.yml wolfCrypt-Wconversion.yml wolfboot-integration.yml wolfsm.yml xcode.yml zephyr-4.x.yml zephyr.yml
PULL_REQUEST_TEMPLATE.md SECURITY.md membrowse-targets.json
Docker
OpenWrt Dockerfile README.md runTests.sh
packaging
debian Dockerfile
fedora Dockerfile
wolfCLU Dockerfile README.md
yocto Dockerfile buildAndPush.sh
Dockerfile Dockerfile.cross-compiler README.md buildAndPush.sh include.am run.sh
IDE
ARDUINO
sketches
wolfssl_client README.md
wolfssl_server README.md
wolfssl_version README.md
README.md
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.h
AURIX Cpu0_Main.c README.md include.am user_settings.h wolf_main.c
Android Android.bp README.md include.am user_settings.h
CRYPTOCELL README.md include.am main.c user_settings.h
CSBENCH include.am user_settings.h
ECLIPSE
DEOS
deos_wolfssl .options
README.md deos_malloc.c include.am tls_wolfssl.c tls_wolfssl.h user_settings.h
MICRIUM README.md client_wolfssl.c client_wolfssl.h include.am server_wolfssl.c server_wolfssl.h user_settings.h wolfsslRunTests.c
RTTHREAD README.md include.am user_settings.h wolfssl_test.c
SIFIVE README.md include.am
Espressif
ESP-IDF
examples
template
VisualGDB wolfssl_template_IDF_v5.1_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_benchmark
VisualGDB wolfssl_benchmark_IDF_v4.4_ESP32.sln wolfssl_benchmark_IDF_v4.4_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32.sln wolfssl_benchmark_IDF_v5_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32C3.sln wolfssl_benchmark_IDF_v5_ESP32C3.vgdbproj wolfssl_benchmark_IDF_v5_ESP32S3.sln wolfssl_benchmark_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_client
VisualGDB README.md wolfssl_client_IDF_v5_ESP32.sln wolfssl_client_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include client-tls.h main.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild client-tls.c component.mk main.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbproj
wolfssl_server
VisualGDB README.md wolfssl_server_IDF_v5_ESP32.sln wolfssl_server_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h server-tls.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild component.mk main.c server-tls.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbproj
wolfssl_test
VisualGDB wolfssl_test-IDF_v5_ESP32.sln wolfssl_test-IDF_v5_ESP32.vgdbproj wolfssl_test-IDF_v5_ESP32C3.sln wolfssl_test-IDF_v5_ESP32C3.vgdbproj wolfssl_test-IDF_v5_ESP32C6.sln wolfssl_test-IDF_v5_ESP32C6.vgdbproj wolfssl_test_IDF_v5_ESP32S3.sln wolfssl_test_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32 sdkconfig.defaults.esp32c3 sdkconfig.defaults.esp32c6 sdkconfig.defaults.esp32h2 sdkconfig.defaults.esp32s2 sdkconfig.defaults.esp32s3 sdkconfig.defaults.esp8266 testAll.sh testMonitor.sh wolfssl_test_ESP8266.sln wolfssl_test_ESP8266.vgdbproj
wolfssl_test_idf
VisualGDB VisualGDB_wolfssl_test_idf.sln VisualGDB_wolfssl_test_idf.vgdbproj
main CMakeLists.txt Kconfig.projbuild component.mk main.c main_wip.c.ex time_helper.c time_helper.h
CMakeLists.txt Kconfig.projbuild README.md component.mk sdkconfig.defaults
README.md
libs CMakeLists.txt README.md component.mk tigard.cfg
test CMakeLists.txt README.md component.mk test_wolfssl.c
README.md README_32se.md UPDATE.md compileAllExamples.sh dummy_config_h dummy_test_paths.h setup.sh setup_win.bat user_settings.h
README.md include.am
GCC-ARM
Header user_settings.h
Source armtarget.c benchmark_main.c test_main.c tls_client.c tls_server.c wolf_main.c
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ld
Gaisler-BCC README.md include.am
HEXAGON
DSP Makefile wolfssl_dsp.idl
Makefile README.md build.sh ecc-verify-benchmark.c ecc-verify.c include.am user_settings.h
HEXIWEAR
wolfSSL_HW .cwGeneratedFileSetLog user_settings.h
IAR-EWARM
Projects
benchmark benchmark-main.c current_time.c wolfCrypt-benchmark.ewd wolfCrypt-benchmark.ewp
common minimum-startup.c wolfssl.icf
lib wolfSSL-Lib.ewd wolfSSL-Lib.ewp
test test-main.c wolfCrypt-test.ewd wolfCrypt-test.ewp
user_settings.h wolfssl.eww
embOS
SAMV71_XULT
embOS_SAMV71_XULT_Linker_Script samv71q21_wolfssl.icf
embOS_SAMV71_XULT_user_settings user_settings.h user_settings_simple_example.h user_settings_verbose_example.h
embOS_wolfcrypt_benchmark_SAMV71_XULT
Application runBenchmarks.c
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewp
embOS_wolfcrypt_lib_SAMV71_XULT README_wolfcrypt_lib wolfcrypt_lib.ewd wolfcrypt_lib.ewp
embOS_wolfcrypt_test_SAMV71_XULT
Application runWolfcryptTests.c
README_wolfcrypt_test wolfcrypt_test.ewd wolfcrypt_test.ewp
README_SAMV71
custom_port
custom_port_Linker_Script samv71q21_wolfssl.icf
custom_port_user_settings user_settings.h
wolfcrypt_benchmark_custom_port
Application runBenchmarks.c
wolfcrypt_test_custom_port
Application runWolfcryptTests.c
README_custom_port
extract_trial_here README_extract_trial_here
README
.gitignore README
IAR-MSP430 Makefile README.md include.am main.c user_settings.h
INTIME-RTOS Makefile README.md include.am libwolfssl.c libwolfssl.vcxproj user_settings.h wolfExamples.c wolfExamples.h wolfExamples.sln wolfExamples.vcxproj wolfssl-lib.sln wolfssl-lib.vcxproj
Infineon README.md include.am user_settings.h
KDS
config user_settings.h
include.am
LINUX-SGX README.md build.sh clean.sh include.am sgx_t_static.mk
LPCXPRESSO
lib_wolfssl lpc_18xx_port.c user_settings.h
wolf_example
src lpc_18xx_startup.c wolfssl_example.c
readme.txt
README.md
M68K
benchmark Makefile main.cpp
testwolfcrypt Makefile main.cpp
Makefile README.md include.am user_settings.h
MCUEXPRESSO
RT1170 fsl_caam_c.patch fsl_caam_h.patch user_settings.h
benchmark
source run_benchmark.c
wolfssl liblinks.xml
README.md include.am user_settings.h wolfcrypt_test.c
MDK-ARM
LPC43xx time-LCP43xx.c
MDK-ARM
wolfSSL Retarget.c cert_data.c cert_data.h config-BARE-METAL.h config-FS.h config-RTX-TCP-FS.h config-WOLFLIB.h main.c shell.c time-CortexM3-4.c time-dummy.c wolfssl_MDK_ARM.c wolfssl_MDK_ARM.h
STM32F2xx_StdPeriph_Lib time-STM32F2xx.c
MDK5-ARM
Conf user_settings.h
Inc wolfssl_MDK_ARM.h
Projects
CryptBenchmark Abstract.txt CryptBenchmark.sct CryptBenchmark.uvoptx CryptBenchmark.uvprojx main.c
CryptTest Abstract.txt CryptTest.sct CryptTest.uvoptx CryptTest.uvprojx main.c
EchoClient Abstract.txt EchoClient.uvoptx EchoClient.uvprojx main.c wolfssl-link.sct
EchoServer Abstract.txt EchoServer.uvoptx EchoServer.uvprojx main.c wolfssl-link.sct
SimpleClient Abstract.txt SimpleClient.uvoptx SimpleClient.uvprojx main.c wolfssl-link.sct
SimpleServer Abstract.txt SimpleServer.uvoptx SimpleServer.uvprojx main.c wolfssl-link.sct
wolfSSL-Full Abstract.txt main.c shell.c time-CortexM3-4.c wolfsslFull.uvoptx wolfsslFull.uvprojx
wolfSSL-Lib Abstract.txt wolfSSL-Lib.uvoptx wolfSSL-Lib.uvprojx
Src ssl-dummy.c
README.md include.am
MPLABX16
wolfcrypt_test.X
nbproject
private configurations.xml private.xml
configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
README.md include.am main.c user_settings.h
MQX Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.h
MSVS-2019-AZSPHERE
client client.c client.h
server server.c server.h
shared util.h
wolfssl_new_azsphere
HardwareDefinitions
avnet_mt3620_sk
inc
hw template_appliance.h
template_appliance.json
mt3620_rdb
inc
hw template_appliance.h
template_appliance.json
seeed_mt3620_mdb
inc
hw template_appliance.h
template_appliance.json
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.c
README.md include.am user_settings.h
MYSQL CMakeLists_wolfCrypt.txt CMakeLists_wolfSSL.txt do.sh
NDS README.md
NETOS Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.c
OPENSTM32 README.md
PlatformIO
examples
wolfssl_benchmark
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspace
wolfssl_test
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_test.code-workspace
README.md wolfssl_platformio.code-workspace
README.md include.am
QNX
CAAM-DRIVER Makefile
example-client Makefile client-tls.c
example-cmac Makefile cmac-test.c
example-server Makefile server-tls.c
testwolfcrypt Makefile
wolfssl Makefile user_settings.h
README.md include.am
RISCV
SIFIVE-HIFIVE1 Makefile README.md include.am main.c user_settings.h
SIFIVE-UNLEASHED README.md include.am
include.am
ROWLEY-CROSSWORKS-ARM Kinetis_FlashPlacement.xml README.md arm_startup.c benchmark_main.c hw.h include.am kinetis_hw.c retarget.c test_main.c user_settings.h wolfssl.hzp wolfssl_ltc.hzp
Renesas
cs+
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
t4_demo README_en.txt README_jp.txt t4_demo.mtpj wolf_client.c wolf_demo.h wolf_main.c wolf_server.c
test test.mtpj test_main.c
wolfssl_lib wolfssl_lib.mtpj
README include.am
e2studio
DK-S7G2
benchmark-template
src app_entry.c
example_server-template
src app_entry.c
wolfcrypttest-template
src app_entry.c
wolfssl-template-project configuration.xml
README.md include.am user_settings.h
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
tools generate_rsa_keypair.sh genhexbuf.pl rsa_pss_sign.sh
wolfssl
src .gitkeep
wolfcrypt
src .gitkeep
README include.am
RA6M3
benchmark-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
client-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
common
ra6m3g README.md
src freertos_tcp_port.c
user_settings.h util.h
server-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
test-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl
src .gitkeep
wolfcrypt .gitkeep
README.md README_APRA6M_en.md README_APRA6M_jp.md include.am
RA6M3G README.md
RA6M4
common user_settings.h wolfssl_demo.h
test
key_data key_data.h key_data_sce.c
src
SEGGER_RTT myprint.c
common .gitignore
test_main.c wolf_client.c wolfssl_sce_unit_test.c
test_RA6M4Debug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
README.md include.am
RX65N
GR-ROSE
common strings.h unistd.h user_settings.h wolfssl_dummy.c
smc smc.scfg
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
test.rcpc test_HardwareDebug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
README_EN.md README_JP.md include.am
RSK
resource section.esi
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h
InstructionManualForExample_RSK+RX65N-2MB_EN.pdf InstructionManualForExample_RSK+RX65N-2MB_JP.pdf README_EN.md README_JP.md include.am
RX72N
EnvisionKit
Simple
common sectioninfo.esi wolfssl_dummy.c
test
src
client simple_tcp_client.c simple_tls_tsip_client.c
server simple_tcp_server.c simple_tls_server.c
test_main.c wolfssl_simple_demo.h
test.rcpc test.scfg test_HardwareDebug.launch
wolfssl wolfssl.rcpc
README_EN.md README_JP.md
resource section.esi
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.c
InstructionManualForExample_RX72N_EnvisonKit_EN.pdf InstructionManualForExample_RX72N_EnvisonKit_JP.pdf README_EN.md README_JP.md include.am
RZN2L
common user_settings.h wolfssl_demo.h
test
src
serial_io app_print.c
test wolf_client.c wolf_server.c wolfssl_rsip_unit_test.c
wolfCrypt .gitignore
wolfSSL .gitignore
local_system_init.c rzn2l_tst_thread_entry.c wolfssl_dummy.c
README.md include.am
SK-S7G2
common user_settings.h
wolfssl_lib configuration.xml
.gitignore README.md include.am
STARCORE README.txt include.am starcore_test.c user_settings.h
STM32Cube README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.h
SimplicityStudio README.md include.am test_wolf.c user_settings.h
TRUESTUDIO
wolfssl user_settings.h
README include.am
VS-ARM README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VS-AZURE-SPHERE
client app_manifest.json client.c client.h client.vcxproj
server app_manifest.json server.c server.h server.vcxproj
shared util.h
wolfcrypt_test app_manifest.json wolfcrypt_test.vcxproj
README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VisualDSP include.am user_settings.h wolf_tasks.c
WICED-STUDIO README include.am user_settings.h
WIN README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxproj
WIN-SGX ReadMe.txt include.am wolfSSL_SGX.edl wolfSSL_SGX.sln wolfSSL_SGX.vcxproj
WIN-SRTP-KDF-140-3 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WIN10 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WINCE README.md include.am user_settings.h user_settings.h.140-2-deprecated
WORKBENCH README.md include.am
XCODE
Benchmark
wolfBench
Assets.xcassets
AppIcon.appiconset Contents.json
Base.lproj LaunchScreen.storyboard Main.storyboard
AppDelegate.h AppDelegate.m Info.plist ViewController.h ViewController.m main.m
wolfBench.xcodeproj project.pbxproj
include.am
wolfssl-FIPS.xcodeproj project.pbxproj
wolfssl.xcodeproj project.pbxproj
wolfssl_testsuite.xcodeproj project.pbxproj
README.md build-for-i386.sh include.am user_settings.h
XCODE-FIPSv2
macOS-C++
Intel user_settings.h
M1 user_settings.h
include.am user_settings.h
XCODE-FIPSv5 README include.am user_settings.h
XCODE-FIPSv6 README include.am user_settings.h
XilinxSDK
2018_2 lscript.ld
2019_2
wolfCrypt_example
src lscript.ld
wolfCrypt_example_system wolfCrypt_example_system.sprj
2022_1
wolfCrypt_FreeRTOS_example wolfCrypt_FreeRTOS_example.prj
wolfCrypt_FreeRTOS_example_system wolfCrypt_FreeRTOS_example_system.sprj
wolfCrypt_example wolfCrypt_example.prj
wolfCrypt_example_system wolfCrypt_example_system.sprj
.gitignore
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.c
apple-universal
wolfssl-multiplatform
wolfssl-multiplatform
Assets.xcassets
AccentColor.colorset Contents.json
AppIcon.appiconset Contents.json
Contents.json
ContentView.swift simple_client_example.c simple_client_example.h wolfssl-multiplatform-Bridging-Header.h wolfssl_multiplatform.entitlements wolfssl_multiplatformApp.swift wolfssl_test_driver.c wolfssl_test_driver.h
wolfssl-multiplatform.xcodeproj project.pbxproj
.gitignore README.md build-wolfssl-framework.sh include.am
iotsafe Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.h
iotsafe-raspberrypi Makefile README.md client-tls13.c include.am main.c
mynewt README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.sh
zephyr README.md include.am
include.am
RTOS
nuttx
wolfssl .gitignore Kconfig Make.defs Makefile README.md setup-wolfssl.sh user_settings.h
include.am
bsdkm Makefile README.md bsdkm_wc_port.h include.am wolfkmod.c wolfkmod_aes.c x86_vecreg.c
certs
1024 ca-cert.der ca-cert.pem ca-key.der ca-key.pem client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der dh1024.der dh1024.pem dsa-pub-1024.pem dsa1024.der dsa1024.pem include.am rsa1024.der server-cert.der server-cert.pem server-key.der server-key.pem
3072 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
4096 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
acert
rsa_pss acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem
acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem include.am
aia ca-issuers-cert.pem multi-aia-cert.pem overflow-aia-cert.pem
crl
extra-crls ca-int-cert-revoked.pem claim-root.pem crl_critical_entry.pem crlnum_57oct.pem crlnum_64oct.pem general-server-crl.pem large_crlnum.pem large_crlnum2.pem
hash_der 0fdb2da4.r0
hash_pem 0fdb2da4.r0
bad_time_fmt.pem ca-int-ecc.pem ca-int.pem ca-int2-ecc.pem ca-int2.pem caEcc384Crl.pem caEccCrl.der caEccCrl.pem cliCrl.pem client-int-ecc.pem client-int.pem crl.der crl.pem crl.revoked crl2.der crl2.pem crl_reason.pem crl_rsapss.pem eccCliCRL.pem eccSrvCRL.pem gencrls.sh include.am server-goodaltCrl.pem server-goodaltwildCrl.pem server-goodcnCrl.pem server-goodcnwildCrl.pem server-int-ecc.pem server-int.pem wolfssl.cnf
dilithium bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.am
ecc bp256r1-key.der bp256r1-key.pem ca-secp256k1-cert.pem ca-secp256k1-key.pem client-bp256r1-cert.der client-bp256r1-cert.pem client-secp256k1-cert.der client-secp256k1-cert.pem genecc.sh include.am secp256k1-key.der secp256k1-key.pem secp256k1-param.pem secp256k1-privkey.der secp256k1-privkey.pem server-bp256r1-cert.der server-bp256r1-cert.pem server-secp256k1-cert.der server-secp256k1-cert.pem server2-secp256k1-cert.der server2-secp256k1-cert.pem wolfssl.cnf wolfssl_384.cnf
ed25519 ca-ed25519-key.der ca-ed25519-key.pem ca-ed25519-priv.der ca-ed25519-priv.pem ca-ed25519.der ca-ed25519.pem client-ed25519-key.der client-ed25519-key.pem client-ed25519-priv.der client-ed25519-priv.pem client-ed25519.der client-ed25519.pem eddsa-ed25519.der eddsa-ed25519.pem gen-ed25519-certs.sh gen-ed25519-keys.sh gen-ed25519.sh include.am root-ed25519-key.der root-ed25519-key.pem root-ed25519-priv.der root-ed25519-priv.pem root-ed25519.der root-ed25519.pem server-ed25519-cert.pem server-ed25519-key.der server-ed25519-key.pem server-ed25519-priv.der server-ed25519-priv.pem server-ed25519.der server-ed25519.pem
ed448 ca-ed448-key.der ca-ed448-key.pem ca-ed448-priv.der ca-ed448-priv.pem ca-ed448.der ca-ed448.pem client-ed448-key.der client-ed448-key.pem client-ed448-priv.der client-ed448-priv.pem client-ed448.der client-ed448.pem gen-ed448-certs.sh gen-ed448-keys.sh include.am root-ed448-key.der root-ed448-key.pem root-ed448-priv.der root-ed448-priv.pem root-ed448.der root-ed448.pem server-ed448-cert.pem server-ed448-key.der server-ed448-key.pem server-ed448-priv.der server-ed448-priv.pem server-ed448.der server-ed448.pem
external DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.am
falcon bench_falcon_level1_key.der bench_falcon_level5_key.der include.am
intermediate
ca_false_intermediate gentestcert.sh int_ca.key server.key test_ca.key test_ca.pem test_int_not_cacert.pem test_sign_bynoca_srv.pem wolfssl_base.conf wolfssl_srv.conf
ca-ecc-bad-aki.der ca-ecc-bad-aki.pem ca-int-cert.der ca-int-cert.pem ca-int-ecc-cert.der ca-int-ecc-cert.pem ca-int-ecc-key.der ca-int-ecc-key.pem ca-int-key.der ca-int-key.pem ca-int2-cert.der ca-int2-cert.pem ca-int2-ecc-cert.der ca-int2-ecc-cert.pem ca-int2-ecc-key.der ca-int2-ecc-key.pem ca-int2-key.der ca-int2-key.pem client-chain-alt-ecc.pem client-chain-alt.pem client-chain-ecc.der client-chain-ecc.pem client-chain.der client-chain.pem client-int-cert.der client-int-cert.pem client-int-ecc-cert.der client-int-ecc-cert.pem genintcerts.sh include.am server-chain-alt-ecc.pem server-chain-alt.pem server-chain-ecc.der server-chain-ecc.pem server-chain-short.pem server-chain.der server-chain.pem server-int-cert.der server-int-cert.pem server-int-ecc-cert.der server-int-ecc-cert.pem
lms bc_hss_L2_H5_W8_root.der bc_hss_L3_H5_W4_root.der bc_lms_chain_ca.der bc_lms_chain_leaf.der bc_lms_native_bc_root.der bc_lms_sha256_h10_w8_root.der bc_lms_sha256_h5_w4_root.der include.am
mldsa README.txt include.am mldsa44-cert.der mldsa44-cert.pem mldsa44-key.pem mldsa44_bare-priv.der mldsa44_bare-seed.der mldsa44_oqskeypair.der mldsa44_priv-only.der mldsa44_pub-spki.der mldsa44_seed-only.der mldsa44_seed-priv.der mldsa65-cert.der mldsa65-cert.pem mldsa65-key.pem mldsa65_bare-priv.der mldsa65_bare-seed.der mldsa65_oqskeypair.der mldsa65_priv-only.der mldsa65_pub-spki.der mldsa65_seed-only.der mldsa65_seed-priv.der mldsa87-cert.der mldsa87-cert.pem mldsa87-key.pem mldsa87_bare-priv.der mldsa87_bare-seed.der mldsa87_oqskeypair.der mldsa87_priv-only.der mldsa87_pub-spki.der mldsa87_seed-only.der mldsa87_seed-priv.der
ocsp imposter-root-ca-cert.der imposter-root-ca-cert.pem imposter-root-ca-key.der imposter-root-ca-key.pem include.am index-ca-and-intermediate-cas.txt index-ca-and-intermediate-cas.txt.attr index-intermediate1-ca-issued-certs.txt index-intermediate1-ca-issued-certs.txt.attr index-intermediate2-ca-issued-certs.txt index-intermediate2-ca-issued-certs.txt.attr index-intermediate3-ca-issued-certs.txt index-intermediate3-ca-issued-certs.txt.attr intermediate1-ca-cert.der intermediate1-ca-cert.pem intermediate1-ca-key.der intermediate1-ca-key.pem intermediate2-ca-cert.der intermediate2-ca-cert.pem intermediate2-ca-key.der intermediate2-ca-key.pem intermediate3-ca-cert.der intermediate3-ca-cert.pem intermediate3-ca-key.der intermediate3-ca-key.pem ocsp-responder-cert.der ocsp-responder-cert.pem ocsp-responder-key.der ocsp-responder-key.pem openssl.cnf renewcerts-for-test.sh renewcerts.sh root-ca-cert.der root-ca-cert.pem root-ca-crl.pem root-ca-key.der root-ca-key.pem server1-cert.der server1-cert.pem server1-chain-noroot.pem server1-key.der server1-key.pem server2-cert.der server2-cert.pem server2-key.der server2-key.pem server3-cert.der server3-cert.pem server3-key.der server3-key.pem server4-cert.der server4-cert.pem server4-key.der server4-key.pem server5-cert.der server5-cert.pem server5-key.der server5-key.pem test-leaf-response.der test-multi-response.der test-response-nointern.der test-response-rsapss.der test-response.der
p521 ca-p521-key.der ca-p521-key.pem ca-p521-priv.der ca-p521-priv.pem ca-p521.der ca-p521.pem client-p521-key.der client-p521-key.pem client-p521-priv.der client-p521-priv.pem client-p521.der client-p521.pem gen-p521-certs.sh gen-p521-keys.sh include.am root-p521-key.der root-p521-key.pem root-p521-priv.der root-p521-priv.pem root-p521.der root-p521.pem server-p521-cert.pem server-p521-key.der server-p521-key.pem server-p521-priv.der server-p521-priv.pem server-p521.der server-p521.pem
renewcerts wolfssl.cnf
rpk client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.der
rsapss ca-3072-rsapss-key.der ca-3072-rsapss-key.pem ca-3072-rsapss-priv.der ca-3072-rsapss-priv.pem ca-3072-rsapss.der ca-3072-rsapss.pem ca-rsapss-key.der ca-rsapss-key.pem ca-rsapss-priv.der ca-rsapss-priv.pem ca-rsapss.der ca-rsapss.pem client-3072-rsapss-key.der client-3072-rsapss-key.pem client-3072-rsapss-priv.der client-3072-rsapss-priv.pem client-3072-rsapss.der client-3072-rsapss.pem client-rsapss-key.der client-rsapss-key.pem client-rsapss-priv.der client-rsapss-priv.pem client-rsapss.der client-rsapss.pem gen-rsapss-keys.sh include.am renew-rsapss-certs.sh root-3072-rsapss-key.der root-3072-rsapss-key.pem root-3072-rsapss-priv.der root-3072-rsapss-priv.pem root-3072-rsapss.der root-3072-rsapss.pem root-rsapss-key.der root-rsapss-key.pem root-rsapss-priv.der root-rsapss-priv.pem root-rsapss.der root-rsapss.pem server-3072-rsapss-cert.pem server-3072-rsapss-key.der server-3072-rsapss-key.pem server-3072-rsapss-priv.der server-3072-rsapss-priv.pem server-3072-rsapss.der server-3072-rsapss.pem server-mix-rsapss-cert.pem server-rsapss-cert.pem server-rsapss-key.der server-rsapss-key.pem server-rsapss-priv.der server-rsapss-priv.pem server-rsapss.der server-rsapss.pem
sia timestamping-sia-cert.pem
slhdsa bench_slhdsa_sha2_128f_key.der bench_slhdsa_sha2_128s_key.der bench_slhdsa_sha2_192f_key.der bench_slhdsa_sha2_192s_key.der bench_slhdsa_sha2_256f_key.der bench_slhdsa_sha2_256s_key.der bench_slhdsa_shake128f_key.der bench_slhdsa_shake128s_key.der bench_slhdsa_shake192f_key.der bench_slhdsa_shake192s_key.der bench_slhdsa_shake256f_key.der bench_slhdsa_shake256s_key.der client-mldsa44-priv.pem client-mldsa44-sha2.der client-mldsa44-sha2.pem client-mldsa44-shake.der client-mldsa44-shake.pem gen-slhdsa-mldsa-certs.sh include.am root-slhdsa-sha2-128s-priv.der root-slhdsa-sha2-128s-priv.pem root-slhdsa-sha2-128s.der root-slhdsa-sha2-128s.pem root-slhdsa-shake-128s-priv.der root-slhdsa-shake-128s-priv.pem root-slhdsa-shake-128s.der root-slhdsa-shake-128s.pem server-mldsa44-priv.pem server-mldsa44-sha2.der server-mldsa44-sha2.pem server-mldsa44-shake.der server-mldsa44-shake.pem
sm2 ca-sm2-key.der ca-sm2-key.pem ca-sm2-priv.der ca-sm2-priv.pem ca-sm2.der ca-sm2.pem client-sm2-key.der client-sm2-key.pem client-sm2-priv.der client-sm2-priv.pem client-sm2.der client-sm2.pem fix_sm2_spki.py gen-sm2-certs.sh gen-sm2-keys.sh include.am root-sm2-key.der root-sm2-key.pem root-sm2-priv.der root-sm2-priv.pem root-sm2.der root-sm2.pem self-sm2-cert.pem self-sm2-key.pem self-sm2-priv.pem server-sm2-cert.der server-sm2-cert.pem server-sm2-key.der server-sm2-key.pem server-sm2-priv.der server-sm2-priv.pem server-sm2.der server-sm2.pem
statickeys dh-ffdhe2048-params.pem dh-ffdhe2048-pub.der dh-ffdhe2048-pub.pem dh-ffdhe2048.der dh-ffdhe2048.pem ecc-secp256r1.der ecc-secp256r1.pem gen-static.sh include.am x25519-pub.der x25519-pub.pem x25519.der x25519.pem
test
expired expired-ca.der expired-ca.pem expired-cert.der expired-cert.pem
catalog.txt cert-bad-neg-int.der cert-bad-oid.der cert-bad-utf8.der cert-ext-ia.cfg cert-ext-ia.der cert-ext-ia.pem cert-ext-joi.cfg cert-ext-joi.der cert-ext-joi.pem cert-ext-mnc.der cert-ext-multiple.cfg cert-ext-multiple.der cert-ext-multiple.pem cert-ext-nc-combined.der cert-ext-nc-combined.pem cert-ext-nc.cfg cert-ext-nc.der cert-ext-nc.pem cert-ext-ncdns.der cert-ext-ncdns.pem cert-ext-ncip.der cert-ext-ncip.pem cert-ext-ncmixed.der cert-ext-ncmulti.der cert-ext-ncmulti.pem cert-ext-ncrid.der cert-ext-ncrid.pem cert-ext-nct.cfg cert-ext-nct.der cert-ext-nct.pem cert-ext-ndir-exc.cfg cert-ext-ndir-exc.der cert-ext-ndir-exc.pem cert-ext-ndir.cfg cert-ext-ndir.der cert-ext-ndir.pem cert-ext-ns.der cert-over-max-altnames.cfg cert-over-max-altnames.der cert-over-max-altnames.pem cert-over-max-nc.cfg cert-over-max-nc.der cert-over-max-nc.pem client-ecc-cert-ski.hex cn-ip-literal.der cn-ip-wildcard.der crit-cert.pem crit-key.pem dh1024.der dh1024.pem dh512.der dh512.pem digsigku.pem encrypteddata.msg gen-badsig.sh gen-ext-certs.sh gen-testcerts.sh include.am kari-keyid-cms.msg ktri-keyid-cms.msg ossl-trusted-cert.pem server-badaltname.der server-badaltname.pem server-badaltnull.der server-badaltnull.pem server-badcn.der server-badcn.pem server-badcnnull.der server-badcnnull.pem server-cert-ecc-badsig.der server-cert-ecc-badsig.pem server-cert-rsa-badsig.der server-cert-rsa-badsig.pem server-duplicate-policy.pem server-garbage.der server-garbage.pem server-goodalt.der server-goodalt.pem server-goodaltwild.der server-goodaltwild.pem server-goodcn.der server-goodcn.pem server-goodcnwild.der server-goodcnwild.pem server-localhost.der server-localhost.pem smime-test-canon.p7s smime-test-multipart-badsig.p7s smime-test-multipart.p7s smime-test.p7s
test-pathlen assemble-chains.sh chainA-ICA1-key.pem chainA-ICA1-pathlen0.pem chainA-assembled.pem chainA-entity-key.pem chainA-entity.pem chainB-ICA1-key.pem chainB-ICA1-pathlen0.pem chainB-ICA2-key.pem chainB-ICA2-pathlen1.pem chainB-assembled.pem chainB-entity-key.pem chainB-entity.pem chainC-ICA1-key.pem chainC-ICA1-pathlen1.pem chainC-assembled.pem chainC-entity-key.pem chainC-entity.pem chainD-ICA1-key.pem chainD-ICA1-pathlen127.pem chainD-assembled.pem chainD-entity-key.pem chainD-entity.pem chainE-ICA1-key.pem chainE-ICA1-pathlen128.pem chainE-assembled.pem chainE-entity-key.pem chainE-entity.pem chainF-ICA1-key.pem chainF-ICA1-pathlen1.pem chainF-ICA2-key.pem chainF-ICA2-pathlen0.pem chainF-assembled.pem chainF-entity-key.pem chainF-entity.pem chainG-ICA1-key.pem chainG-ICA1-pathlen0.pem chainG-ICA2-key.pem chainG-ICA2-pathlen1.pem chainG-ICA3-key.pem chainG-ICA3-pathlen99.pem chainG-ICA4-key.pem chainG-ICA4-pathlen5.pem chainG-ICA5-key.pem chainG-ICA5-pathlen20.pem chainG-ICA6-key.pem chainG-ICA6-pathlen10.pem chainG-ICA7-key.pem chainG-ICA7-pathlen100.pem chainG-assembled.pem chainG-entity-key.pem chainG-entity.pem chainH-ICA1-key.pem chainH-ICA1-pathlen0.pem chainH-ICA2-key.pem chainH-ICA2-pathlen2.pem chainH-ICA3-key.pem chainH-ICA3-pathlen2.pem chainH-ICA4-key.pem chainH-ICA4-pathlen2.pem chainH-assembled.pem chainH-entity-key.pem chainH-entity.pem chainI-ICA1-key.pem chainI-ICA1-no_pathlen.pem chainI-ICA2-key.pem chainI-ICA2-no_pathlen.pem chainI-ICA3-key.pem chainI-ICA3-pathlen2.pem chainI-assembled.pem chainI-entity-key.pem chainI-entity.pem chainJ-ICA1-key.pem chainJ-ICA1-no_pathlen.pem chainJ-ICA2-key.pem chainJ-ICA2-no_pathlen.pem chainJ-ICA3-key.pem chainJ-ICA3-no_pathlen.pem chainJ-ICA4-key.pem chainJ-ICA4-pathlen2.pem chainJ-assembled.pem chainJ-entity-key.pem chainJ-entity.pem include.am refreshkeys.sh
test-serial0 ee_normal.pem ee_serial0.pem generate_certs.sh include.am intermediate_serial0.pem root_serial0.pem root_serial0_key.pem selfsigned_nonca_serial0.pem
xmss bc_xmss_chain_ca.der bc_xmss_chain_leaf.der bc_xmss_sha2_10_256_root.der bc_xmss_sha2_16_256_root.der bc_xmssmt_sha2_20_2_256_root.der bc_xmssmt_sha2_20_4_256_root.der bc_xmssmt_sha2_40_8_256_root.der include.am
ca-cert-chain.der ca-cert.der ca-cert.pem ca-ecc-cert.der ca-ecc-cert.pem ca-ecc-key.der ca-ecc-key.pem ca-ecc384-cert.der ca-ecc384-cert.pem ca-ecc384-key.der ca-ecc384-key.pem ca-key-pkcs8-attribute.der ca-key.der ca-key.pem check_dates.sh client-absolute-urn.pem client-ca-cert.der client-ca-cert.pem client-ca.pem client-cert-ext.der client-cert-ext.pem client-cert.der client-cert.pem client-crl-dist.der client-crl-dist.pem client-ecc-ca-cert.der client-ecc-ca-cert.pem client-ecc-cert.der client-ecc-cert.pem client-ecc384-cert.der client-ecc384-cert.pem client-ecc384-key.der client-ecc384-key.pem client-key.der client-key.pem client-keyEnc.pem client-keyPub.der client-keyPub.pem client-relative-uri.pem client-uri-cert.pem csr.attr.der csr.dsa.der csr.dsa.pem csr.ext.der csr.signed.der dh-priv-2048.der dh-priv-2048.pem dh-pub-2048.der dh-pub-2048.pem dh-pubkey-2048.der dh2048.der dh2048.pem dh3072.der dh3072.pem dh4096.der dh4096.pem dsa-pubkey-2048.der dsa2048.der dsa2048.pem dsa3072.der dsaparams.der dsaparams.pem ecc-client-key.der ecc-client-key.pem ecc-client-keyPub.der ecc-client-keyPub.pem ecc-key-comp.pem ecc-keyPkcs8.der ecc-keyPkcs8.pem ecc-keyPkcs8Enc.der ecc-keyPkcs8Enc.pem ecc-keyPub.der ecc-keyPub.pem ecc-params.der ecc-params.pem ecc-privOnlyCert.pem ecc-privOnlyKey.pem ecc-privkey.der ecc-privkey.pem ecc-privkeyPkcs8.der ecc-privkeyPkcs8.pem ecc-rsa-server.p12 empty-issuer-cert.pem entity-no-ca-bool-cert.pem entity-no-ca-bool-key.pem fpki-cert.der fpki-certpol-cert.der gen_revoked.sh include.am renewcerts.sh rid-cert.der rsa-pub-2048.pem rsa2048.der rsa3072.der server-cert-chain.der server-cert.der server-cert.pem server-ecc-comp.der server-ecc-comp.pem server-ecc-rsa.der server-ecc-rsa.pem server-ecc-self.der server-ecc-self.pem server-ecc.der server-ecc.pem server-ecc384-cert.der server-ecc384-cert.pem server-ecc384-key.der server-ecc384-key.pem server-key.der server-key.pem server-keyEnc.pem server-keyPkcs8.der server-keyPkcs8.pem server-keyPkcs8Enc.der server-keyPkcs8Enc.pem server-keyPkcs8Enc12.pem server-keyPkcs8Enc2.pem server-keyPub.der server-keyPub.pem server-revoked-cert.pem server-revoked-key.pem taoCert.txt test-ber-exp02-05-2022.p7b test-degenerate.p7b test-multiple-recipients.p7b test-servercert-rc2.p12 test-servercert.p12 test-stream-dec.p7b test-stream-sign.p7b wolfssl-website-ca.pem x942dh2048.der x942dh2048.pem
cmake
consumer CMakeLists.txt README.md main.c
modules FindARIA.cmake FindOQS.cmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.in
debian
source format
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.in
doc
dox_comments
header_files aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h puf.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wc_she.h wc_slhdsa.h wolfio.h
header_files-ja aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wolfio.h
formats
html
html_changes
search search.css search.js
customdoxygen.css doxygen.css menu.js menudata.js tabs.css
Doxyfile footer.html header.html mainpage.dox
pdf Doxyfile header.tex
images wolfssl_logo.png
QUIC.md README.txt README_DOXYGEN check_api.sh generate_documentation.sh include.am
examples
asn1 asn1.c dumpasn1.cfg gen_oid_names.rb include.am oid_names.h
async Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.h
benchmark include.am tls_bench.c tls_bench.h
client client.c client.h client.sln client.vcproj client.vcxproj include.am
configs README.md include.am user_settings_EBSnet.h user_settings_all.h user_settings_arduino.h user_settings_baremetal.h user_settings_ca.h user_settings_curve25519nonblock.h user_settings_dtls13.h user_settings_eccnonblock.h user_settings_espressif.h user_settings_fipsv2.h user_settings_fipsv5.h user_settings_min_ecc.h user_settings_openssl_compat.h user_settings_pkcs7.h user_settings_platformio.h user_settings_pq.h user_settings_rsa_only.h user_settings_stm32.h user_settings_template.h user_settings_tls12.h user_settings_tls13.h user_settings_wolfboot_keytools.h user_settings_wolfssh.h user_settings_wolftpm.h
crypto_policies
default wolfssl.txt
future wolfssl.txt
legacy wolfssl.txt
echoclient echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quit
echoserver echoserver.c echoserver.h echoserver.sln echoserver.vcproj echoserver.vcxproj include.am
ocsp_responder include.am ocsp_responder.c ocsp_responder.h
pem include.am pem.c
sctp include.am sctp-client-dtls.c sctp-client.c sctp-server-dtls.c sctp-server.c
server include.am server.c server.h server.sln server.vcproj server.vcxproj
README.md include.am
linuxkm
patches
5.10.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch
5.10.236 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch
5.14.0-570.58.1.el9_6 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v14-570v58v1-el9_6.patch
5.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch
5.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch
5.17-ubuntu-jammy-tegra WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17-ubuntu-jammy-tegra.patch
6.1.73 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch
6.12 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch
6.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch
7.0 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-7v0.patch
regen-patches.sh
Kbuild Makefile README.md get_thread_size.c include.am linuxkm-fips-hash-wrapper.sh linuxkm-fips-hash.c linuxkm_memory.c linuxkm_memory.h linuxkm_wc_port.h lkcapi_aes_glue.c lkcapi_dh_glue.c lkcapi_ecdh_glue.c lkcapi_ecdsa_glue.c lkcapi_glue.c lkcapi_rsa_glue.c lkcapi_sha_glue.c module_exports.c.template module_hooks.c pie_redirect_table.c wolfcrypt.lds x86_vector_register_glue.c
m4 ax_add_am_macro.m4 ax_am_jobserver.m4 ax_am_macros.m4 ax_append_compile_flags.m4 ax_append_flag.m4 ax_append_link_flags.m4 ax_append_to_file.m4 ax_atomic.m4 ax_bsdkm.m4 ax_check_compile_flag.m4 ax_check_link_flag.m4 ax_compiler_version.m4 ax_count_cpus.m4 ax_create_generic_config.m4 ax_debug.m4 ax_file_escapes.m4 ax_harden_compiler_flags.m4 ax_linuxkm.m4 ax_print_to_file.m4 ax_pthread.m4 ax_require_defined.m4 ax_tls.m4 ax_vcs_checkout.m4 hexversion.m4 lib_socket_nsl.m4 visibility.m4
mcapi
wolfcrypt_mcapi.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
zlib.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README crypto.c crypto.h include.am mcapi_test.c user_settings.h
mplabx
wolfcrypt_benchmark.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README benchmark_main.c include.am test_main.c user_settings.h
mqx
util_lib
Sources include.am util.c util.h
wolfcrypt_benchmark
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfcrypt_test
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfssl include.am
wolfssl_client
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfssl_client_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
README
rpm include.am spec.in
scripts
bench bench_functions.sh
aria-cmake-build-test.sh asn1_oid_sum.pl benchmark.test benchmark_compare.sh cleanup_testfiles.sh crl-gen-openssl.test crl-revoked.test dertoc.pl dtls.test dtlscid.test external.test google.test include.am makedistsmall.sh memtest.sh ocsp-responder-openssl-interop.test ocsp-stapling-with-ca-as-responder.test ocsp-stapling-with-wolfssl-responder.test ocsp-stapling.test ocsp-stapling2.test ocsp-stapling_tls13multi.test ocsp.test openssl.test openssl_srtp.test pem.test ping.test pkcallbacks.test psk.test resume.test rsapss.test sniffer-gen.sh sniffer-ipv6.pcap sniffer-static-rsa.pcap sniffer-testsuite.test sniffer-tls12-keylog.out sniffer-tls12-keylog.pcap sniffer-tls12-keylog.sslkeylog sniffer-tls13-dh-resume.pcap sniffer-tls13-dh.pcap sniffer-tls13-ecc-resume.pcap sniffer-tls13-ecc.pcap sniffer-tls13-hrr.pcap sniffer-tls13-keylog.out sniffer-tls13-keylog.pcap sniffer-tls13-keylog.sslkeylog sniffer-tls13-x25519-resume.pcap sniffer-tls13-x25519.pcap stm32l4-v4_0_1_build.sh tls13.test trusted_peer.test unit.test.in user_settings_asm.sh
src bio.c conf.c crl.c dtls.c dtls13.c include.am internal.c keys.c ocsp.c pk.c pk_ec.c pk_rsa.c quic.c sniffer.c ssl.c ssl_api_cert.c ssl_api_crl_ocsp.c ssl_api_pk.c ssl_asn1.c ssl_bn.c ssl_certman.c ssl_crypto.c ssl_ech.c ssl_load.c ssl_misc.c ssl_p7p12.c ssl_sess.c ssl_sk.c tls.c tls13.c wolfio.c x509.c x509_str.c
sslSniffer
sslSnifferTest README_WIN.md include.am snifftest.c sslSniffTest.vcproj sslSniffTest.vcxproj
README.md sslSniffer.vcproj sslSniffer.vcxproj
support gen-debug-trace-error-codes.sh include.am wolfssl.pc.in
tests
api api.h api_decl.h create_ocsp_test_blobs.py include.am test_aes.c test_aes.h test_arc4.c test_arc4.h test_ascon.c test_ascon.h test_ascon_kats.h test_asn.c test_asn.h test_blake2.c test_blake2.h test_camellia.c test_camellia.h test_certman.c test_certman.h test_chacha.c test_chacha.h test_chacha20_poly1305.c test_chacha20_poly1305.h test_cmac.c test_cmac.h test_curve25519.c test_curve25519.h test_curve448.c test_curve448.h test_des3.c test_des3.h test_dh.c test_dh.h test_digest.h test_dsa.c test_dsa.h test_dtls.c test_dtls.h test_ecc.c test_ecc.h test_ed25519.c test_ed25519.h test_ed448.c test_ed448.h test_evp.c test_evp.h test_evp_cipher.c test_evp_cipher.h test_evp_digest.c test_evp_digest.h test_evp_pkey.c test_evp_pkey.h test_hash.c test_hash.h test_hmac.c test_hmac.h test_md2.c test_md2.h test_md4.c test_md4.h test_md5.c test_md5.h test_mldsa.c test_mldsa.h test_mlkem.c test_mlkem.h test_ocsp.c test_ocsp.h test_ocsp_test_blobs.h test_ossl_asn1.c test_ossl_asn1.h test_ossl_bio.c test_ossl_bio.h test_ossl_bn.c test_ossl_bn.h test_ossl_cipher.c test_ossl_cipher.h test_ossl_dgst.c test_ossl_dgst.h test_ossl_dh.c test_ossl_dh.h test_ossl_dsa.c test_ossl_dsa.h test_ossl_ec.c test_ossl_ec.h test_ossl_ecx.c test_ossl_ecx.h test_ossl_mac.c test_ossl_mac.h test_ossl_obj.c test_ossl_obj.h test_ossl_p7p12.c test_ossl_p7p12.h test_ossl_pem.c test_ossl_pem.h test_ossl_rand.c test_ossl_rand.h test_ossl_rsa.c test_ossl_rsa.h test_ossl_sk.c test_ossl_sk.h test_ossl_x509.c test_ossl_x509.h test_ossl_x509_acert.c test_ossl_x509_acert.h test_ossl_x509_crypto.c test_ossl_x509_crypto.h test_ossl_x509_ext.c test_ossl_x509_ext.h test_ossl_x509_info.c test_ossl_x509_info.h test_ossl_x509_io.c test_ossl_x509_io.h test_ossl_x509_lu.c test_ossl_x509_lu.h test_ossl_x509_name.c test_ossl_x509_name.h test_ossl_x509_pk.c test_ossl_x509_pk.h test_ossl_x509_str.c test_ossl_x509_str.h test_ossl_x509_vp.c test_ossl_x509_vp.h test_pkcs12.c test_pkcs12.h test_pkcs7.c test_pkcs7.h test_poly1305.c test_poly1305.h test_random.c test_random.h test_rc2.c test_rc2.h test_ripemd.c test_ripemd.h test_rsa.c test_rsa.h test_sha.c test_sha.h test_sha256.c test_sha256.h test_sha3.c test_sha3.h test_sha512.c test_sha512.h test_she.c test_she.h test_signature.c test_signature.h test_slhdsa.c test_slhdsa.h test_sm2.c test_sm2.h test_sm3.c test_sm3.h test_sm4.c test_sm4.h test_tls.c test_tls.h test_tls13.c test_tls13.h test_tls_ext.c test_tls_ext.h test_wc_encrypt.c test_wc_encrypt.h test_wolfmath.c test_wolfmath.h test_x509.c test_x509.h
emnet
IP IP.h
Makefile emnet_nonblock_test.c emnet_shim.c
freertos-mem-track-repro FreeRTOS.h repro.c run.sh semphr.h task.h user_settings.h
swdev .gitignore Makefile README.md swdev.c swdev.h swdev_loader.c swdev_loader.h user_settings.h
CONF_FILES_README.md NCONF_test.cnf README TXT_DB.txt api.c include.am quic.c srp.c suites.c test-altchains.conf test-chains.conf test-dhprime.conf test-dtls-downgrade.conf test-dtls-fails-cipher.conf test-dtls-fails.conf test-dtls-group.conf test-dtls-mtu.conf test-dtls-reneg-client.conf test-dtls-reneg-server.conf test-dtls-resume.conf test-dtls-sha2.conf test-dtls-srtp-fails.conf test-dtls-srtp.conf test-dtls.conf test-dtls13-cid.conf test-dtls13-downgrade-fails.conf test-dtls13-downgrade.conf test-dtls13-pq-hybrid-extra-frag.conf test-dtls13-pq-hybrid-extra.conf test-dtls13-pq-hybrid-frag.conf test-dtls13-pq-standalone-frag.conf test-dtls13-pq-standalone.conf test-dtls13-psk.conf test-dtls13.conf test-ecc-cust-curves.conf test-ed25519.conf test-ed448.conf test-enckeys.conf test-fails.conf test-maxfrag-dtls.conf test-maxfrag.conf test-p521.conf test-psk-no-id-sha2.conf test-psk-no-id.conf test-psk.conf test-rsapss.conf test-sctp-sha2.conf test-sctp.conf test-sha2.conf test-sig.conf test-sm2.conf test-tls-downgrade.conf test-tls13-down.conf test-tls13-ecc.conf test-tls13-pq-hybrid-extra.conf test-tls13-pq-hybrid.conf test-tls13-pq-standalone.conf test-tls13-psk-certs.conf test-tls13-psk.conf test-tls13-slhdsa-fail.conf test-tls13-slhdsa-sha2.conf test-tls13-slhdsa-shake.conf test-tls13.conf test-trustpeer.conf test.conf unit.c unit.h utils.c utils.h w64wrapper.c
testsuite include.am testsuite.c testsuite.sln testsuite.vcproj testsuite.vcxproj utils.c utils.h
tirtos
packages
ti
net
wolfssl
tests
EK_TM4C1294XL
wolfcrypt
benchmark TM4C1294NC.icf benchmark.cfg main.c package.bld.hide package.xdc
test TM4C1294NC.icf main.c package.bld.hide package.xdc test.cfg
package.bld package.xdc package.xs
.gitignore README include.am products.mak wolfssl.bld wolfssl.mak
wolfcrypt
benchmark README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.am
src
port
Espressif
esp_crt_bundle README.md cacrt_all.pem cacrt_deprecated.pem cacrt_local.pem esp_crt_bundle.c gen_crt_bundle.py pio_install_cryptography.py
README.md esp32_aes.c esp32_mp.c esp32_sha.c esp32_util.c esp_sdk_mem_lib.c esp_sdk_time_lib.c esp_sdk_wifi_lib.c
Renesas README.md renesas_common.c renesas_fspsm_aes.c renesas_fspsm_rsa.c renesas_fspsm_sha.c renesas_fspsm_util.c renesas_rx64_hw_sha.c renesas_rx64_hw_util.c renesas_tsip_aes.c renesas_tsip_rsa.c renesas_tsip_sha.c renesas_tsip_util.c
af_alg afalg_aes.c afalg_hash.c wc_afalg.c
aria aria-crypt.c aria-cryptocb.c
arm armv8-32-aes-asm.S armv8-32-aes-asm_c.c armv8-32-chacha-asm.S armv8-32-chacha-asm_c.c armv8-32-curve25519.S armv8-32-curve25519_c.c armv8-32-mlkem-asm.S armv8-32-mlkem-asm_c.c armv8-32-poly1305-asm.S armv8-32-poly1305-asm_c.c armv8-32-sha256-asm.S armv8-32-sha256-asm_c.c armv8-32-sha3-asm.S armv8-32-sha3-asm_c.c armv8-32-sha512-asm.S armv8-32-sha512-asm_c.c armv8-aes-asm.S armv8-aes-asm_c.c armv8-aes.c armv8-chacha-asm.S armv8-chacha-asm_c.c armv8-curve25519.S armv8-curve25519_c.c armv8-mlkem-asm.S armv8-mlkem-asm_c.c armv8-poly1305-asm.S armv8-poly1305-asm_c.c armv8-sha256-asm.S armv8-sha256-asm_c.c armv8-sha256.c armv8-sha3-asm.S armv8-sha3-asm_c.c armv8-sha512-asm.S armv8-sha512-asm_c.c armv8-sha512.c cryptoCell.c cryptoCellHash.c thumb2-aes-asm.S thumb2-aes-asm_c.c thumb2-chacha-asm.S thumb2-chacha-asm_c.c thumb2-curve25519.S thumb2-curve25519_c.c thumb2-mlkem-asm.S thumb2-mlkem-asm_c.c thumb2-poly1305-asm.S thumb2-poly1305-asm_c.c thumb2-sha256-asm.S thumb2-sha256-asm_c.c thumb2-sha3-asm.S thumb2-sha3-asm_c.c thumb2-sha512-asm.S thumb2-sha512-asm_c.c
atmel README.md atmel.c
autosar README.md cryif.c crypto.c csm.c include.am test.c
caam README.md caam_aes.c caam_doc.pdf caam_driver.c caam_error.c caam_integrity.c caam_qnx.c caam_sha.c wolfcaam_aes.c wolfcaam_cmac.c wolfcaam_ecdsa.c wolfcaam_fsl_nxp.c wolfcaam_hash.c wolfcaam_hmac.c wolfcaam_init.c wolfcaam_qnx.c wolfcaam_rsa.c wolfcaam_seco.c wolfcaam_x25519.c
cavium README.md README_Octeon.md cavium_nitrox.c cavium_octeon_sync.c
cuda README.md aes-cuda.cu
cypress README.md psoc6_crypto.c
devcrypto README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.c
intel README.md quickassist.c quickassist_mem.c quickassist_sync.c
iotsafe iotsafe.c
kcapi README.md kcapi_aes.c kcapi_dh.c kcapi_ecc.c kcapi_hash.c kcapi_hmac.c kcapi_rsa.c
liboqs liboqs.c
maxim README.md max3266x.c maxq10xx.c
mynewt mynewt_port.c
nxp README.md README_SE050.md casper_port.c dcp_port.c hashcrypt_port.c ksdk_port.c se050_port.c
pic32 pic32mz-crypt.c
ppc32 ppc32-sha256-asm.S ppc32-sha256-asm_c.c ppc32-sha256-asm_cr.c
psa README.md psa.c psa_aes.c psa_hash.c psa_pkcbs.c
riscv riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.c
rpi_pico README.md pico.c
silabs README.md silabs_aes.c silabs_ecc.c silabs_hash.c silabs_random.c
st README.md STM32MP13.md STM32MP25.md stm32.c stsafe.c
ti ti-aes.c ti-ccm.c ti-des3.c ti-hash.c
tropicsquare README.md tropic01.c
xilinx xil-aesgcm.c xil-sha3.c xil-versal-glue.c xil-versal-trng.c
nrf51.c
ASN_TEMPLATE.md aes.c aes_asm.S aes_asm.asm aes_gcm_asm.S aes_gcm_asm.asm aes_gcm_x86_asm.S aes_xts_asm.S aes_xts_asm.asm arc4.c ascon.c asm.c asn.c asn_orig.c async.c blake2b.c blake2s.c camellia.c chacha.c chacha20_poly1305.c chacha_asm.S chacha_asm.asm cmac.c coding.c compress.c cpuid.c cryptocb.c curve25519.c curve448.c des3.c dh.c dilithium.c dsa.c ecc.c ecc_fp.c eccsi.c ed25519.c ed448.c error.c evp.c evp_pk.c falcon.c fe_448.c fe_low_mem.c fe_operations.c fe_x25519_128.h fe_x25519_asm.S fp_mont_small.i fp_mul_comba_12.i fp_mul_comba_17.i fp_mul_comba_20.i fp_mul_comba_24.i fp_mul_comba_28.i fp_mul_comba_3.i fp_mul_comba_32.i fp_mul_comba_4.i fp_mul_comba_48.i fp_mul_comba_6.i fp_mul_comba_64.i fp_mul_comba_7.i fp_mul_comba_8.i fp_mul_comba_9.i fp_mul_comba_small_set.i fp_sqr_comba_12.i fp_sqr_comba_17.i fp_sqr_comba_20.i fp_sqr_comba_24.i fp_sqr_comba_28.i fp_sqr_comba_3.i fp_sqr_comba_32.i fp_sqr_comba_4.i fp_sqr_comba_48.i fp_sqr_comba_6.i fp_sqr_comba_64.i fp_sqr_comba_7.i fp_sqr_comba_8.i fp_sqr_comba_9.i fp_sqr_comba_small_set.i ge_448.c ge_low_mem.c ge_operations.c hash.c hmac.c hpke.c include.am integer.c kdf.c logging.c md2.c md4.c md5.c memory.c misc.c pkcs12.c pkcs7.c poly1305.c poly1305_asm.S poly1305_asm.asm puf.c pwdbased.c random.c rc2.c ripemd.c rng_bank.c rsa.c sakke.c sha.c sha256.c sha256_asm.S sha3.c sha3_asm.S sha512.c sha512_asm.S signature.c siphash.c sm2.c sm3.c sm3_asm.S sm4.c sp_arm32.c sp_arm64.c sp_armthumb.c sp_c32.c sp_c64.c sp_cortexm.c sp_dsp32.c sp_int.c sp_sm2_arm32.c sp_sm2_arm64.c sp_sm2_armthumb.c sp_sm2_c32.c sp_sm2_c64.c sp_sm2_cortexm.c sp_sm2_x86_64.c sp_sm2_x86_64_asm.S sp_x86_64.c sp_x86_64_asm.S sp_x86_64_asm.asm srp.c tfm.c wc_dsp.c wc_encrypt.c wc_lms.c wc_lms_impl.c wc_mldsa_asm.S wc_mlkem.c wc_mlkem_asm.S wc_mlkem_poly.c wc_pkcs11.c wc_port.c wc_she.c wc_slhdsa.c wc_xmss.c wc_xmss_impl.c wolfentropy.c wolfevent.c wolfmath.c
test README.md include.am test-VS2022.sln test-VS2022.vcxproj test-VS2022.vcxproj.user test.c test.h test.sln test.vcproj test_paths.h.in
wolfssl
openssl aes.h asn1.h asn1t.h bio.h bn.h buffer.h camellia.h cmac.h cms.h compat_types.h conf.h crypto.h des.h dh.h dsa.h ec.h ec25519.h ec448.h ecdh.h ecdsa.h ed25519.h ed448.h engine.h err.h evp.h fips_rand.h hmac.h include.am kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pkcs12.h pkcs7.h rand.h rc4.h ripemd.h rsa.h safestack.h sha.h sha3.h srp.h ssl.h ssl23.h stack.h tls1.h txt_db.h ui.h x509.h x509_vfy.h x509v3.h
wolfcrypt
port
Espressif esp-sdk-lib.h esp32-crypt.h esp_crt_bundle.h
Renesas renesas-fspsm-crypt.h renesas-fspsm-types.h renesas-rx64-hw-crypt.h renesas-tsip-crypt.h renesas_cmn.h renesas_fspsm_internal.h renesas_sync.h renesas_tsip_internal.h renesas_tsip_types.h
af_alg afalg_hash.h wc_afalg.h
aria aria-crypt.h aria-cryptocb.h
arm cryptoCell.h
atmel atmel.h
autosar CryIf.h Crypto.h Csm.h StandardTypes.h
caam caam_driver.h caam_error.h caam_qnx.h wolfcaam.h wolfcaam_aes.h wolfcaam_cmac.h wolfcaam_ecdsa.h wolfcaam_fsl_nxp.h wolfcaam_hash.h wolfcaam_qnx.h wolfcaam_rsa.h wolfcaam_seco.h wolfcaam_sha.h wolfcaam_x25519.h
cavium cavium_nitrox.h cavium_octeon_sync.h
cypress psoc6_crypto.h
devcrypto wc_devcrypto.h
intel quickassist.h quickassist_mem.h quickassist_sync.h
iotsafe iotsafe.h
kcapi kcapi_dh.h kcapi_ecc.h kcapi_hash.h kcapi_hmac.h kcapi_rsa.h wc_kcapi.h
liboqs liboqs.h
maxim max3266x-cryptocb.h max3266x.h maxq10xx.h
nxp casper_port.h dcp_port.h hashcrypt_port.h ksdk_port.h se050_port.h
pic32 pic32mz-crypt.h
psa psa.h
riscv riscv-64-asm.h
rpi_pico pico.h
silabs silabs_aes.h silabs_ecc.h silabs_hash.h silabs_random.h
st stm32.h stsafe.h
ti ti-ccm.h ti-hash.h
tropicsquare tropic01.h
xilinx xil-sha3.h xil-versal-glue.h xil-versal-trng.h
nrf51.h
aes.h arc4.h ascon.h asn.h asn_public.h async.h blake2-impl.h blake2-int.h blake2.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cpuid.h cryptocb.h curve25519.h curve448.h des3.h dh.h dilithium.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h falcon.h fe_448.h fe_operations.h fips_test.h ge_448.h ge_operations.h hash.h hmac.h hpke.h include.am integer.h kdf.h libwolfssl_sources.h libwolfssl_sources_asm.h logging.h md2.h md4.h md5.h mem_track.h memory.h misc.h mpi_class.h mpi_superclass.h oid_sum.h pkcs11.h pkcs12.h pkcs7.h poly1305.h puf.h pwdbased.h random.h rc2.h ripemd.h rng_bank.h rsa.h sakke.h selftest.h settings.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h sm2.h sm3.h sm4.h sp.h sp_int.h srp.h tfm.h types.h visibility.h wc_encrypt.h wc_lms.h wc_mlkem.h wc_pkcs11.h wc_port.h wc_she.h wc_slhdsa.h wc_xmss.h wolfentropy.h wolfevent.h wolfmath.h
callbacks.h certs_test.h certs_test_sm.h crl.h error-ssl.h include.am internal.h ocsp.h options.h.in quic.h sniffer.h sniffer_error.h sniffer_error.rc ssl.h test.h version.h version.h.in wolfio.h
wrapper
Ada
examples
src aes_verify_main.adb rsa_verify_main.adb sha256_main.adb spark_sockets.adb spark_sockets.ads spark_terminal.adb spark_terminal.ads tls_client.adb tls_client.ads tls_client_main.adb tls_server.adb tls_server.ads tls_server_main.adb
.gitignore alire.toml examples.gpr
tests
src
support test_support.adb test_support.ads tests_root_suite.adb tests_root_suite.ads
aes_bindings_tests.adb aes_bindings_tests.ads rsa_verify_bindings_tests.adb rsa_verify_bindings_tests.ads sha256_bindings_tests.adb sha256_bindings_tests.ads tests.adb
.gitignore README.md alire.toml tests.gpr valgrind.supp
.gitignore README.md ada_binding.c alire.toml default.gpr include.am restricted.adc user_settings.h wolfssl-full_runtime.adb wolfssl-full_runtime.ads wolfssl.adb wolfssl.ads wolfssl.gpr
CSharp
wolfCrypt-Test
Properties AssemblyInfo.cs
App.config wolfCrypt-Test.cs wolfCrypt-Test.csproj
wolfSSL-DTLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-PSK-Server.cs wolfSSL-DTLS-PSK-Server.csproj
wolfSSL-DTLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-Server.cs wolfSSL-DTLS-Server.csproj
wolfSSL-Example-IOCallbacks
Properties AssemblyInfo.cs
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csproj
wolfSSL-TLS-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Client.cs wolfSSL-TLS-Client.csproj
wolfSSL-TLS-PSK-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Client.cs wolfSSL-TLS-PSK-Client.csproj
wolfSSL-TLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Server.cs wolfSSL-TLS-PSK-Server.csproj
wolfSSL-TLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Server.cs wolfSSL-TLS-Server.csproj
wolfSSL-TLS-ServerThreaded
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csproj
wolfSSL_CSharp
Properties AssemblyInfo.cs Resources.Designer.cs Resources.resx
X509.cs wolfCrypt.cs wolfSSL.cs wolfSSL_CSharp.csproj
README.md include.am user_settings.h wolfSSL_CSharp.sln wolfssl.vcxproj
python README.md
rust
wolfssl-wolfcrypt
src aes.rs blake2.rs chacha20_poly1305.rs cmac.rs cmac_mac.rs curve25519.rs dh.rs dilithium.rs ecc.rs ecdsa.rs ed25519.rs ed448.rs fips.rs hkdf.rs hmac.rs hmac_mac.rs kdf.rs lib.rs lms.rs mlkem.rs mlkem_kem.rs pbkdf2_password_hash.rs prf.rs random.rs rsa.rs rsa_pkcs1v15.rs sha.rs sha_digest.rs sys.rs
tests
common mod.rs
test_aes.rs test_blake2.rs test_chacha20_poly1305.rs test_cmac.rs test_cmac_mac.rs test_curve25519.rs test_dh.rs test_dilithium.rs test_ecc.rs test_ecdsa.rs test_ed25519.rs test_ed448.rs test_hkdf.rs test_hmac.rs test_hmac_mac.rs test_kdf.rs test_lms.rs test_mlkem.rs test_mlkem_kem.rs test_pbkdf2_password_hash.rs test_prf.rs test_random.rs test_rsa.rs test_rsa_pkcs1v15.rs test_sha.rs test_sha_digest.rs test_wolfcrypt.rs
CHANGELOG.md Cargo.lock Cargo.toml Makefile README.md build.rs headers.h
Makefile README.md include.am
include.am
zephyr
samples
wolfssl_benchmark
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_test
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_sock
boards native_sim.conf
src tls_sock.c
CMakeLists.txt README install_sample.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_thread
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
src tls_threaded.c
CMakeLists.txt README install_sample.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl options.h
CMakeLists.txt Kconfig Kconfig.tls-generic README.md include.am module.yml user_settings-no-malloc.h user_settings.h zephyr_init.c
.codespellexcludelines .cyignore .editorconfig .gitignore .wolfssl_known_macro_extras AUTHORS CMakeLists.txt CMakePresets.json CMakeSettings.json COPYING ChangeLog.md INSTALL LICENSING LPCExpresso.cproject LPCExpresso.project Makefile.am README README-async.md README.md SCRIPTS-LIST SECURITY-POLICY.md SECURITY-REPORT-TEMPLATE.md Vagrantfile autogen.sh commit-tests.sh configure.ac fips-check.sh fips-hash.sh gencertbuf.pl input pull_to_vagrant.sh quit resource.h stamp-h.in valgrind-bash.supp valgrind-error.sh wnr-example.conf wolfssl-VS2022.vcxproj wolfssl.rc wolfssl.vcproj wolfssl.vcxproj wolfssl64.sln
.clangd .gitignore DOCS.md Makefile README.md assert.c core.c crypto.c env.c fs.c http.c ini.c json.c log.c luna.h main.c makext.mk path.c process.c request.c sqlite.c stash.c template.c util.c
curl/lib/vssh/libssh2.c raw
   1/***************************************************************************
   2 *                                  _   _ ____  _
   3 *  Project                     ___| | | |  _ \| |
   4 *                             / __| | | | |_) | |
   5 *                            | (__| |_| |  _ <| |___
   6 *                             \___|\___/|_| \_\_____|
   7 *
   8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
   9 *
  10 * This software is licensed as described in the file COPYING, which
  11 * you should have received as part of this distribution. The terms
  12 * are also available at https://curl.se/docs/copyright.html.
  13 *
  14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15 * copies of the Software, and permit persons to whom the Software is
  16 * furnished to do so, under the terms of the COPYING file.
  17 *
  18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19 * KIND, either express or implied.
  20 *
  21 * SPDX-License-Identifier: curl
  22 *
  23 ***************************************************************************/
  24#include "curl_setup.h"
  25
  26#ifdef USE_LIBSSH2
  27
  28/* #define CURL_LIBSSH2_DEBUG */
  29
  30#ifdef HAVE_NETINET_IN_H
  31#include <netinet/in.h>
  32#endif
  33#ifdef HAVE_ARPA_INET_H
  34#include <arpa/inet.h>
  35#endif
  36#ifdef HAVE_NETDB_H
  37#include <netdb.h>
  38#endif
  39#ifdef __VMS
  40#include <in.h>
  41#include <inet.h>
  42#endif
  43
  44#include "urldata.h"
  45#include "sendf.h"
  46#include "curl_trc.h"
  47#include "hostip.h"
  48#include "progress.h"
  49#include "transfer.h"
  50#include "vssh/ssh.h"
  51#include "url.h"
  52#include "cfilters.h"
  53#include "connect.h"
  54#include "parsedate.h" /* for the week day and month names */
  55#include "multiif.h"
  56#include "select.h"
  57#include "curlx/fopen.h"
  58#include "vssh/vssh.h"
  59#include "curlx/strparse.h"
  60#include "curlx/base64.h" /* for curlx_base64_encode() */
  61
  62static const char *sftp_libssh2_strerror(unsigned long err)
  63{
  64  switch(err) {
  65  case LIBSSH2_FX_NO_SUCH_FILE:
  66    return "No such file or directory";
  67
  68  case LIBSSH2_FX_PERMISSION_DENIED:
  69    return "Permission denied";
  70
  71  case LIBSSH2_FX_FAILURE:
  72    return "Operation failed";
  73
  74  case LIBSSH2_FX_BAD_MESSAGE:
  75    return "Bad message from SFTP server";
  76
  77  case LIBSSH2_FX_NO_CONNECTION:
  78    return "Not connected to SFTP server";
  79
  80  case LIBSSH2_FX_CONNECTION_LOST:
  81    return "Connection to SFTP server lost";
  82
  83  case LIBSSH2_FX_OP_UNSUPPORTED:
  84    return "Operation not supported by SFTP server";
  85
  86  case LIBSSH2_FX_INVALID_HANDLE:
  87    return "Invalid handle";
  88
  89  case LIBSSH2_FX_NO_SUCH_PATH:
  90    return "No such file or directory";
  91
  92  case LIBSSH2_FX_FILE_ALREADY_EXISTS:
  93    return "File already exists";
  94
  95  case LIBSSH2_FX_WRITE_PROTECT:
  96    return "File is write protected";
  97
  98  case LIBSSH2_FX_NO_MEDIA:
  99    return "No media";
 100
 101  case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
 102    return "Disk full";
 103
 104  case LIBSSH2_FX_QUOTA_EXCEEDED:
 105    return "User quota exceeded";
 106
 107  case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
 108    return "Unknown principle";
 109
 110  case LIBSSH2_FX_LOCK_CONFlICT:
 111    return "File lock conflict";
 112
 113  case LIBSSH2_FX_DIR_NOT_EMPTY:
 114    return "Directory not empty";
 115
 116  case LIBSSH2_FX_NOT_A_DIRECTORY:
 117    return "Not a directory";
 118
 119  case LIBSSH2_FX_INVALID_FILENAME:
 120    return "Invalid filename";
 121
 122  case LIBSSH2_FX_LINK_LOOP:
 123    return "Link points to itself";
 124  }
 125  return "Unknown error in libssh2";
 126}
 127
 128static void kbd_callback(const char *name, int name_len,
 129                         const char *instruction, int instruction_len,
 130                         int num_prompts,
 131                         const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
 132                         LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
 133                         void **abstract)
 134{
 135  struct Curl_easy *data = (struct Curl_easy *)*abstract;
 136
 137#ifdef CURL_LIBSSH2_DEBUG
 138  curl_mfprintf(stderr, "name=%s\n", name);
 139  curl_mfprintf(stderr, "name_len=%d\n", name_len);
 140  curl_mfprintf(stderr, "instruction=%s\n", instruction);
 141  curl_mfprintf(stderr, "instruction_len=%d\n", instruction_len);
 142  curl_mfprintf(stderr, "num_prompts=%d\n", num_prompts);
 143#else
 144  (void)name;
 145  (void)name_len;
 146  (void)instruction;
 147  (void)instruction_len;
 148#endif /* CURL_LIBSSH2_DEBUG */
 149  if(num_prompts == 1) {
 150    struct connectdata *conn = data->conn;
 151    const char *passwd = Curl_creds_passwd(conn->creds);
 152    /* this function must allocate memory that can be freed by libssh2, which
 153       uses the LIBSSH2_FREE_FUNC callback */
 154    responses[0].text = Curl_cstrdup(passwd);
 155    responses[0].length =
 156      responses[0].text == NULL ? 0 : curlx_uztoui(strlen(passwd));
 157  }
 158  (void)prompts;
 159} /* kbd_callback */
 160
 161static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err)
 162{
 163  switch(err) {
 164  case LIBSSH2_FX_OK:
 165    return CURLE_OK;
 166
 167  case LIBSSH2_FX_NO_SUCH_FILE:
 168  case LIBSSH2_FX_NO_SUCH_PATH:
 169    return CURLE_REMOTE_FILE_NOT_FOUND;
 170
 171  case LIBSSH2_FX_PERMISSION_DENIED:
 172  case LIBSSH2_FX_WRITE_PROTECT:
 173  case LIBSSH2_FX_LOCK_CONFlICT:
 174    return CURLE_REMOTE_ACCESS_DENIED;
 175
 176  case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
 177  case LIBSSH2_FX_QUOTA_EXCEEDED:
 178    return CURLE_REMOTE_DISK_FULL;
 179
 180  case LIBSSH2_FX_FILE_ALREADY_EXISTS:
 181    return CURLE_REMOTE_FILE_EXISTS;
 182
 183  case LIBSSH2_FX_DIR_NOT_EMPTY:
 184    return CURLE_QUOTE_ERROR;
 185
 186  default:
 187    break;
 188  }
 189
 190  return CURLE_SSH;
 191}
 192
 193static CURLcode libssh2_session_error_to_CURLE(int err)
 194{
 195  switch(err) {
 196  /* Ordered by order of appearance in libssh2.h */
 197  case LIBSSH2_ERROR_NONE:
 198    return CURLE_OK;
 199
 200  /* This is the error returned by libssh2_scp_recv2
 201   * on unknown file */
 202  case LIBSSH2_ERROR_SCP_PROTOCOL:
 203    return CURLE_REMOTE_FILE_NOT_FOUND;
 204
 205  case LIBSSH2_ERROR_SOCKET_NONE:
 206    return CURLE_COULDNT_CONNECT;
 207
 208  case LIBSSH2_ERROR_ALLOC:
 209    return CURLE_OUT_OF_MEMORY;
 210
 211  case LIBSSH2_ERROR_SOCKET_SEND:
 212    return CURLE_SEND_ERROR;
 213
 214  case LIBSSH2_ERROR_HOSTKEY_INIT:
 215  case LIBSSH2_ERROR_HOSTKEY_SIGN:
 216  case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
 217  case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
 218    return CURLE_PEER_FAILED_VERIFICATION;
 219
 220  case LIBSSH2_ERROR_PASSWORD_EXPIRED:
 221    return CURLE_LOGIN_DENIED;
 222
 223  case LIBSSH2_ERROR_SOCKET_TIMEOUT:
 224  case LIBSSH2_ERROR_TIMEOUT:
 225    return CURLE_OPERATION_TIMEDOUT;
 226
 227  case LIBSSH2_ERROR_EAGAIN:
 228    return CURLE_AGAIN;
 229  }
 230
 231  return CURLE_SSH;
 232}
 233
 234/* These functions are made to use the libcurl memory functions - NOT the
 235   debugmem functions, as that leads us to trigger on libssh2 memory leaks
 236   that are not ours to care for */
 237
 238static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
 239{
 240  (void)abstract;
 241  return Curl_cmalloc(count);
 242}
 243
 244static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
 245{
 246  (void)abstract;
 247  return Curl_crealloc(ptr, count);
 248}
 249
 250static LIBSSH2_FREE_FUNC(my_libssh2_free)
 251{
 252  (void)abstract;
 253  if(ptr) /* ssh2 agent sometimes call free with null ptr */
 254    Curl_cfree(ptr);
 255}
 256
 257static int sshkeycallback(CURL *easy,
 258                          const struct curl_khkey *knownkey, /* known */
 259                          const struct curl_khkey *foundkey, /* found */
 260                          enum curl_khmatch match,
 261                          void *clientp)
 262{
 263  (void)easy;
 264  (void)knownkey;
 265  (void)foundkey;
 266  (void)clientp;
 267
 268  /* we only allow perfect matches, and we reject everything else */
 269  return (match != CURLKHMATCH_OK) ? CURLKHSTAT_REJECT : CURLKHSTAT_FINE;
 270}
 271
 272static enum curl_khtype convert_ssh2_keytype(int sshkeytype)
 273{
 274  enum curl_khtype keytype = CURLKHTYPE_UNKNOWN;
 275  switch(sshkeytype) {
 276  case LIBSSH2_HOSTKEY_TYPE_RSA:
 277    keytype = CURLKHTYPE_RSA;
 278    break;
 279  case LIBSSH2_HOSTKEY_TYPE_DSS:
 280    keytype = CURLKHTYPE_DSS;
 281    break;
 282#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
 283  case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
 284    keytype = CURLKHTYPE_ECDSA;
 285    break;
 286#endif
 287#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
 288  case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
 289    keytype = CURLKHTYPE_ECDSA;
 290    break;
 291#endif
 292#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521
 293  case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
 294    keytype = CURLKHTYPE_ECDSA;
 295    break;
 296#endif
 297#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
 298  case LIBSSH2_HOSTKEY_TYPE_ED25519:
 299    keytype = CURLKHTYPE_ED25519;
 300    break;
 301#endif
 302  }
 303  return keytype;
 304}
 305
 306static CURLcode ssh_knownhost(struct Curl_easy *data,
 307                              struct ssh_conn *sshc)
 308{
 309  int sshkeytype = 0;
 310  size_t keylen = 0;
 311  int rc = 0;
 312  CURLcode result = CURLE_OK;
 313
 314  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
 315    /* we are asked to verify the host against a file */
 316    struct connectdata *conn = data->conn;
 317    struct libssh2_knownhost *host = NULL;
 318    const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
 319                                                    &keylen, &sshkeytype);
 320    int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
 321    int keybit = 0;
 322
 323    if(remotekey) {
 324      /*
 325       * A subject to figure out is what hostname we need to pass in here.
 326       * What hostname does OpenSSH store in its file if an IDN name is
 327       * used?
 328       */
 329      enum curl_khmatch keymatch;
 330      curl_sshkeycallback func =
 331        data->set.ssh_keyfunc ? data->set.ssh_keyfunc : sshkeycallback;
 332      struct curl_khkey knownkey;
 333      struct curl_khkey *knownkeyp = NULL;
 334      struct curl_khkey foundkey;
 335
 336      switch(sshkeytype) {
 337      case LIBSSH2_HOSTKEY_TYPE_RSA:
 338        keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
 339        break;
 340      case LIBSSH2_HOSTKEY_TYPE_DSS:
 341        keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
 342        break;
 343      case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
 344        keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
 345        break;
 346      case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
 347        keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
 348        break;
 349      case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
 350        keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
 351        break;
 352      case LIBSSH2_HOSTKEY_TYPE_ED25519:
 353        keybit = LIBSSH2_KNOWNHOST_KEY_ED25519;
 354        break;
 355      default:
 356        infof(data, "unsupported key type, cannot check knownhosts");
 357        keybit = 0;
 358        break;
 359      }
 360      if(!keybit)
 361        /* no check means failure! */
 362        rc = CURLKHSTAT_REJECT;
 363      else {
 364        keycheck = libssh2_knownhost_checkp(sshc->kh,
 365                                            conn->origin->hostname,
 366                                            (conn->origin->port != PORT_SSH) ?
 367                                            conn->origin->port : -1,
 368                                            remotekey, keylen,
 369                                            LIBSSH2_KNOWNHOST_TYPE_PLAIN|
 370                                            LIBSSH2_KNOWNHOST_KEYENC_RAW|
 371                                            keybit,
 372                                            &host);
 373
 374        infof(data, "SSH host check: %d, key: %s", keycheck,
 375              (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) ?
 376              host->key : "<none>");
 377
 378        /* setup 'knownkey' */
 379        if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
 380          knownkey.key = host->key;
 381          knownkey.len = 0;
 382          knownkey.keytype = convert_ssh2_keytype(sshkeytype);
 383          knownkeyp = &knownkey;
 384        }
 385
 386        /* setup 'foundkey' */
 387        foundkey.key = remotekey;
 388        foundkey.len = keylen;
 389        foundkey.keytype = convert_ssh2_keytype(sshkeytype);
 390
 391        /*
 392         * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
 393         * curl_khmatch enum are ever modified, we need to introduce a
 394         * translation table here!
 395         */
 396        keymatch = (enum curl_khmatch)keycheck;
 397
 398        /* Ask the callback how to behave */
 399        Curl_set_in_callback(data, TRUE);
 400        rc = func(data, knownkeyp, /* from the knownhosts file */
 401                  &foundkey, /* from the remote host */
 402                  keymatch, data->set.ssh_keyfunc_userp);
 403        Curl_set_in_callback(data, FALSE);
 404      }
 405    }
 406    else
 407      /* no remotekey means failure! */
 408      rc = CURLKHSTAT_REJECT;
 409
 410    switch(rc) {
 411    default: /* unknown return codes is the same as reject */
 412    case CURLKHSTAT_REJECT:
 413      myssh_to(data, sshc, SSH_SESSION_FREE);
 414      FALLTHROUGH();
 415    case CURLKHSTAT_DEFER:
 416      /* DEFER means bail out but keep the SSH_HOSTKEY state */
 417      result = CURLE_PEER_FAILED_VERIFICATION;
 418      break;
 419    case CURLKHSTAT_FINE_REPLACE:
 420      /* remove old host+key that does not match */
 421      if(host)
 422        libssh2_knownhost_del(sshc->kh, host);
 423      FALLTHROUGH();
 424    case CURLKHSTAT_FINE:
 425    case CURLKHSTAT_FINE_ADD_TO_FILE:
 426      /* proceed */
 427      if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
 428        /* the found host+key did not match but has been told to be fine
 429           anyway so we add it in memory */
 430        int addrc = libssh2_knownhost_add(sshc->kh,
 431                                          conn->origin->hostname, NULL,
 432                                          remotekey, keylen,
 433                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
 434                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
 435                                          keybit, NULL);
 436        if(addrc)
 437          infof(data, "WARNING: adding the known host %s failed",
 438                conn->origin->hostname);
 439        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE ||
 440                rc == CURLKHSTAT_FINE_REPLACE) {
 441          /* now we write the entire in-memory list of known hosts to the
 442             known_hosts file */
 443          int wrc =
 444            libssh2_knownhost_writefile(sshc->kh,
 445                                        data->set.str[STRING_SSH_KNOWNHOSTS],
 446                                        LIBSSH2_KNOWNHOST_FILE_OPENSSH);
 447          if(wrc) {
 448            infof(data, "WARNING: writing %s failed",
 449                  data->set.str[STRING_SSH_KNOWNHOSTS]);
 450          }
 451        }
 452      }
 453      break;
 454    }
 455  }
 456  return result;
 457}
 458
 459static CURLcode ssh_check_fingerprint(struct Curl_easy *data,
 460                                      struct ssh_conn *sshc)
 461{
 462  const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
 463  const char *pubkey_sha256 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_SHA256];
 464
 465  infof(data, "SSH MD5 public key: %s",
 466        pubkey_md5 != NULL ? pubkey_md5 : "NULL");
 467  infof(data, "SSH SHA256 public key: %s",
 468        pubkey_sha256 != NULL ? pubkey_sha256 : "NULL");
 469
 470  if(pubkey_sha256) {
 471    const char *fingerprint = NULL;
 472    char *fingerprint_b64 = NULL;
 473    size_t fingerprint_b64_len;
 474    size_t pub_pos = 0;
 475    size_t b64_pos = 0;
 476
 477    /* The fingerprint points to static storage (!), do not free() it. */
 478    fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
 479                                       LIBSSH2_HOSTKEY_HASH_SHA256);
 480    if(!fingerprint) {
 481      failf(data,
 482            "Denied establishing ssh session: SHA256 fingerprint "
 483            "not available");
 484      myssh_to(data, sshc, SSH_SESSION_FREE);
 485      return CURLE_PEER_FAILED_VERIFICATION;
 486    }
 487
 488    /* The length of fingerprint is 32 bytes for SHA256.
 489     * See libssh2_hostkey_hash documentation. */
 490    if(curlx_base64_encode((const uint8_t *)fingerprint, 32, &fingerprint_b64,
 491                           &fingerprint_b64_len) != CURLE_OK) {
 492      myssh_to(data, sshc, SSH_SESSION_FREE);
 493      return CURLE_PEER_FAILED_VERIFICATION;
 494    }
 495
 496    if(!fingerprint_b64) {
 497      failf(data, "SHA256 fingerprint could not be encoded");
 498      myssh_to(data, sshc, SSH_SESSION_FREE);
 499      return CURLE_PEER_FAILED_VERIFICATION;
 500    }
 501
 502    infof(data, "SSH SHA256 fingerprint: %s", fingerprint_b64);
 503
 504    /* Find the position of any = padding characters in the public key */
 505    while((pubkey_sha256[pub_pos] != '=') && pubkey_sha256[pub_pos]) {
 506      pub_pos++;
 507    }
 508
 509    /* Find the position of any = padding characters in the base64 coded
 510     * hostkey fingerprint */
 511    while((fingerprint_b64[b64_pos] != '=') && fingerprint_b64[b64_pos]) {
 512      b64_pos++;
 513    }
 514
 515    /* Before we authenticate we check the hostkey's SHA256 fingerprint
 516     * against a known fingerprint, if available.
 517     */
 518    if((pub_pos != b64_pos) ||
 519       strncmp(fingerprint_b64, pubkey_sha256, pub_pos)) {
 520      failf(data,
 521            "Denied establishing ssh session: mismatch SHA256 fingerprint. "
 522            "Remote %s is not equal to %s", fingerprint_b64, pubkey_sha256);
 523      curlx_free(fingerprint_b64);
 524      myssh_to(data, sshc, SSH_SESSION_FREE);
 525      return CURLE_PEER_FAILED_VERIFICATION;
 526    }
 527
 528    curlx_free(fingerprint_b64);
 529
 530    infof(data, "SHA256 checksum match");
 531  }
 532
 533  if(pubkey_md5) {
 534    char md5buffer[33];
 535    const char *fingerprint;
 536
 537    fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
 538                                       LIBSSH2_HOSTKEY_HASH_MD5);
 539
 540    if(fingerprint) {
 541      /* The fingerprint points to static storage (!), do not free() it. */
 542      int i;
 543      for(i = 0; i < 16; i++) {
 544        curl_msnprintf(&md5buffer[i * 2], 3, "%02x",
 545                       (unsigned char)fingerprint[i]);
 546      }
 547
 548      infof(data, "SSH MD5 fingerprint: %s", md5buffer);
 549    }
 550
 551    /* This does NOT verify the length of 'pubkey_md5' separately, which
 552       makes the comparison below fail unless it is exactly 32 characters */
 553    if(!fingerprint || !curl_strequal(md5buffer, pubkey_md5)) {
 554      if(fingerprint) {
 555        failf(data,
 556              "Denied establishing ssh session: mismatch MD5 fingerprint. "
 557              "Remote %s is not equal to %s", md5buffer, pubkey_md5);
 558      }
 559      else {
 560        failf(data,
 561              "Denied establishing ssh session: MD5 fingerprint "
 562              "not available");
 563      }
 564      myssh_to(data, sshc, SSH_SESSION_FREE);
 565      return CURLE_PEER_FAILED_VERIFICATION;
 566    }
 567    infof(data, "MD5 checksum match");
 568  }
 569
 570  if(!pubkey_md5 && !pubkey_sha256) {
 571    if(data->set.ssh_hostkeyfunc) {
 572      size_t keylen = 0;
 573      int sshkeytype = 0;
 574      int rc = 0;
 575      /* we handle the process to the callback */
 576      const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
 577                                                      &keylen, &sshkeytype);
 578      if(remotekey) {
 579        enum curl_khtype keytype = convert_ssh2_keytype(sshkeytype);
 580        Curl_set_in_callback(data, TRUE);
 581        rc = data->set.ssh_hostkeyfunc(data->set.ssh_hostkeyfunc_userp,
 582                                       (int)keytype, remotekey, keylen);
 583        Curl_set_in_callback(data, FALSE);
 584        if(rc != CURLKHMATCH_OK) {
 585          myssh_to(data, sshc, SSH_SESSION_FREE);
 586          return CURLE_PEER_FAILED_VERIFICATION;
 587        }
 588      }
 589      else {
 590        myssh_to(data, sshc, SSH_SESSION_FREE);
 591        return CURLE_PEER_FAILED_VERIFICATION;
 592      }
 593      return CURLE_OK;
 594    }
 595    else {
 596      return ssh_knownhost(data, sshc);
 597    }
 598  }
 599  else {
 600    /* as we already matched, we skip the check for known hosts */
 601    return CURLE_OK;
 602  }
 603}
 604
 605/*
 606 * ssh_force_knownhost_key_type() checks the known hosts file and try to
 607 * force a specific public key type from the server if an entry is found.
 608 */
 609static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data,
 610                                             struct ssh_conn *sshc)
 611{
 612  CURLcode result = CURLE_OK;
 613
 614  static const char hostkey_method_ssh_ed25519[] = "ssh-ed25519";
 615  static const char hostkey_method_ssh_ecdsa_521[] = "ecdsa-sha2-nistp521";
 616  static const char hostkey_method_ssh_ecdsa_384[] = "ecdsa-sha2-nistp384";
 617  static const char hostkey_method_ssh_ecdsa_256[] = "ecdsa-sha2-nistp256";
 618  static const char hostkey_method_ssh_rsa_all[] =
 619    "rsa-sha2-256,rsa-sha2-512,ssh-rsa";
 620  static const char hostkey_method_ssh_dss[] = "ssh-dss";
 621  bool found = FALSE;
 622
 623  if(sshc->kh &&
 624     !data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
 625     !data->set.str[STRING_SSH_HOST_PUBLIC_KEY_SHA256]) {
 626    struct libssh2_knownhost *store = NULL;
 627    struct connectdata *conn = data->conn;
 628    /* lets try to find our host in the known hosts file */
 629    while(!libssh2_knownhost_get(sshc->kh, &store, store)) {
 630      /* For non-standard ports, the name is enclosed in */
 631      /* square brackets, followed by a colon and the port */
 632      if(store) {
 633        if(store->name) {
 634          if(store->name[0] == '[') {
 635            curl_off_t port;
 636            size_t kh_name_size = 0;
 637            const char *p;
 638            const char *kh_name_end = strstr(store->name, "]:");
 639            if(!kh_name_end) {
 640              infof(data, "Invalid host pattern %s in %s",
 641                    store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
 642              continue;
 643            }
 644            p = kh_name_end + 2; /* start of port number */
 645            if(!curlx_str_number(&p, &port, 0xffff) &&
 646               (kh_name_end && (port == conn->origin->port))) {
 647              kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end);
 648              if(strncmp(store->name + 1,
 649                         conn->origin->hostname, kh_name_size) == 0) {
 650                found = TRUE;
 651                break;
 652              }
 653            }
 654          }
 655          else if(strcmp(store->name, conn->origin->hostname) == 0) {
 656            found = TRUE;
 657            break;
 658          }
 659        }
 660        else {
 661          found = TRUE;
 662          break;
 663        }
 664      }
 665    }
 666
 667    if(found) {
 668      int rc;
 669      const char *hostkey_method = NULL;
 670      infof(data, "Found host %s in %s",
 671            conn->origin->hostname, data->set.str[STRING_SSH_KNOWNHOSTS]);
 672
 673      switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
 674      case LIBSSH2_KNOWNHOST_KEY_ED25519:
 675        hostkey_method = hostkey_method_ssh_ed25519;
 676        break;
 677      case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
 678        hostkey_method = hostkey_method_ssh_ecdsa_521;
 679        break;
 680      case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
 681        hostkey_method = hostkey_method_ssh_ecdsa_384;
 682        break;
 683      case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
 684        hostkey_method = hostkey_method_ssh_ecdsa_256;
 685        break;
 686      case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
 687        hostkey_method = hostkey_method_ssh_rsa_all;
 688        break;
 689      case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
 690        hostkey_method = hostkey_method_ssh_dss;
 691        break;
 692      case LIBSSH2_KNOWNHOST_KEY_RSA1:
 693        failf(data, "Found host key type RSA1 which is not supported");
 694        return CURLE_SSH;
 695      default:
 696        failf(data, "Unknown host key type: %i",
 697              (store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK));
 698        return CURLE_SSH;
 699      }
 700
 701      infof(data, "Set \"%s\" as SSH hostkey type", hostkey_method);
 702      rc = libssh2_session_method_pref(sshc->ssh_session,
 703                                       LIBSSH2_METHOD_HOSTKEY, hostkey_method);
 704      if(rc) {
 705        char *err_msg = NULL;
 706        int errlen;
 707        libssh2_session_last_error(sshc->ssh_session, &err_msg, &errlen, 0);
 708        failf(data, "libssh2 method '%s' failed: %s", hostkey_method, err_msg);
 709        result = libssh2_session_error_to_CURLE(rc);
 710      }
 711    }
 712    else {
 713      infof(data, "Did not find host %s in %s",
 714            conn->origin->hostname, data->set.str[STRING_SSH_KNOWNHOSTS]);
 715    }
 716  }
 717
 718  return result;
 719}
 720
 721static CURLcode quote_error(struct Curl_easy *data,
 722                            struct ssh_conn *sshc)
 723{
 724  failf(data, "Suspicious data after the command line");
 725  curlx_safefree(sshc->quote_path1);
 726  curlx_safefree(sshc->quote_path2);
 727  return CURLE_QUOTE_ERROR;
 728}
 729
 730static CURLcode sftp_quote(struct Curl_easy *data,
 731                           struct ssh_conn *sshc,
 732                           struct SSHPROTO *sshp)
 733{
 734  const char *cp;
 735  CURLcode result = CURLE_OK;
 736
 737  /*
 738   * Support some of the "FTP" commands
 739   *
 740   * 'sshc->quote_item' is already verified to be non-NULL before it
 741   * switched to this state.
 742   */
 743  const char *cmd = sshc->quote_item->data;
 744  sshc->acceptfail = FALSE;
 745
 746  /* if a command starts with an asterisk, which a legal SFTP command never
 747     can, the command is allowed to fail without it causing any
 748     aborts or cancels etc. It causes libcurl to act as if the command
 749     is successful, whatever the server responds. */
 750
 751  if(cmd[0] == '*') {
 752    cmd++;
 753    sshc->acceptfail = TRUE;
 754  }
 755
 756  if(curl_strequal("pwd", cmd)) {
 757    /* output debug output if that is requested */
 758    char *tmp = curl_maprintf("257 \"%s\" is current directory.\n",
 759                              sshp->path);
 760    if(!tmp)
 761      return CURLE_OUT_OF_MEMORY;
 762    Curl_debug(data, CURLINFO_HEADER_OUT, "PWD\n", 4);
 763    Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
 764
 765    /* this sends an FTP-like "header" to the header callback so that
 766       the current directory can be read similar to how it is read when
 767       using ordinary FTP. */
 768    result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
 769    curlx_free(tmp);
 770    if(!result)
 771      myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
 772    return result;
 773  }
 774
 775  /*
 776   * the arguments following the command must be separated from the
 777   * command with a space so we can check for it unconditionally
 778   */
 779  cp = strchr(cmd, ' ');
 780  if(!cp) {
 781    failf(data, "Syntax error command '%s', missing parameter", cmd);
 782    return result;
 783  }
 784
 785  /*
 786   * also, every command takes at least one argument so we get that
 787   * first argument right now
 788   */
 789  result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
 790  if(result) {
 791    if(result != CURLE_OUT_OF_MEMORY)
 792      failf(data, "Syntax error: Bad first parameter to '%s'", cmd);
 793    return result;
 794  }
 795
 796  /*
 797   * SFTP is a binary protocol, so we do not send text commands to the server.
 798   * Instead, we scan for commands used by OpenSSH's sftp program and call the
 799   * appropriate libssh2 functions.
 800   */
 801  if(!strncmp(cmd, "chgrp ", 6) ||
 802     !strncmp(cmd, "chmod ", 6) ||
 803     !strncmp(cmd, "chown ", 6) ||
 804     !strncmp(cmd, "atime ", 6) ||
 805     !strncmp(cmd, "mtime ", 6)) {
 806    /* attribute change */
 807
 808    /* sshc->quote_path1 contains the mode to set */
 809    /* get the destination */
 810    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
 811    if(result) {
 812      if(result != CURLE_OUT_OF_MEMORY)
 813        failf(data, "Syntax error in %s: Bad second parameter", cmd);
 814      curlx_safefree(sshc->quote_path1);
 815      return result;
 816    }
 817    if(*cp)
 818      return quote_error(data, sshc);
 819
 820    memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
 821    myssh_to(data, sshc, SSH_SFTP_QUOTE_STAT);
 822    return result;
 823  }
 824  if(!strncmp(cmd, "ln ", 3) ||
 825     !strncmp(cmd, "symlink ", 8)) {
 826    /* symbolic linking */
 827    /* sshc->quote_path1 is the source */
 828    /* get the destination */
 829    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
 830    if(result) {
 831      if(result != CURLE_OUT_OF_MEMORY)
 832        failf(data, "Syntax error in ln/symlink: Bad second parameter");
 833      curlx_safefree(sshc->quote_path1);
 834      return result;
 835    }
 836    if(*cp)
 837      return quote_error(data, sshc);
 838    myssh_to(data, sshc, SSH_SFTP_QUOTE_SYMLINK);
 839    return result;
 840  }
 841  else if(!strncmp(cmd, "mkdir ", 6)) {
 842    if(*cp)
 843      return quote_error(data, sshc);
 844    /* create directory */
 845    myssh_to(data, sshc, SSH_SFTP_QUOTE_MKDIR);
 846    return result;
 847  }
 848  else if(!strncmp(cmd, "rename ", 7)) {
 849    /* rename file */
 850    /* first param is the source path */
 851    /* second param is the dest. path */
 852    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
 853    if(result) {
 854      if(result != CURLE_OUT_OF_MEMORY)
 855        failf(data, "Syntax error in rename: Bad second parameter");
 856      curlx_safefree(sshc->quote_path1);
 857      return result;
 858    }
 859    if(*cp)
 860      return quote_error(data, sshc);
 861    myssh_to(data, sshc, SSH_SFTP_QUOTE_RENAME);
 862    return result;
 863  }
 864  else if(!strncmp(cmd, "rmdir ", 6)) {
 865    if(*cp)
 866      return quote_error(data, sshc);
 867    /* delete directory */
 868    myssh_to(data, sshc, SSH_SFTP_QUOTE_RMDIR);
 869    return result;
 870  }
 871  else if(!strncmp(cmd, "rm ", 3)) {
 872    if(*cp)
 873      return quote_error(data, sshc);
 874    myssh_to(data, sshc, SSH_SFTP_QUOTE_UNLINK);
 875    return result;
 876  }
 877  else if(!strncmp(cmd, "statvfs ", 8)) {
 878    if(*cp)
 879      return quote_error(data, sshc);
 880    myssh_to(data, sshc, SSH_SFTP_QUOTE_STATVFS);
 881    return result;
 882  }
 883
 884  failf(data, "Unknown SFTP command");
 885  curlx_safefree(sshc->quote_path1);
 886  curlx_safefree(sshc->quote_path2);
 887  return CURLE_QUOTE_ERROR;
 888}
 889
 890static CURLcode sftp_upload_init(struct Curl_easy *data,
 891                                 struct ssh_conn *sshc,
 892                                 struct SSHPROTO *sshp,
 893                                 bool *blockp)
 894{
 895  unsigned long flags;
 896
 897  /*
 898   * NOTE!!!  libssh2 requires that the destination path is a full path
 899   *          that includes the destination file and name OR ends in a "/"
 900   *          If this is not done the destination file is named the
 901   *          same name as the last directory in the path.
 902   */
 903
 904  if(data->state.resume_from) {
 905    LIBSSH2_SFTP_ATTRIBUTES attrs;
 906    if(data->state.resume_from < 0) {
 907      int rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
 908                                    curlx_uztoui(strlen(sshp->path)),
 909                                    LIBSSH2_SFTP_STAT, &attrs);
 910      if(rc == LIBSSH2_ERROR_EAGAIN) {
 911        *blockp = TRUE;
 912        return CURLE_OK;
 913      }
 914      if(rc) {
 915        data->state.resume_from = 0;
 916      }
 917      else {
 918        curl_off_t size = attrs.filesize;
 919        if(size < 0) {
 920          failf(data, "Bad file size (%" FMT_OFF_T ")", size);
 921          return CURLE_BAD_DOWNLOAD_RESUME;
 922        }
 923        data->state.resume_from = attrs.filesize;
 924      }
 925    }
 926  }
 927
 928  if(data->set.remote_append) {
 929    /* True append mode: create if nonexisting */
 930    flags = LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_APPEND;
 931  }
 932  else if(data->state.resume_from > 0) {
 933    /*
 934     * Resume MUST NOT use APPEND; some servers force writes to EOF when
 935     * APPEND is set, ignoring a prior seek().
 936     */
 937    flags = LIBSSH2_FXF_WRITE;
 938  }
 939  else {
 940    /* Clear file before writing (normal behavior) */
 941    flags = LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC;
 942  }
 943
 944  sshc->sftp_handle =
 945    libssh2_sftp_open_ex(sshc->sftp_session, sshp->path,
 946                         curlx_uztoui(strlen(sshp->path)),
 947                         flags, (long)data->set.new_file_perms,
 948                         LIBSSH2_SFTP_OPENFILE);
 949
 950  if(!sshc->sftp_handle) {
 951    CURLcode result;
 952    unsigned long sftperr;
 953    int rc = libssh2_session_last_errno(sshc->ssh_session);
 954
 955    if(LIBSSH2_ERROR_EAGAIN == rc) {
 956      *blockp = TRUE;
 957      return CURLE_OK;
 958    }
 959
 960    if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
 961      /* only when there was an SFTP protocol error can we extract
 962         the sftp error! */
 963      sftperr = libssh2_sftp_last_error(sshc->sftp_session);
 964    else
 965      sftperr = LIBSSH2_FX_OK; /* not an sftp error at all */
 966
 967    if(sshc->secondCreateDirs) {
 968      myssh_to(data, sshc, SSH_SFTP_CLOSE);
 969      failf(data, "Creating the dir/file failed: %s",
 970            sftp_libssh2_strerror(sftperr));
 971      return sftp_libssh2_error_to_CURLE(sftperr);
 972    }
 973    if((sftperr == LIBSSH2_FX_NO_SUCH_FILE ||
 974        sftperr == LIBSSH2_FX_FAILURE ||
 975        sftperr == LIBSSH2_FX_NO_SUCH_PATH) &&
 976       data->set.ftp_create_missing_dirs &&
 977       (strlen(sshp->path) > 1)) {
 978      /* try to create the path remotely */
 979      sshc->secondCreateDirs = 1;
 980      myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_INIT);
 981      return CURLE_OK;
 982    }
 983    myssh_to(data, sshc, SSH_SFTP_CLOSE);
 984    result = sftp_libssh2_error_to_CURLE(sftperr);
 985    if(!result) {
 986      /* Sometimes, for some reason libssh2_sftp_last_error() returns zero
 987         even though libssh2_sftp_open() failed previously! We need to
 988         work around that! */
 989      result = CURLE_SSH;
 990      sftperr = LIBSSH2_FX_OK;
 991    }
 992    failf(data, "Upload failed: %s (%lu/%d)",
 993          sftperr != LIBSSH2_FX_OK ?
 994          sftp_libssh2_strerror(sftperr) : "ssh error",
 995          sftperr, rc);
 996    return result;
 997  }
 998
 999  /* If we have a restart point then we need to seek to the correct
1000     Skip if in explicit remote append mode. */
1001  if(data->state.resume_from > 0 && !data->set.remote_append) {
1002    int seekerr = CURL_SEEKFUNC_OK;
1003    /* Let's read off the proper amount of bytes from the input. */
1004    if(data->set.seek_func) {
1005      Curl_set_in_callback(data, TRUE);
1006      seekerr = data->set.seek_func(data->set.seek_client,
1007                                    data->state.resume_from, SEEK_SET);
1008      Curl_set_in_callback(data, FALSE);
1009    }
1010
1011    if(seekerr != CURL_SEEKFUNC_OK) {
1012      curl_off_t passed = 0;
1013
1014      if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1015        failf(data, "Could not seek stream");
1016        return CURLE_FTP_COULDNT_USE_REST;
1017      }
1018      /* seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */
1019      do {
1020        char scratch[4 * 1024];
1021        size_t readthisamountnow =
1022          (data->state.resume_from - passed >
1023           (curl_off_t)sizeof(scratch)) ?
1024          sizeof(scratch) : curlx_sotouz(data->state.resume_from - passed);
1025
1026        size_t actuallyread;
1027        Curl_set_in_callback(data, TRUE);
1028        actuallyread = data->state.fread_func(scratch, 1,
1029                                              readthisamountnow,
1030                                              data->state.in);
1031        Curl_set_in_callback(data, FALSE);
1032
1033        passed += actuallyread;
1034        if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1035          /* this checks for greater-than only to make sure that the
1036             CURL_READFUNC_ABORT return code still aborts */
1037          failf(data, "Failed to read data");
1038          return CURLE_FTP_COULDNT_USE_REST;
1039        }
1040      } while(passed < data->state.resume_from);
1041    }
1042
1043    /* now, decrease the size of the read */
1044    if(data->state.infilesize > 0) {
1045      data->state.infilesize -= data->state.resume_from;
1046      data->req.size = data->state.infilesize;
1047      Curl_pgrsSetUploadSize(data, data->state.infilesize);
1048    }
1049
1050    libssh2_sftp_seek64(sshc->sftp_handle,
1051                        (libssh2_uint64_t)data->state.resume_from);
1052  }
1053  if(data->state.infilesize > 0) {
1054    data->req.size = data->state.infilesize;
1055    Curl_pgrsSetUploadSize(data, data->state.infilesize);
1056  }
1057  /* upload data */
1058  Curl_xfer_setup_send(data, FIRSTSOCKET);
1059
1060  /* not set by Curl_xfer_setup to preserve io_flags */
1061  data->conn->recv_idx = FIRSTSOCKET;
1062
1063  /* since we do not really wait for anything at this point, we want the
1064     state machine to move on as soon as possible so mark this as dirty */
1065  Curl_multi_mark_dirty(data);
1066
1067  myssh_to(data, sshc, SSH_STOP);
1068  return CURLE_OK;
1069}
1070
1071static CURLcode ssh_state_pkey_init(struct Curl_easy *data,
1072                                    struct ssh_conn *sshc)
1073{
1074  /*
1075   * Check the supported auth types in the order I feel is most secure
1076   * with the requested type of authentication
1077   */
1078  sshc->authed = FALSE;
1079
1080  if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
1081     (strstr(sshc->authlist, "publickey") != NULL)) {
1082    bool out_of_memory = FALSE;
1083
1084    sshc->rsa_pub = sshc->rsa = NULL;
1085
1086    if(data->set.str[STRING_SSH_PRIVATE_KEY]) {
1087      sshc->rsa = curlx_strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
1088      if(!sshc->rsa)
1089        out_of_memory = TRUE;
1090    }
1091    else {
1092      /* To ponder about: should really the lib be messing about with the
1093         HOME environment variable etc? */
1094      char *home = curl_getenv("HOME");
1095      curlx_struct_stat sbuf;
1096
1097      /* If no private key file is specified, try some common paths. */
1098      if(home) {
1099        /* Try ~/.ssh first. */
1100        sshc->rsa = curl_maprintf("%s/.ssh/id_rsa", home);
1101        if(!sshc->rsa)
1102          out_of_memory = TRUE;
1103        else if(curlx_stat(sshc->rsa, &sbuf)) {
1104          curlx_free(sshc->rsa);
1105          sshc->rsa = curl_maprintf("%s/.ssh/id_dsa", home);
1106          if(!sshc->rsa)
1107            out_of_memory = TRUE;
1108          else if(curlx_stat(sshc->rsa, &sbuf)) {
1109            curlx_safefree(sshc->rsa);
1110          }
1111        }
1112        curlx_free(home);
1113      }
1114      if(!out_of_memory && !sshc->rsa) {
1115        /* Nothing found; try the current dir. */
1116        sshc->rsa = curlx_strdup("id_rsa");
1117        if(sshc->rsa && curlx_stat(sshc->rsa, &sbuf)) {
1118          curlx_free(sshc->rsa);
1119          sshc->rsa = curlx_strdup("id_dsa");
1120          if(sshc->rsa && curlx_stat(sshc->rsa, &sbuf)) {
1121            curlx_free(sshc->rsa);
1122            /* Out of guesses. Set to the empty string to avoid
1123             * surprising info messages. */
1124            sshc->rsa = curlx_strdup("");
1125          }
1126        }
1127      }
1128    }
1129
1130    /*
1131     * Unless the user explicitly specifies a public key file, let
1132     * libssh2 extract the public key from the private key file.
1133     * This is done by passing sshc->rsa_pub = NULL.
1134     */
1135    if(!out_of_memory && data->set.str[STRING_SSH_PUBLIC_KEY] &&
1136       /* treat empty string the same way as NULL */
1137       data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
1138      sshc->rsa_pub = curlx_strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
1139      if(!sshc->rsa_pub)
1140        out_of_memory = TRUE;
1141    }
1142
1143    if(out_of_memory || !sshc->rsa) {
1144      curlx_safefree(sshc->rsa);
1145      curlx_safefree(sshc->rsa_pub);
1146      myssh_to(data, sshc, SSH_SESSION_FREE);
1147      return CURLE_OUT_OF_MEMORY;
1148    }
1149
1150    sshc->passphrase = data->set.ssl.key_passwd;
1151    if(!sshc->passphrase)
1152      sshc->passphrase = "";
1153
1154    if(sshc->rsa_pub)
1155      infof(data, "Using SSH public key file '%s'", sshc->rsa_pub);
1156    infof(data, "Using SSH private key file '%s'", sshc->rsa);
1157
1158    myssh_to(data, sshc, SSH_AUTH_PKEY);
1159  }
1160  else {
1161    myssh_to(data, sshc, SSH_AUTH_PASS_INIT);
1162  }
1163  return CURLE_OK;
1164}
1165
1166static CURLcode sftp_quote_stat(struct Curl_easy *data,
1167                                struct ssh_conn *sshc,
1168                                struct SSHPROTO *sshp,
1169                                bool *blockp)
1170{
1171  const char *cmd = sshc->quote_item->data;
1172  sshc->acceptfail = FALSE;
1173
1174  /* if a command starts with an asterisk, which a legal SFTP command never
1175     can, the command is allowed to fail without it causing any aborts or
1176     cancels etc. It causes libcurl to act as if the command is
1177     successful, whatever the server responds. */
1178
1179  if(cmd[0] == '*') {
1180    cmd++;
1181    sshc->acceptfail = TRUE;
1182  }
1183
1184  if(!!strncmp(cmd, "chmod", 5)) {
1185    /* Since chown and chgrp only set owner OR group but libssh2 wants to set
1186     * them both at once, we need to obtain the current ownership first. This
1187     * takes an extra protocol round trip.
1188     */
1189    int rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1190                                  curlx_uztoui(strlen(sshc->quote_path2)),
1191                                  LIBSSH2_SFTP_STAT,
1192                                  &sshp->quote_attrs);
1193    if(rc == LIBSSH2_ERROR_EAGAIN) {
1194      *blockp = TRUE;
1195      return CURLE_OK;
1196    }
1197    if(rc && !sshc->acceptfail) { /* get those attributes */
1198      unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1199      failf(data, "Attempt to get SFTP stats failed: %s",
1200            sftp_libssh2_strerror(sftperr));
1201      goto fail;
1202    }
1203  }
1204
1205  /* Now set the new attributes... */
1206  if(!strncmp(cmd, "chgrp", 5)) {
1207    const char *p = sshc->quote_path1;
1208    curl_off_t gid;
1209    if(!curlx_str_number(&p, &gid, ULONG_MAX)) {
1210      sshp->quote_attrs.gid = (unsigned long)gid;
1211      sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1212    }
1213    else if(!sshc->acceptfail) {
1214      failf(data, "Syntax error: chgrp gid not a number");
1215      goto fail;
1216    }
1217  }
1218  else if(!strncmp(cmd, "chmod", 5)) {
1219    curl_off_t perms;
1220    const char *p = sshc->quote_path1;
1221    /* permissions are octal */
1222    if(curlx_str_octal(&p, &perms, 07777)) {
1223      failf(data, "Syntax error: chmod permissions not a number");
1224      goto fail;
1225    }
1226
1227    sshp->quote_attrs.permissions = (unsigned long)perms;
1228    sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1229  }
1230  else if(!strncmp(cmd, "chown", 5)) {
1231    const char *p = sshc->quote_path1;
1232    curl_off_t uid;
1233    if(!curlx_str_number(&p, &uid, ULONG_MAX)) {
1234      sshp->quote_attrs.uid = (unsigned long)uid;
1235      sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1236    }
1237    else if(!sshc->acceptfail) {
1238      failf(data, "Syntax error: chown uid not a number");
1239      goto fail;
1240    }
1241  }
1242  else if(!strncmp(cmd, "atime", 5) ||
1243          !strncmp(cmd, "mtime", 5)) {
1244    time_t date;
1245    bool fail = FALSE;
1246
1247    if(Curl_getdate_capped(sshc->quote_path1, &date)) {
1248      failf(data, "incorrect date format for %.*s", 5, cmd);
1249      fail = TRUE;
1250    }
1251#if SIZEOF_TIME_T > SIZEOF_LONG
1252    if(date > 0xffffffff) {
1253      /* if 'long' cannot hold >32-bit, this date cannot be sent */
1254      failf(data, "date overflow");
1255      fail = TRUE;
1256    }
1257#endif
1258    if(fail)
1259      goto fail;
1260    if(!strncmp(cmd, "atime", 5))
1261      sshp->quote_attrs.atime = (unsigned long)date;
1262    else /* mtime */
1263      sshp->quote_attrs.mtime = (unsigned long)date;
1264
1265    sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
1266  }
1267
1268  /* Now send the completed structure... */
1269  myssh_to(data, sshc, SSH_SFTP_QUOTE_SETSTAT);
1270  return CURLE_OK;
1271fail:
1272  curlx_safefree(sshc->quote_path1);
1273  curlx_safefree(sshc->quote_path2);
1274  return CURLE_QUOTE_ERROR;
1275}
1276
1277static CURLcode sftp_download_stat(struct Curl_easy *data,
1278                                   struct ssh_conn *sshc,
1279                                   struct SSHPROTO *sshp,
1280                                   bool *blockp)
1281{
1282  LIBSSH2_SFTP_ATTRIBUTES attrs;
1283  int rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
1284                                curlx_uztoui(strlen(sshp->path)),
1285                                LIBSSH2_SFTP_STAT, &attrs);
1286  if(rc == LIBSSH2_ERROR_EAGAIN) {
1287    *blockp = TRUE;
1288    return CURLE_OK;
1289  }
1290  if(rc ||
1291     !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
1292     (attrs.filesize == 0)) {
1293    /*
1294     * libssh2_sftp_open() did not return an error, so maybe the server
1295     * does not support stat()
1296     * OR the server does not return a file size with a stat()
1297     * OR file size is 0
1298     */
1299    data->req.size = -1;
1300    data->req.maxdownload = -1;
1301    Curl_pgrsSetDownloadSize(data, -1);
1302    attrs.filesize = 0; /* might be uninitialized but is read below */
1303  }
1304  else {
1305    curl_off_t size = attrs.filesize;
1306
1307    if(size < 0) {
1308      failf(data, "Bad file size (%" FMT_OFF_T ")", size);
1309      return CURLE_BAD_DOWNLOAD_RESUME;
1310    }
1311    if(data->state.use_range) {
1312      curl_off_t from;
1313      CURLcode result = Curl_ssh_range(data, data->state.range, size,
1314                                       &from, &size);
1315      if(result)
1316        return result;
1317
1318      libssh2_sftp_seek64(sshc->sftp_handle, (libssh2_uint64_t)from);
1319    }
1320    data->req.size = size;
1321    data->req.maxdownload = size;
1322    Curl_pgrsSetDownloadSize(data, size);
1323  }
1324
1325  /* We can resume if we can seek to the resume position */
1326  if(data->state.resume_from) {
1327    if(data->state.resume_from < 0) {
1328      /* We are supposed to download the last abs(from) bytes */
1329      if((curl_off_t)attrs.filesize < -data->state.resume_from) {
1330        failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%"
1331              FMT_OFF_T ")",
1332              data->state.resume_from, (curl_off_t)attrs.filesize);
1333        return CURLE_BAD_DOWNLOAD_RESUME;
1334      }
1335      /* download from where? */
1336      data->state.resume_from += attrs.filesize;
1337    }
1338    else {
1339      if((curl_off_t)attrs.filesize < data->state.resume_from) {
1340        failf(data, "Offset (%" FMT_OFF_T
1341              ") was beyond file size (%" FMT_OFF_T ")",
1342              data->state.resume_from, (curl_off_t)attrs.filesize);
1343        return CURLE_BAD_DOWNLOAD_RESUME;
1344      }
1345    }
1346    /* Now store the number of bytes we are expected to download */
1347    data->req.size = attrs.filesize - data->state.resume_from;
1348    data->req.maxdownload = attrs.filesize - data->state.resume_from;
1349    Curl_pgrsSetDownloadSize(data, attrs.filesize - data->state.resume_from);
1350    libssh2_sftp_seek64(sshc->sftp_handle,
1351                        (libssh2_uint64_t)data->state.resume_from);
1352  }
1353
1354  /* Setup the actual download */
1355  if(data->req.size == 0) {
1356    /* no data to transfer */
1357    Curl_xfer_setup_nop(data);
1358    infof(data, "File already completely downloaded");
1359    myssh_to(data, sshc, SSH_STOP);
1360    return CURLE_OK;
1361  }
1362  Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size);
1363
1364  /* not set by Curl_xfer_setup to preserve io_flags */
1365  data->conn->send_idx = 0;
1366
1367  myssh_to(data, sshc, SSH_STOP);
1368
1369  return CURLE_OK;
1370}
1371
1372static CURLcode sftp_readdir(struct Curl_easy *data,
1373                             struct ssh_conn *sshc,
1374                             struct SSHPROTO *sshp,
1375                             bool *blockp)
1376{
1377  CURLcode result = CURLE_OK;
1378  int rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1379                                   sshp->readdir_filename, CURL_PATH_MAX,
1380                                   sshp->readdir_longentry, CURL_PATH_MAX,
1381                                   &sshp->readdir_attrs);
1382  if(rc == LIBSSH2_ERROR_EAGAIN) {
1383    *blockp = TRUE;
1384    return result;
1385  }
1386  if(rc > 0) {
1387    size_t readdir_len = (size_t)rc;
1388    sshp->readdir_filename[readdir_len] = '\0';
1389
1390    if(data->set.list_only) {
1391      result = Curl_client_write(data, CLIENTWRITE_BODY,
1392                                 sshp->readdir_filename,
1393                                 readdir_len);
1394      if(!result)
1395        result = Curl_client_write(data, CLIENTWRITE_BODY, "\n", 1);
1396      if(result)
1397        return result;
1398    }
1399    else {
1400      result = curlx_dyn_add(&sshp->readdir, sshp->readdir_longentry);
1401
1402      if(!result) {
1403        if((sshp->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1404           ((sshp->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1405            LIBSSH2_SFTP_S_IFLNK)) {
1406          result = curlx_dyn_addf(&sshp->readdir_link, "%s%s", sshp->path,
1407                                  sshp->readdir_filename);
1408          myssh_to(data, sshc, SSH_SFTP_READDIR_LINK);
1409        }
1410        else {
1411          myssh_to(data, sshc, SSH_SFTP_READDIR_BOTTOM);
1412        }
1413      }
1414      return result;
1415    }
1416  }
1417  else if(!rc) {
1418    myssh_to(data, sshc, SSH_SFTP_READDIR_DONE);
1419  }
1420  else {
1421    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1422    result = sftperr ? sftp_libssh2_error_to_CURLE(sftperr) : CURLE_SSH;
1423    failf(data, "Could not open remote file for reading: %s :: %d",
1424          sftp_libssh2_strerror(sftperr),
1425          libssh2_session_last_errno(sshc->ssh_session));
1426    myssh_to(data, sshc, SSH_SFTP_CLOSE);
1427  }
1428  return result;
1429}
1430
1431static CURLcode ssh_state_init(struct Curl_easy *data,
1432                               struct ssh_conn *sshc)
1433{
1434  CURLcode result;
1435  sshc->secondCreateDirs = 0;
1436  sshc->nextstate = SSH_NO_STATE;
1437
1438  /* Set libssh2 to non-blocking, since everything internally is
1439     non-blocking */
1440  libssh2_session_set_blocking(sshc->ssh_session, 0);
1441
1442  result = ssh_force_knownhost_key_type(data, sshc);
1443  if(result)
1444    myssh_to(data, sshc, SSH_SESSION_FREE);
1445  else
1446    myssh_to(data, sshc, SSH_S_STARTUP);
1447  return result;
1448}
1449
1450static CURLcode ssh_state_startup(struct Curl_easy *data,
1451                                  struct ssh_conn *sshc)
1452{
1453  struct connectdata *conn = data->conn;
1454  int rc = libssh2_session_handshake(sshc->ssh_session,
1455                                     conn->sock[FIRSTSOCKET]);
1456  if(rc == LIBSSH2_ERROR_EAGAIN)
1457    return CURLE_AGAIN;
1458
1459  if(rc) {
1460    char *err_msg = NULL;
1461    (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
1462    failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg);
1463
1464    myssh_to(data, sshc, SSH_SESSION_FREE);
1465    return CURLE_FAILED_INIT;
1466  }
1467
1468  myssh_to(data, sshc, SSH_HOSTKEY);
1469  return CURLE_OK;
1470}
1471
1472static CURLcode ssh_state_hostkey(struct Curl_easy *data,
1473                                  struct ssh_conn *sshc)
1474{
1475  /*
1476   * Before we authenticate we should check the hostkey's fingerprint
1477   * against our known hosts. How that is handled (reading from file,
1478   * whatever) is up to us.
1479   */
1480  CURLcode result = ssh_check_fingerprint(data, sshc);
1481  if(!result)
1482    myssh_to(data, sshc, SSH_AUTHLIST);
1483  return result;
1484}
1485
1486static CURLcode ssh_state_authlist(struct Curl_easy *data,
1487                                   struct ssh_conn *sshc)
1488{
1489  /*
1490   * Figure out authentication methods
1491   * NB: As soon as we have provided a username to an openssh server we
1492   * must never change it later. Thus, always specify the correct username
1493   * here, even though the libssh2 docs kind of indicate that it should be
1494   * possible to get a 'generic' list (not user-specific) of authentication
1495   * methods, presumably with a blank username. That does not work in my
1496   * experience.
1497   * Therefore always specify it here.
1498   */
1499  struct connectdata *conn = data->conn;
1500  const char *user = Curl_creds_user(conn->creds);
1501  sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
1502                                         user, curlx_uztoui(strlen(user)));
1503
1504  if(!sshc->authlist) {
1505    int rc;
1506    if(libssh2_userauth_authenticated(sshc->ssh_session)) {
1507      sshc->authed = TRUE;
1508      infof(data, "SSH user accepted with no authentication");
1509      myssh_to(data, sshc, SSH_AUTH_DONE);
1510      return CURLE_OK;
1511    }
1512    rc = libssh2_session_last_errno(sshc->ssh_session);
1513    if(rc == LIBSSH2_ERROR_EAGAIN)
1514      return CURLE_AGAIN;
1515
1516    myssh_to(data, sshc, SSH_SESSION_FREE);
1517    return libssh2_session_error_to_CURLE(rc);
1518  }
1519  infof(data, "SSH authentication methods available: %s", sshc->authlist);
1520
1521  myssh_to(data, sshc, SSH_AUTH_PKEY_INIT);
1522  return CURLE_OK;
1523}
1524
1525static CURLcode ssh_state_auth_pkey(struct Curl_easy *data,
1526                                    struct ssh_conn *sshc)
1527{
1528  /* The function below checks if the files exists, no need to stat() here.
1529   */
1530  struct connectdata *conn = data->conn;
1531  const char *user = Curl_creds_user(conn->creds);
1532  int rc =
1533    libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
1534                                           user,
1535                                           curlx_uztoui(strlen(user)),
1536                                           sshc->rsa_pub,
1537                                           sshc->rsa, sshc->passphrase);
1538  if(rc == LIBSSH2_ERROR_EAGAIN)
1539    return CURLE_AGAIN;
1540
1541  curlx_safefree(sshc->rsa_pub);
1542  curlx_safefree(sshc->rsa);
1543
1544  if(rc == 0) {
1545    sshc->authed = TRUE;
1546    infof(data, "Initialized SSH public key authentication");
1547    myssh_to(data, sshc, SSH_AUTH_DONE);
1548  }
1549  else {
1550    char *err_msg = NULL;
1551    char unknown[] = "Reason unknown (-1)";
1552    if(rc == -1) {
1553      /* No error message has been set and the last set error message, if
1554         any, is from a previous error so ignore it. #11837 */
1555      err_msg = unknown;
1556    }
1557    else {
1558      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
1559    }
1560    infof(data, "SSH public key authentication failed: %s", err_msg);
1561    myssh_to(data, sshc, SSH_AUTH_PASS_INIT);
1562  }
1563  return CURLE_OK;
1564}
1565
1566static CURLcode ssh_state_auth_pass_init(struct Curl_easy *data,
1567                                         struct ssh_conn *sshc)
1568{
1569  if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
1570     (strstr(sshc->authlist, "password") != NULL)) {
1571    myssh_to(data, sshc, SSH_AUTH_PASS);
1572  }
1573  else {
1574    myssh_to(data, sshc, SSH_AUTH_HOST_INIT);
1575  }
1576  return CURLE_OK;
1577}
1578
1579static CURLcode ssh_state_auth_pass(struct Curl_easy *data,
1580                                    struct ssh_conn *sshc)
1581{
1582  struct connectdata *conn = data->conn;
1583  const char *user = Curl_creds_user(conn->creds);
1584  const char *passwd = Curl_creds_passwd(conn->creds);
1585  int rc =
1586    libssh2_userauth_password_ex(sshc->ssh_session, user,
1587                                 curlx_uztoui(strlen(user)),
1588                                 passwd,
1589                                 curlx_uztoui(strlen(passwd)),
1590                                 NULL);
1591  if(rc == LIBSSH2_ERROR_EAGAIN) {
1592    return CURLE_AGAIN;
1593  }
1594  if(rc == 0) {
1595    sshc->authed = TRUE;
1596    infof(data, "Initialized password authentication");
1597    myssh_to(data, sshc, SSH_AUTH_DONE);
1598  }
1599  else {
1600    myssh_to(data, sshc, SSH_AUTH_HOST_INIT);
1601  }
1602  return CURLE_OK;
1603}
1604
1605static CURLcode ssh_state_auth_host_init(struct Curl_easy *data,
1606                                         struct ssh_conn *sshc)
1607{
1608  if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
1609     (strstr(sshc->authlist, "hostbased") != NULL)) {
1610    myssh_to(data, sshc, SSH_AUTH_HOST);
1611  }
1612  else {
1613    myssh_to(data, sshc, SSH_AUTH_AGENT_INIT);
1614  }
1615  return CURLE_OK;
1616}
1617
1618static CURLcode ssh_state_auth_agent_init(struct Curl_easy *data,
1619                                          struct ssh_conn *sshc)
1620{
1621  int rc = 0;
1622  if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT) &&
1623     (strstr(sshc->authlist, "publickey") != NULL)) {
1624
1625    /* Connect to the ssh-agent */
1626    /* The agent could be shared by a curl thread i believe
1627       but nothing obvious as keys can be added/removed at any time */
1628    if(!sshc->ssh_agent) {
1629      sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
1630      if(!sshc->ssh_agent) {
1631        infof(data, "Could not create agent object");
1632
1633        myssh_to(data, sshc, SSH_AUTH_KEY_INIT);
1634        return CURLE_OK;
1635      }
1636    }
1637
1638    rc = libssh2_agent_connect(sshc->ssh_agent);
1639    if(rc == LIBSSH2_ERROR_EAGAIN)
1640      return CURLE_AGAIN;
1641    if(rc < 0) {
1642      infof(data, "Failure connecting to agent");
1643      myssh_to(data, sshc, SSH_AUTH_KEY_INIT);
1644    }
1645    else {
1646      myssh_to(data, sshc, SSH_AUTH_AGENT_LIST);
1647    }
1648  }
1649  else
1650    myssh_to(data, sshc, SSH_AUTH_KEY_INIT);
1651  return CURLE_OK;
1652}
1653
1654static CURLcode ssh_state_auth_agent_list(struct Curl_easy *data,
1655                                          struct ssh_conn *sshc)
1656{
1657  int rc = libssh2_agent_list_identities(sshc->ssh_agent);
1658
1659  if(rc == LIBSSH2_ERROR_EAGAIN)
1660    return CURLE_AGAIN;
1661  if(rc < 0) {
1662    infof(data, "Failure requesting identities to agent");
1663    myssh_to(data, sshc, SSH_AUTH_KEY_INIT);
1664  }
1665  else {
1666    myssh_to(data, sshc, SSH_AUTH_AGENT);
1667    sshc->sshagent_prev_identity = NULL;
1668  }
1669  return CURLE_OK;
1670}
1671
1672static CURLcode ssh_state_auth_agent(struct Curl_easy *data,
1673                                     struct ssh_conn *sshc)
1674{
1675  /* as prev_identity evolves only after an identity user auth finished we
1676     can safely request it again as long as EAGAIN is returned here or by
1677     libssh2_agent_userauth */
1678  int rc = libssh2_agent_get_identity(sshc->ssh_agent,
1679                                      &sshc->sshagent_identity,
1680                                      sshc->sshagent_prev_identity);
1681  if(rc == LIBSSH2_ERROR_EAGAIN)
1682    return CURLE_AGAIN;
1683
1684  if(rc == 0) {
1685    struct connectdata *conn = data->conn;
1686    rc = libssh2_agent_userauth(sshc->ssh_agent, Curl_creds_user(conn->creds),
1687                                sshc->sshagent_identity);
1688
1689    if(rc < 0) {
1690      if(rc != LIBSSH2_ERROR_EAGAIN) {
1691        /* tried and failed? go to next identity */
1692        sshc->sshagent_prev_identity = sshc->sshagent_identity;
1693        return CURLE_OK;
1694      }
1695      return CURLE_AGAIN;
1696    }
1697  }
1698
1699  if(rc < 0)
1700    infof(data, "Failure requesting identities to agent");
1701  else if(rc == 1)
1702    infof(data, "No identity would match");
1703
1704  if(rc == LIBSSH2_ERROR_NONE) {
1705    sshc->authed = TRUE;
1706    infof(data, "Agent based authentication successful");
1707    myssh_to(data, sshc, SSH_AUTH_DONE);
1708  }
1709  else {
1710    myssh_to(data, sshc, SSH_AUTH_KEY_INIT);
1711  }
1712  return CURLE_OK;
1713}
1714
1715static CURLcode ssh_state_auth_key_init(struct Curl_easy *data,
1716                                        struct ssh_conn *sshc)
1717{
1718  if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) &&
1719     (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1720    myssh_to(data, sshc, SSH_AUTH_KEY);
1721  }
1722  else {
1723    myssh_to(data, sshc, SSH_AUTH_DONE);
1724  }
1725  return CURLE_OK;
1726}
1727
1728static CURLcode ssh_state_auth_key(struct Curl_easy *data,
1729                                   struct ssh_conn *sshc)
1730{
1731  /* Authentication failed. Continue with keyboard-interactive now. */
1732  struct connectdata *conn = data->conn;
1733  const char *user = Curl_creds_user(conn->creds);
1734  int rc =
1735    libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1736                                             user, curlx_uztoui(strlen(user)),
1737                                             &kbd_callback);
1738  if(rc == LIBSSH2_ERROR_EAGAIN)
1739    return CURLE_AGAIN;
1740
1741  if(rc == 0) {
1742    sshc->authed = TRUE;
1743    infof(data, "Initialized keyboard interactive authentication");
1744    myssh_to(data, sshc, SSH_AUTH_DONE);
1745    return CURLE_OK;
1746  }
1747  return CURLE_LOGIN_DENIED;
1748}
1749
1750static CURLcode ssh_state_auth_done(struct Curl_easy *data,
1751                                    struct ssh_conn *sshc)
1752{
1753  struct connectdata *conn = data->conn;
1754  if(!sshc->authed) {
1755    failf(data, "Authentication failure");
1756    myssh_to(data, sshc, SSH_SESSION_FREE);
1757    return CURLE_LOGIN_DENIED;
1758  }
1759
1760  /*
1761   * At this point we have an authenticated ssh session.
1762   */
1763  infof(data, "Authentication complete");
1764
1765  Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */
1766
1767  data->conn->recv_idx = FIRSTSOCKET;
1768  conn->send_idx = -1;
1769
1770  if(conn->scheme->protocol == CURLPROTO_SFTP) {
1771    myssh_to(data, sshc, SSH_SFTP_INIT);
1772    return CURLE_OK;
1773  }
1774  infof(data, "SSH CONNECT phase done");
1775  myssh_to(data, sshc, SSH_STOP);
1776  return CURLE_OK;
1777}
1778
1779static CURLcode ssh_state_sftp_init(struct Curl_easy *data,
1780                                    struct ssh_conn *sshc)
1781{
1782  /*
1783   * Start the libssh2 sftp session
1784   */
1785  sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1786  if(!sshc->sftp_session) {
1787    char *err_msg = NULL;
1788    if(libssh2_session_last_errno(sshc->ssh_session) ==
1789       LIBSSH2_ERROR_EAGAIN)
1790      return CURLE_AGAIN;
1791
1792    (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
1793    failf(data, "Failure initializing sftp session: %s", err_msg);
1794    myssh_to(data, sshc, SSH_SESSION_FREE);
1795    return CURLE_FAILED_INIT;
1796  }
1797  myssh_to(data, sshc, SSH_SFTP_REALPATH);
1798  return CURLE_OK;
1799}
1800
1801static CURLcode ssh_state_sftp_realpath(struct Curl_easy *data,
1802                                        struct ssh_conn *sshc,
1803                                        struct SSHPROTO *sshp)
1804{
1805  /*
1806   * Get the "home" directory
1807   */
1808  int rc;
1809
1810  if(!sshp)
1811    return CURLE_FAILED_INIT;
1812
1813  rc = libssh2_sftp_symlink_ex(sshc->sftp_session, ".",
1814                               curlx_uztoui(strlen(".")),
1815                               sshp->readdir_filename, CURL_PATH_MAX,
1816                               LIBSSH2_SFTP_REALPATH);
1817  if(rc == LIBSSH2_ERROR_EAGAIN)
1818    return CURLE_AGAIN;
1819
1820  myssh_to(data, sshc, SSH_STOP);
1821  if(rc > 0) {
1822    curlx_free(sshc->homedir);
1823    sshc->homedir = curlx_strdup(sshp->readdir_filename);
1824    if(!sshc->homedir)
1825      return CURLE_OUT_OF_MEMORY;
1826    curlx_free(data->state.most_recent_ftp_entrypath);
1827    data->state.most_recent_ftp_entrypath = curlx_strdup(sshc->homedir);
1828    if(!data->state.most_recent_ftp_entrypath)
1829      return CURLE_OUT_OF_MEMORY;
1830  }
1831  else {
1832    /* Return the error type */
1833    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1834    CURLcode result;
1835    if(sftperr)
1836      result = sftp_libssh2_error_to_CURLE(sftperr);
1837    else
1838      /* in this case, the error was not in the SFTP level but for example a
1839         time-out or similar */
1840      result = CURLE_SSH;
1841    CURL_TRC_SSH(data, "error = %lu makes libcurl = %d", sftperr, (int)result);
1842    return result;
1843  }
1844
1845  /* This is the last step in the SFTP connect phase. Do note that while we
1846     get the homedir here, we get the "workingpath" in the DO action since the
1847     homedir remains the same between request but the working path does not. */
1848  CURL_TRC_SSH(data, "CONNECT phase done");
1849  return CURLE_OK;
1850}
1851
1852static CURLcode ssh_state_sftp_quote_init(struct Curl_easy *data,
1853                                          struct ssh_conn *sshc,
1854                                          struct SSHPROTO *sshp)
1855{
1856  CURLcode result;
1857
1858  if(!sshp)
1859    return CURLE_FAILED_INIT;
1860
1861  result = Curl_getworkingpath(data, sshc->homedir, &sshp->path);
1862  if(result) {
1863    myssh_to(data, sshc, SSH_STOP);
1864    return result;
1865  }
1866
1867  if(data->set.quote) {
1868    infof(data, "Sending quote commands");
1869    sshc->quote_item = data->set.quote;
1870    myssh_to(data, sshc, SSH_SFTP_QUOTE);
1871  }
1872  else {
1873    myssh_to(data, sshc, SSH_SFTP_GETINFO);
1874  }
1875  return CURLE_OK;
1876}
1877
1878static CURLcode ssh_state_sftp_postquote_init(struct Curl_easy *data,
1879                                              struct ssh_conn *sshc)
1880{
1881  if(data->set.postquote) {
1882    infof(data, "Sending quote commands");
1883    sshc->quote_item = data->set.postquote;
1884    myssh_to(data, sshc, SSH_SFTP_QUOTE);
1885  }
1886  else {
1887    myssh_to(data, sshc, SSH_STOP);
1888  }
1889  return CURLE_OK;
1890}
1891
1892static CURLcode ssh_state_sftp_quote(struct Curl_easy *data,
1893                                     struct ssh_conn *sshc,
1894                                     struct SSHPROTO *sshp)
1895{
1896  /* Send quote commands */
1897  CURLcode result;
1898
1899  if(!sshp)
1900    return CURLE_FAILED_INIT;
1901
1902  result = sftp_quote(data, sshc, sshp);
1903  if(result) {
1904    myssh_to(data, sshc, SSH_SFTP_CLOSE);
1905    sshc->nextstate = SSH_NO_STATE;
1906  }
1907  return result;
1908}
1909
1910static CURLcode ssh_state_sftp_next_quote(struct Curl_easy *data,
1911                                          struct ssh_conn *sshc)
1912{
1913  curlx_safefree(sshc->quote_path1);
1914  curlx_safefree(sshc->quote_path2);
1915
1916  sshc->quote_item = sshc->quote_item->next;
1917
1918  if(sshc->quote_item) {
1919    myssh_to(data, sshc, SSH_SFTP_QUOTE);
1920  }
1921  else {
1922    if(sshc->nextstate != SSH_NO_STATE) {
1923      myssh_to(data, sshc, sshc->nextstate);
1924      sshc->nextstate = SSH_NO_STATE;
1925    }
1926    else {
1927      myssh_to(data, sshc, SSH_SFTP_GETINFO);
1928    }
1929  }
1930  return CURLE_OK;
1931}
1932
1933static CURLcode ssh_state_sftp_quote_stat(struct Curl_easy *data,
1934                                          struct ssh_conn *sshc,
1935                                          struct SSHPROTO *sshp,
1936                                          bool *blockp)
1937{
1938  CURLcode result;
1939
1940  if(!sshp)
1941    return CURLE_FAILED_INIT;
1942
1943  result = sftp_quote_stat(data, sshc, sshp, blockp);
1944  if(result) {
1945    myssh_to(data, sshc, SSH_SFTP_CLOSE);
1946    sshc->nextstate = SSH_NO_STATE;
1947  }
1948  return result;
1949}
1950
1951static CURLcode ssh_state_sftp_quote_setstat(struct Curl_easy *data,
1952                                             struct ssh_conn *sshc,
1953                                             struct SSHPROTO *sshp)
1954{
1955  int rc;
1956
1957  if(!sshp)
1958    return CURLE_FAILED_INIT;
1959
1960  rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1961                            curlx_uztoui(strlen(sshc->quote_path2)),
1962                            LIBSSH2_SFTP_SETSTAT,
1963                            &sshp->quote_attrs);
1964  if(rc == LIBSSH2_ERROR_EAGAIN)
1965    return CURLE_AGAIN;
1966
1967  if(rc && !sshc->acceptfail) {
1968    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1969    failf(data, "Attempt to set SFTP stats for \"%s\" failed: %s",
1970          sshc->quote_path2, sftp_libssh2_strerror(sftperr));
1971    curlx_safefree(sshc->quote_path1);
1972    curlx_safefree(sshc->quote_path2);
1973    myssh_to(data, sshc, SSH_SFTP_CLOSE);
1974    sshc->nextstate = SSH_NO_STATE;
1975    return CURLE_QUOTE_ERROR;
1976  }
1977  myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
1978  return CURLE_OK;
1979}
1980
1981static CURLcode ssh_state_sftp_quote_symlink(struct Curl_easy *data,
1982                                             struct ssh_conn *sshc)
1983{
1984  int rc =
1985    libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1986                            curlx_uztoui(strlen(sshc->quote_path1)),
1987                            sshc->quote_path2,
1988                            curlx_uztoui(strlen(sshc->quote_path2)),
1989                            LIBSSH2_SFTP_SYMLINK);
1990  if(rc == LIBSSH2_ERROR_EAGAIN)
1991    return CURLE_AGAIN;
1992
1993  if(rc && !sshc->acceptfail) {
1994    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1995    failf(data, "symlink \"%s\" to \"%s\" failed: %s",
1996          sshc->quote_path1, sshc->quote_path2,
1997          sftp_libssh2_strerror(sftperr));
1998    curlx_safefree(sshc->quote_path1);
1999    curlx_safefree(sshc->quote_path2);
2000    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2001    sshc->nextstate = SSH_NO_STATE;
2002    return CURLE_QUOTE_ERROR;
2003  }
2004  myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
2005  return CURLE_OK;
2006}
2007
2008static CURLcode ssh_state_sftp_quote_mkdir(struct Curl_easy *data,
2009                                           struct ssh_conn *sshc)
2010{
2011  int rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
2012                                 curlx_uztoui(strlen(sshc->quote_path1)),
2013                                 (long)data->set.new_directory_perms);
2014  if(rc == LIBSSH2_ERROR_EAGAIN)
2015    return CURLE_AGAIN;
2016
2017  if(rc && !sshc->acceptfail) {
2018    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2019    failf(data, "mkdir \"%s\" failed: %s",
2020          sshc->quote_path1, sftp_libssh2_strerror(sftperr));
2021    curlx_safefree(sshc->quote_path1);
2022    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2023    sshc->nextstate = SSH_NO_STATE;
2024    return CURLE_QUOTE_ERROR;
2025  }
2026  myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
2027  return CURLE_OK;
2028}
2029
2030static CURLcode ssh_state_sftp_quote_rename(struct Curl_easy *data,
2031                                            struct ssh_conn *sshc)
2032{
2033  int rc =
2034    libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
2035                           curlx_uztoui(strlen(sshc->quote_path1)),
2036                           sshc->quote_path2,
2037                           curlx_uztoui(strlen(sshc->quote_path2)),
2038                           LIBSSH2_SFTP_RENAME_OVERWRITE |
2039                           LIBSSH2_SFTP_RENAME_ATOMIC |
2040                           LIBSSH2_SFTP_RENAME_NATIVE);
2041
2042  if(rc == LIBSSH2_ERROR_EAGAIN)
2043    return CURLE_AGAIN;
2044
2045  if(rc && !sshc->acceptfail) {
2046    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2047    failf(data, "rename \"%s\" to \"%s\" failed: %s",
2048          sshc->quote_path1, sshc->quote_path2,
2049          sftp_libssh2_strerror(sftperr));
2050    curlx_safefree(sshc->quote_path1);
2051    curlx_safefree(sshc->quote_path2);
2052    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2053    sshc->nextstate = SSH_NO_STATE;
2054    return CURLE_QUOTE_ERROR;
2055  }
2056  myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
2057  return CURLE_OK;
2058}
2059
2060static CURLcode ssh_state_sftp_quote_rmdir(struct Curl_easy *data,
2061                                           struct ssh_conn *sshc)
2062{
2063  int rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
2064                                 curlx_uztoui(strlen(sshc->quote_path1)));
2065  if(rc == LIBSSH2_ERROR_EAGAIN)
2066    return CURLE_AGAIN;
2067
2068  if(rc && !sshc->acceptfail) {
2069    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2070    failf(data, "rmdir \"%s\" failed: %s",
2071          sshc->quote_path1, sftp_libssh2_strerror(sftperr));
2072    curlx_safefree(sshc->quote_path1);
2073    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2074    sshc->nextstate = SSH_NO_STATE;
2075    return CURLE_QUOTE_ERROR;
2076  }
2077  myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
2078  return CURLE_OK;
2079}
2080
2081static CURLcode ssh_state_sftp_quote_unlink(struct Curl_easy *data,
2082                                            struct ssh_conn *sshc)
2083{
2084  int rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
2085                                  curlx_uztoui(strlen(sshc->quote_path1)));
2086  if(rc == LIBSSH2_ERROR_EAGAIN)
2087    return CURLE_AGAIN;
2088
2089  if(rc && !sshc->acceptfail) {
2090    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2091    failf(data, "rm \"%s\" failed: %s",
2092          sshc->quote_path1, sftp_libssh2_strerror(sftperr));
2093    curlx_safefree(sshc->quote_path1);
2094    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2095    sshc->nextstate = SSH_NO_STATE;
2096    return CURLE_QUOTE_ERROR;
2097  }
2098  myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
2099  return CURLE_OK;
2100}
2101
2102static CURLcode ssh_state_sftp_quote_statvfs(struct Curl_easy *data,
2103                                             struct ssh_conn *sshc)
2104{
2105  LIBSSH2_SFTP_STATVFS statvfs;
2106  int rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
2107                                curlx_uztoui(strlen(sshc->quote_path1)),
2108                                &statvfs);
2109
2110  if(rc == LIBSSH2_ERROR_EAGAIN)
2111    return CURLE_AGAIN;
2112
2113  if(rc && !sshc->acceptfail) {
2114    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2115    failf(data, "statvfs \"%s\" failed: %s",
2116          sshc->quote_path1, sftp_libssh2_strerror(sftperr));
2117    curlx_safefree(sshc->quote_path1);
2118    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2119    sshc->nextstate = SSH_NO_STATE;
2120    return CURLE_QUOTE_ERROR;
2121  }
2122  else if(rc == 0) {
2123#ifdef _MSC_VER
2124#define CURL_LIBSSH2_VFS_SIZE_MASK "I64u"
2125#else
2126#define CURL_LIBSSH2_VFS_SIZE_MASK "llu"
2127#endif
2128    CURLcode result;
2129    char *tmp = curl_maprintf("statvfs:\n"
2130                              "f_bsize: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2131                              "f_frsize: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2132                              "f_blocks: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2133                              "f_bfree: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2134                              "f_bavail: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2135                              "f_files: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2136                              "f_ffree: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2137                              "f_favail: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2138                              "f_fsid: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2139                              "f_flag: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
2140                              "f_namemax: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n",
2141                              statvfs.f_bsize, statvfs.f_frsize,
2142                              statvfs.f_blocks, statvfs.f_bfree,
2143                              statvfs.f_bavail, statvfs.f_files,
2144                              statvfs.f_ffree, statvfs.f_favail,
2145                              statvfs.f_fsid, statvfs.f_flag,
2146                              statvfs.f_namemax);
2147    if(!tmp) {
2148      myssh_to(data, sshc, SSH_SFTP_CLOSE);
2149      sshc->nextstate = SSH_NO_STATE;
2150      return CURLE_OUT_OF_MEMORY;
2151    }
2152
2153    result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
2154    curlx_free(tmp);
2155    if(result) {
2156      myssh_to(data, sshc, SSH_SFTP_CLOSE);
2157      sshc->nextstate = SSH_NO_STATE;
2158      return result;
2159    }
2160  }
2161  myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
2162  return CURLE_OK;
2163}
2164
2165static CURLcode ssh_state_sftp_create_dirs_mkdir(struct Curl_easy *data,
2166                                                 struct ssh_conn *sshc,
2167                                                 struct SSHPROTO *sshp)
2168{
2169  /* 'mode' - parameter is preliminary - default to 0644 */
2170  int rc;
2171
2172  if(!sshp)
2173    return CURLE_FAILED_INIT;
2174
2175  rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshp->path,
2176                             curlx_uztoui(strlen(sshp->path)),
2177                             (long)data->set.new_directory_perms);
2178  if(rc == LIBSSH2_ERROR_EAGAIN)
2179    return CURLE_AGAIN;
2180
2181  *sshc->slash_pos = '/';
2182  ++sshc->slash_pos;
2183  if(rc < 0) {
2184    /*
2185     * Abort if failure was not that the directory already exists or
2186     * the permission was denied (creation might succeed further down
2187     * the path) - retry on unspecific FAILURE also
2188     */
2189    unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2190    if((sftperr != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
2191       (sftperr != LIBSSH2_FX_FAILURE) &&
2192       (sftperr != LIBSSH2_FX_PERMISSION_DENIED)) {
2193      myssh_to(data, sshc, SSH_SFTP_CLOSE);
2194      return sftp_libssh2_error_to_CURLE(sftperr);
2195    }
2196  }
2197  myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS);
2198  return CURLE_OK;
2199}
2200
2201static CURLcode ssh_state_sftp_readdir_init(struct Curl_easy *data,
2202                                            struct ssh_conn *sshc,
2203                                            struct SSHPROTO *sshp)
2204{
2205  if(!sshp)
2206    return CURLE_FAILED_INIT;
2207
2208  Curl_pgrsSetDownloadSize(data, -1);
2209  if(data->req.no_body) {
2210    myssh_to(data, sshc, SSH_STOP);
2211    return CURLE_OK;
2212  }
2213
2214  /*
2215   * This is a directory that we are trying to get, so produce a directory
2216   * listing
2217   */
2218  sshc->sftp_handle =
2219    libssh2_sftp_open_ex(sshc->sftp_session, sshp->path,
2220                         curlx_uztoui(strlen(sshp->path)),
2221                         0, 0, LIBSSH2_SFTP_OPENDIR);
2222  if(!sshc->sftp_handle) {
2223    unsigned long sftperr;
2224    if(libssh2_session_last_errno(sshc->ssh_session) == LIBSSH2_ERROR_EAGAIN)
2225      return CURLE_AGAIN;
2226
2227    sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2228    failf(data, "Could not open directory for reading: %s",
2229          sftp_libssh2_strerror(sftperr));
2230    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2231    return sftp_libssh2_error_to_CURLE(sftperr);
2232  }
2233  myssh_to(data, sshc, SSH_SFTP_READDIR);
2234  return CURLE_OK;
2235}
2236
2237static CURLcode ssh_state_sftp_readdir_link(struct Curl_easy *data,
2238                                            struct ssh_conn *sshc,
2239                                            struct SSHPROTO *sshp)
2240{
2241  CURLcode result;
2242  int rc;
2243  if(!sshp)
2244    return CURLE_FAILED_INIT;
2245
2246  rc = libssh2_sftp_symlink_ex(sshc->sftp_session,
2247                               curlx_dyn_ptr(&sshp->readdir_link),
2248                               (unsigned int)
2249                               curlx_dyn_len(&sshp->readdir_link),
2250                               sshp->readdir_filename,
2251                               CURL_PATH_MAX, LIBSSH2_SFTP_READLINK);
2252  if(rc == LIBSSH2_ERROR_EAGAIN)
2253    return CURLE_AGAIN;
2254
2255  curlx_dyn_free(&sshp->readdir_link);
2256
2257  if(rc < 0)
2258    return CURLE_OUT_OF_MEMORY;
2259
2260  /* append filename and extra output */
2261  result = curlx_dyn_addf(&sshp->readdir, " -> %s", sshp->readdir_filename);
2262  if(result)
2263    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2264  else
2265    myssh_to(data, sshc, SSH_SFTP_READDIR_BOTTOM);
2266  return result;
2267}
2268
2269static CURLcode ssh_state_scp_download_init(struct Curl_easy *data,
2270                                            struct ssh_conn *sshc,
2271                                            struct SSHPROTO *sshp)
2272{
2273  curl_off_t bytecount;
2274  libssh2_struct_stat sb;
2275
2276  if(!sshp)
2277    return CURLE_FAILED_INIT;
2278  /*
2279   * We must check the remote file; if it is a directory no values are
2280   * be set in sb
2281   */
2282
2283  /*
2284   * If support for >2GB files exists, use it.
2285   */
2286
2287  /* get a fresh new channel from the ssh layer */
2288  memset(&sb, 0, sizeof(libssh2_struct_stat));
2289  sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session, sshp->path, &sb);
2290  if(!sshc->ssh_channel) {
2291    int ssh_err;
2292    char *err_msg = NULL;
2293
2294    if(libssh2_session_last_errno(sshc->ssh_session) ==
2295       LIBSSH2_ERROR_EAGAIN)
2296      return CURLE_AGAIN;
2297
2298    ssh_err = libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2299    failf(data, "%s", err_msg);
2300    myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE);
2301    return libssh2_session_error_to_CURLE(ssh_err);
2302  }
2303
2304  /* download data */
2305  bytecount = (curl_off_t)sb.st_size;
2306  data->req.maxdownload = (curl_off_t)sb.st_size;
2307  Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount);
2308
2309  /* not set by Curl_xfer_setup to preserve io_flags */
2310  data->conn->send_idx = 0;
2311
2312  myssh_to(data, sshc, SSH_STOP);
2313  return CURLE_OK;
2314}
2315
2316static CURLcode ssh_state_sftp_close(struct Curl_easy *data,
2317                                     struct ssh_conn *sshc,
2318                                     struct SSHPROTO *sshp)
2319{
2320  int rc = 0;
2321  if(!sshp)
2322    return CURLE_FAILED_INIT;
2323  if(sshc->sftp_handle) {
2324    rc = libssh2_sftp_close(sshc->sftp_handle);
2325    if(rc == LIBSSH2_ERROR_EAGAIN)
2326      return CURLE_AGAIN;
2327
2328    if(rc < 0) {
2329      char *err_msg = NULL;
2330      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2331      infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg);
2332    }
2333    sshc->sftp_handle = NULL;
2334  }
2335
2336  curlx_safefree(sshp->path);
2337
2338  CURL_TRC_SSH(data, "SFTP DONE done");
2339
2340  /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2341     After nextstate is executed, the control should come back to
2342     SSH_SFTP_CLOSE to pass the correct result back */
2343  if(sshc->nextstate != SSH_NO_STATE &&
2344     sshc->nextstate != SSH_SFTP_CLOSE) {
2345    myssh_to(data, sshc, sshc->nextstate);
2346    sshc->nextstate = SSH_SFTP_CLOSE;
2347  }
2348  else
2349    myssh_to(data, sshc, SSH_STOP);
2350
2351  return CURLE_OK;
2352}
2353
2354static CURLcode ssh_state_sftp_shutdown(struct Curl_easy *data,
2355                                        struct ssh_conn *sshc)
2356{
2357  /* during times we get here due to a broken transfer and then the
2358     sftp_handle might not have been taken down so make sure that is done
2359     before we proceed */
2360  int rc = 0;
2361  if(sshc->sftp_handle) {
2362    rc = libssh2_sftp_close(sshc->sftp_handle);
2363    if(rc == LIBSSH2_ERROR_EAGAIN)
2364      return CURLE_AGAIN;
2365
2366    if(rc < 0) {
2367      char *err_msg = NULL;
2368      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2369      infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg);
2370    }
2371    sshc->sftp_handle = NULL;
2372  }
2373  if(sshc->sftp_session) {
2374    rc = libssh2_sftp_shutdown(sshc->sftp_session);
2375    if(rc == LIBSSH2_ERROR_EAGAIN)
2376      return CURLE_AGAIN;
2377
2378    if(rc < 0) {
2379      infof(data, "Failed to stop libssh2 sftp subsystem");
2380    }
2381    sshc->sftp_session = NULL;
2382  }
2383
2384  curlx_safefree(sshc->homedir);
2385
2386  myssh_to(data, sshc, SSH_SESSION_DISCONNECT);
2387  return CURLE_OK;
2388}
2389
2390static CURLcode ssh_state_sftp_download_init(struct Curl_easy *data,
2391                                             struct ssh_conn *sshc,
2392                                             struct SSHPROTO *sshp)
2393{
2394  if(!sshp)
2395    return CURLE_FAILED_INIT;
2396  /*
2397   * Work on getting the specified file
2398   */
2399  sshc->sftp_handle =
2400    libssh2_sftp_open_ex(sshc->sftp_session, sshp->path,
2401                         curlx_uztoui(strlen(sshp->path)),
2402                         LIBSSH2_FXF_READ, (long)data->set.new_file_perms,
2403                         LIBSSH2_SFTP_OPENFILE);
2404  if(!sshc->sftp_handle) {
2405    unsigned long sftperr;
2406    if(libssh2_session_last_errno(sshc->ssh_session) ==
2407       LIBSSH2_ERROR_EAGAIN) {
2408      return CURLE_AGAIN;
2409    }
2410    sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2411    failf(data, "Could not open remote file for reading: %s",
2412          sftp_libssh2_strerror(sftperr));
2413    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2414    return sftp_libssh2_error_to_CURLE(sftperr);
2415  }
2416  myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_STAT);
2417  return CURLE_OK;
2418}
2419
2420static CURLcode ssh_state_scp_upload_init(struct Curl_easy *data,
2421                                          struct ssh_conn *sshc,
2422                                          struct SSHPROTO *sshp)
2423{
2424  if(!sshp)
2425    return CURLE_FAILED_INIT;
2426  /*
2427   * libssh2 requires that the destination path is a full path that
2428   * includes the destination file and name OR ends in a "/" . If this is
2429   * not done the destination file is named the same name as the last
2430   * directory in the path.
2431   */
2432  sshc->ssh_channel =
2433    libssh2_scp_send64(sshc->ssh_session, sshp->path,
2434                       (int)data->set.new_file_perms,
2435                       (libssh2_int64_t)data->state.infilesize, 0, 0);
2436  if(!sshc->ssh_channel) {
2437    int ssh_err;
2438    char *err_msg = NULL;
2439    CURLcode result;
2440    if(libssh2_session_last_errno(sshc->ssh_session) ==
2441       LIBSSH2_ERROR_EAGAIN)
2442      return CURLE_AGAIN;
2443
2444    ssh_err = libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2445    failf(data, "%s", err_msg);
2446    myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE);
2447    result = libssh2_session_error_to_CURLE(ssh_err);
2448
2449    /* Map generic errors to upload failed */
2450    if(result == CURLE_SSH ||
2451       result == CURLE_REMOTE_FILE_NOT_FOUND)
2452      result = CURLE_UPLOAD_FAILED;
2453    return result;
2454  }
2455
2456  /* upload data */
2457  data->req.size = data->state.infilesize;
2458  Curl_pgrsSetUploadSize(data, data->state.infilesize);
2459  Curl_xfer_setup_send(data, FIRSTSOCKET);
2460
2461  /* not set by Curl_xfer_setup to preserve io_flags */
2462  data->conn->recv_idx = FIRSTSOCKET;
2463
2464  myssh_to(data, sshc, SSH_STOP);
2465
2466  return CURLE_OK;
2467}
2468
2469static CURLcode ssh_state_session_disconnect(struct Curl_easy *data,
2470                                             struct ssh_conn *sshc)
2471{
2472  /* during weird times when we have been prematurely aborted, the channel
2473     is still alive when we reach this state and we MUST kill the channel
2474     properly first */
2475  int rc = 0;
2476  if(sshc->ssh_channel) {
2477    rc = libssh2_channel_free(sshc->ssh_channel);
2478    if(rc == LIBSSH2_ERROR_EAGAIN)
2479      return CURLE_AGAIN;
2480
2481    if(rc < 0) {
2482      char *err_msg = NULL;
2483      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2484      infof(data, "Failed to free libssh2 scp subsystem: %d %s", rc, err_msg);
2485    }
2486    sshc->ssh_channel = NULL;
2487  }
2488
2489  if(sshc->ssh_session) {
2490    rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2491    if(rc == LIBSSH2_ERROR_EAGAIN)
2492      return CURLE_AGAIN;
2493
2494    if(rc < 0) {
2495      char *err_msg = NULL;
2496      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2497      infof(data, "Failed to disconnect libssh2 session: %d %s", rc, err_msg);
2498    }
2499  }
2500
2501  curlx_safefree(sshc->homedir);
2502
2503  myssh_to(data, sshc, SSH_SESSION_FREE);
2504  return CURLE_OK;
2505}
2506
2507static CURLcode sshc_cleanup(struct ssh_conn *sshc, struct Curl_easy *data,
2508                             bool block)
2509{
2510  int rc;
2511
2512  if(sshc->kh) {
2513    libssh2_knownhost_free(sshc->kh);
2514    sshc->kh = NULL;
2515  }
2516
2517  if(sshc->ssh_agent) {
2518    rc = libssh2_agent_disconnect(sshc->ssh_agent);
2519    if((rc < 0) && data) {
2520      char *err_msg = NULL;
2521      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2522      infof(data, "Failed to disconnect from libssh2 agent: %d %s",
2523            rc, err_msg);
2524    }
2525    if(!block && (rc == LIBSSH2_ERROR_EAGAIN))
2526      return CURLE_AGAIN;
2527
2528    libssh2_agent_free(sshc->ssh_agent);
2529    sshc->ssh_agent = NULL;
2530
2531    /* NB: there is no need to free identities, they are part of internal
2532       agent stuff */
2533    sshc->sshagent_identity = NULL;
2534    sshc->sshagent_prev_identity = NULL;
2535  }
2536
2537  if(sshc->sftp_handle) {
2538    rc = libssh2_sftp_close(sshc->sftp_handle);
2539    if((rc < 0) && data) {
2540      char *err_msg = NULL;
2541      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2542      infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg);
2543    }
2544    if(!block && (rc == LIBSSH2_ERROR_EAGAIN))
2545      return CURLE_AGAIN;
2546
2547    sshc->sftp_handle = NULL;
2548  }
2549
2550  if(sshc->ssh_channel) {
2551    rc = libssh2_channel_free(sshc->ssh_channel);
2552    if((rc < 0) && data) {
2553      char *err_msg = NULL;
2554      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2555      infof(data, "Failed to free libssh2 scp subsystem: %d %s", rc, err_msg);
2556    }
2557    if(!block && (rc == LIBSSH2_ERROR_EAGAIN))
2558      return CURLE_AGAIN;
2559
2560    sshc->ssh_channel = NULL;
2561  }
2562
2563  if(sshc->sftp_session) {
2564    rc = libssh2_sftp_shutdown(sshc->sftp_session);
2565    if((rc < 0) && data) {
2566      char *err_msg = NULL;
2567      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2568      infof(data, "Failed to stop libssh2 sftp subsystem: %d %s", rc, err_msg);
2569    }
2570    if(!block && (rc == LIBSSH2_ERROR_EAGAIN))
2571      return CURLE_AGAIN;
2572
2573    sshc->sftp_session = NULL;
2574  }
2575
2576  if(sshc->ssh_session) {
2577    rc = libssh2_session_free(sshc->ssh_session);
2578    if((rc < 0) && data) {
2579      char *err_msg = NULL;
2580      (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
2581      infof(data, "Failed to free libssh2 session: %d %s", rc, err_msg);
2582    }
2583    if(!block && (rc == LIBSSH2_ERROR_EAGAIN))
2584      return CURLE_AGAIN;
2585
2586    sshc->ssh_session = NULL;
2587  }
2588
2589  /* worst-case scenario cleanup */
2590  DEBUGASSERT(sshc->ssh_session == NULL);
2591  DEBUGASSERT(sshc->ssh_channel == NULL);
2592  DEBUGASSERT(sshc->sftp_session == NULL);
2593  DEBUGASSERT(sshc->sftp_handle == NULL);
2594  DEBUGASSERT(sshc->kh == NULL);
2595  DEBUGASSERT(sshc->ssh_agent == NULL);
2596
2597  curlx_safefree(sshc->rsa_pub);
2598  curlx_safefree(sshc->rsa);
2599  curlx_safefree(sshc->quote_path1);
2600  curlx_safefree(sshc->quote_path2);
2601  curlx_safefree(sshc->homedir);
2602
2603  return CURLE_OK;
2604}
2605
2606static CURLcode ssh_state_sftp_getinfo(struct Curl_easy *data,
2607                                       struct ssh_conn *sshc)
2608{
2609  if(data->set.get_filetime)
2610    myssh_to(data, sshc, SSH_SFTP_FILETIME);
2611  else
2612    myssh_to(data, sshc, SSH_SFTP_TRANS_INIT);
2613  return CURLE_OK;
2614}
2615
2616static CURLcode ssh_state_sftp_filetime(struct Curl_easy *data,
2617                                        struct ssh_conn *sshc,
2618                                        struct SSHPROTO *sshp)
2619{
2620  LIBSSH2_SFTP_ATTRIBUTES attrs;
2621  int rc;
2622
2623  if(!sshp)
2624    return CURLE_FAILED_INIT;
2625
2626  rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
2627                            curlx_uztoui(strlen(sshp->path)),
2628                            LIBSSH2_SFTP_STAT, &attrs);
2629  if(rc == LIBSSH2_ERROR_EAGAIN)
2630    return CURLE_AGAIN;
2631
2632  if(rc == 0)
2633    data->info.filetime = (time_t)attrs.mtime;
2634
2635  myssh_to(data, sshc, SSH_SFTP_TRANS_INIT);
2636  return CURLE_OK;
2637}
2638
2639static CURLcode ssh_state_sftp_trans_init(struct Curl_easy *data,
2640                                          struct ssh_conn *sshc,
2641                                          struct SSHPROTO *sshp)
2642{
2643  if(data->state.upload)
2644    myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT);
2645  else if(sshp) {
2646    size_t plen = strlen(sshp->path);
2647    if(plen && (sshp->path[plen - 1] == '/'))
2648      myssh_to(data, sshc, SSH_SFTP_READDIR_INIT);
2649    else
2650      myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_INIT);
2651  }
2652  else
2653    return CURLE_FAILED_INIT;
2654  return CURLE_OK;
2655}
2656
2657static CURLcode ssh_state_sftp_upload_init(struct Curl_easy *data,
2658                                           struct ssh_conn *sshc,
2659                                           struct SSHPROTO *sshp,
2660                                           bool *block)
2661{
2662  CURLcode result;
2663  if(!sshp)
2664    return CURLE_FAILED_INIT;
2665  result = sftp_upload_init(data, sshc, sshp, block);
2666  if(result) {
2667    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2668    sshc->nextstate = SSH_NO_STATE;
2669  }
2670  return result;
2671}
2672
2673static CURLcode ssh_state_sftp_create_dirs_init(struct Curl_easy *data,
2674                                                struct ssh_conn *sshc,
2675                                                struct SSHPROTO *sshp)
2676{
2677  if(!sshp)
2678    return CURLE_FAILED_INIT;
2679  if(strlen(sshp->path) > 1) {
2680    sshc->slash_pos = sshp->path + 1; /* ignore the leading '/' */
2681    myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS);
2682  }
2683  else
2684    myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT);
2685  return CURLE_OK;
2686}
2687
2688static CURLcode ssh_state_sftp_create_dirs(struct Curl_easy *data,
2689                                           struct ssh_conn *sshc,
2690                                           struct SSHPROTO *sshp)
2691{
2692  if(!sshp)
2693    return CURLE_FAILED_INIT;
2694  sshc->slash_pos = strchr(sshc->slash_pos, '/');
2695  if(sshc->slash_pos) {
2696    *sshc->slash_pos = 0;
2697    infof(data, "Creating directory '%s'", sshp->path);
2698    myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_MKDIR);
2699    return CURLE_OK;
2700  }
2701  myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT);
2702  return CURLE_OK;
2703}
2704
2705static CURLcode ssh_state_sftp_readdir(struct Curl_easy *data,
2706                                       struct ssh_conn *sshc,
2707                                       struct SSHPROTO *sshp,
2708                                       bool *block)
2709{
2710  CURLcode result;
2711  if(!sshp)
2712    return CURLE_FAILED_INIT;
2713  result = sftp_readdir(data, sshc, sshp, block);
2714  if(result)
2715    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2716  return result;
2717}
2718
2719static CURLcode ssh_state_sftp_readdir_bottom(struct Curl_easy *data,
2720                                              struct ssh_conn *sshc,
2721                                              struct SSHPROTO *sshp)
2722{
2723  CURLcode result;
2724  if(!sshp)
2725    return CURLE_FAILED_INIT;
2726
2727  result = curlx_dyn_addn(&sshp->readdir, "\n", 1);
2728  if(!result)
2729    result = Curl_client_write(data, CLIENTWRITE_BODY,
2730                               curlx_dyn_ptr(&sshp->readdir),
2731                               curlx_dyn_len(&sshp->readdir));
2732  if(result) {
2733    curlx_dyn_free(&sshp->readdir);
2734    myssh_to(data, sshc, SSH_STOP);
2735  }
2736  else {
2737    curlx_dyn_reset(&sshp->readdir);
2738    myssh_to(data, sshc, SSH_SFTP_READDIR);
2739  }
2740  return result;
2741}
2742
2743static CURLcode ssh_state_sftp_readdir_done(struct Curl_easy *data,
2744                                            struct ssh_conn *sshc)
2745{
2746  if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2747     LIBSSH2_ERROR_EAGAIN)
2748    return CURLE_AGAIN;
2749
2750  sshc->sftp_handle = NULL;
2751
2752  /* no data to transfer */
2753  Curl_xfer_setup_nop(data);
2754  myssh_to(data, sshc, SSH_STOP);
2755  return CURLE_OK;
2756}
2757
2758static CURLcode ssh_state_sftp_download_stat(struct Curl_easy *data,
2759                                             struct ssh_conn *sshc,
2760                                             struct SSHPROTO *sshp,
2761                                             bool *block)
2762{
2763  CURLcode result;
2764  if(!sshp)
2765    return CURLE_FAILED_INIT;
2766  result = sftp_download_stat(data, sshc, sshp, block);
2767  if(result) {
2768    myssh_to(data, sshc, SSH_SFTP_CLOSE);
2769    sshc->nextstate = SSH_NO_STATE;
2770  }
2771  return result;
2772}
2773
2774static CURLcode ssh_state_scp_trans_init(struct Curl_easy *data,
2775                                         struct ssh_conn *sshc,
2776                                         struct SSHPROTO *sshp)
2777{
2778  CURLcode result;
2779  if(!sshp)
2780    return CURLE_FAILED_INIT;
2781  result = Curl_getworkingpath(data, sshc->homedir,
2782                               &sshp->path);
2783  if(result) {
2784    myssh_to(data, sshc, SSH_STOP);
2785    return result;
2786  }
2787
2788  if(data->state.upload) {
2789    if(data->state.infilesize < 0) {
2790      failf(data, "SCP requires a known file size for upload");
2791      myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE);
2792      return CURLE_UPLOAD_FAILED;
2793    }
2794    myssh_to(data, sshc, SSH_SCP_UPLOAD_INIT);
2795  }
2796  else
2797    myssh_to(data, sshc, SSH_SCP_DOWNLOAD_INIT);
2798  return CURLE_OK;
2799}
2800
2801static CURLcode ssh_state_scp_done(struct Curl_easy *data,
2802                                   struct ssh_conn *sshc)
2803{
2804  if(data->state.upload)
2805    myssh_to(data, sshc, SSH_SCP_SEND_EOF);
2806  else
2807    myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE);
2808  return CURLE_OK;
2809}
2810
2811static CURLcode ssh_state_scp_send_eof(struct Curl_easy *data,
2812                                       struct ssh_conn *sshc)
2813{
2814  if(sshc->ssh_channel) {
2815    int rc = libssh2_channel_send_eof(sshc->ssh_channel);
2816    if(rc == LIBSSH2_ERROR_EAGAIN)
2817      return CURLE_AGAIN;
2818    if(rc) {
2819      char *err_msg = NULL;
2820      (void)libssh2_session_last_error(sshc->ssh_session,
2821                                       &err_msg, NULL, 0);
2822      infof(data,
2823            "Failed to send libssh2 channel EOF: %d %s",
2824            rc, err_msg);
2825    }
2826  }
2827  myssh_to(data, sshc, SSH_SCP_WAIT_EOF);
2828  return CURLE_OK;
2829}
2830
2831static CURLcode ssh_state_scp_wait_eof(struct Curl_easy *data,
2832                                       struct ssh_conn *sshc)
2833{
2834  if(sshc->ssh_channel) {
2835    int rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2836    if(rc == LIBSSH2_ERROR_EAGAIN)
2837      return CURLE_AGAIN;
2838    if(rc) {
2839      char *err_msg = NULL;
2840      (void)libssh2_session_last_error(sshc->ssh_session,
2841                                       &err_msg, NULL, 0);
2842      infof(data, "Failed to get channel EOF: %d %s",
2843            rc, err_msg);
2844    }
2845  }
2846  myssh_to(data, sshc, SSH_SCP_WAIT_CLOSE);
2847  return CURLE_OK;
2848}
2849
2850static CURLcode ssh_state_scp_wait_close(struct Curl_easy *data,
2851                                         struct ssh_conn *sshc)
2852{
2853  if(sshc->ssh_channel) {
2854    int rc =
2855      libssh2_channel_wait_closed(sshc->ssh_channel);
2856    if(rc == LIBSSH2_ERROR_EAGAIN)
2857      return CURLE_AGAIN;
2858    if(rc) {
2859      char *err_msg = NULL;
2860      (void)libssh2_session_last_error(sshc->ssh_session,
2861                                       &err_msg, NULL, 0);
2862      infof(data, "Channel failed to close: %d %s",
2863            rc, err_msg);
2864    }
2865  }
2866  myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE);
2867  return CURLE_OK;
2868}
2869
2870static CURLcode ssh_state_scp_channel_free(
2871  struct Curl_easy *data,
2872  struct ssh_conn *sshc)
2873{
2874  if(sshc->ssh_channel) {
2875    int rc = libssh2_channel_free(sshc->ssh_channel);
2876    if(rc == LIBSSH2_ERROR_EAGAIN)
2877      return CURLE_AGAIN;
2878    if(rc < 0) {
2879      char *err_msg = NULL;
2880      (void)libssh2_session_last_error(sshc->ssh_session,
2881                                       &err_msg, NULL, 0);
2882      infof(data,
2883            "Failed to free libssh2 scp subsystem: %d %s",
2884            rc, err_msg);
2885    }
2886    sshc->ssh_channel = NULL;
2887  }
2888  CURL_TRC_SSH(data, "SCP DONE phase complete");
2889  myssh_to(data, sshc, SSH_STOP);
2890  return CURLE_OK;
2891}
2892
2893static CURLcode ssh_state_session_free(struct Curl_easy *data,
2894                                       struct ssh_conn *sshc)
2895{
2896  CURLcode result = sshc_cleanup(sshc, data, FALSE);
2897  struct connectdata *conn = data->conn;
2898  if(result)
2899    return result;
2900  memset(sshc, 0, sizeof(struct ssh_conn));
2901  connclose(conn, "SSH session free");
2902  sshc->state = SSH_SESSION_FREE; /* current */
2903  myssh_to(data, sshc, SSH_STOP);
2904  return CURLE_OK;
2905}
2906
2907/*
2908 * ssh_statemachine() runs the SSH state machine as far as it can without
2909 * blocking and without reaching the end. The data the pointer 'block' points
2910 * to is set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
2911 * meaning it wants to be called again when the socket is ready
2912 */
2913static CURLcode ssh_statemachine(struct Curl_easy *data,
2914                                 struct ssh_conn *sshc,
2915                                 struct SSHPROTO *sshp,
2916                                 bool *block)
2917{
2918  CURLcode result = CURLE_OK;
2919  *block = 0; /* we are not blocking by default */
2920
2921  do {
2922    switch(sshc->state) {
2923    case SSH_INIT:
2924      result = ssh_state_init(data, sshc);
2925      if(result)
2926        break;
2927      FALLTHROUGH();
2928
2929    case SSH_S_STARTUP:
2930      result = ssh_state_startup(data, sshc);
2931      if(result)
2932        break;
2933      FALLTHROUGH();
2934
2935    case SSH_HOSTKEY:
2936      result = ssh_state_hostkey(data, sshc);
2937      break;
2938
2939    case SSH_AUTHLIST:
2940      result = ssh_state_authlist(data, sshc);
2941      break;
2942
2943    case SSH_AUTH_PKEY_INIT:
2944      result = ssh_state_pkey_init(data, sshc);
2945      break;
2946
2947    case SSH_AUTH_PKEY:
2948      result = ssh_state_auth_pkey(data, sshc);
2949      break;
2950
2951    case SSH_AUTH_PASS_INIT:
2952      result = ssh_state_auth_pass_init(data, sshc);
2953      break;
2954
2955    case SSH_AUTH_PASS:
2956      result = ssh_state_auth_pass(data, sshc);
2957      break;
2958
2959    case SSH_AUTH_HOST_INIT:
2960      result = ssh_state_auth_host_init(data, sshc);
2961      break;
2962
2963    case SSH_AUTH_HOST:
2964      myssh_to(data, sshc, SSH_AUTH_AGENT_INIT);
2965      break;
2966
2967    case SSH_AUTH_AGENT_INIT:
2968      result = ssh_state_auth_agent_init(data, sshc);
2969      break;
2970
2971    case SSH_AUTH_AGENT_LIST:
2972      result = ssh_state_auth_agent_list(data, sshc);
2973      break;
2974
2975    case SSH_AUTH_AGENT:
2976      result = ssh_state_auth_agent(data, sshc);
2977      break;
2978
2979    case SSH_AUTH_KEY_INIT:
2980      result = ssh_state_auth_key_init(data, sshc);
2981      break;
2982
2983    case SSH_AUTH_KEY:
2984      result = ssh_state_auth_key(data, sshc);
2985      break;
2986
2987    case SSH_AUTH_DONE:
2988      result = ssh_state_auth_done(data, sshc);
2989      break;
2990
2991    case SSH_SFTP_INIT:
2992      result = ssh_state_sftp_init(data, sshc);
2993      break;
2994
2995    case SSH_SFTP_REALPATH:
2996      result = ssh_state_sftp_realpath(data, sshc, sshp);
2997      break;
2998
2999    case SSH_SFTP_QUOTE_INIT:
3000      result = ssh_state_sftp_quote_init(data, sshc, sshp);
3001      break;
3002
3003    case SSH_SFTP_POSTQUOTE_INIT:
3004      result = ssh_state_sftp_postquote_init(data, sshc);
3005      break;
3006
3007    case SSH_SFTP_QUOTE:
3008      result = ssh_state_sftp_quote(data, sshc, sshp);
3009      break;
3010
3011    case SSH_SFTP_NEXT_QUOTE:
3012      result = ssh_state_sftp_next_quote(data, sshc);
3013      break;
3014
3015    case SSH_SFTP_QUOTE_STAT:
3016      result = ssh_state_sftp_quote_stat(data, sshc, sshp, block);
3017      break;
3018
3019    case SSH_SFTP_QUOTE_SETSTAT:
3020      result = ssh_state_sftp_quote_setstat(data, sshc, sshp);
3021      break;
3022
3023    case SSH_SFTP_QUOTE_SYMLINK:
3024      result = ssh_state_sftp_quote_symlink(data, sshc);
3025      break;
3026
3027    case SSH_SFTP_QUOTE_MKDIR:
3028      result = ssh_state_sftp_quote_mkdir(data, sshc);
3029      break;
3030
3031    case SSH_SFTP_QUOTE_RENAME:
3032      result = ssh_state_sftp_quote_rename(data, sshc);
3033      break;
3034
3035    case SSH_SFTP_QUOTE_RMDIR:
3036      result = ssh_state_sftp_quote_rmdir(data, sshc);
3037      break;
3038
3039    case SSH_SFTP_QUOTE_UNLINK:
3040      result = ssh_state_sftp_quote_unlink(data, sshc);
3041      break;
3042
3043    case SSH_SFTP_QUOTE_STATVFS:
3044      result = ssh_state_sftp_quote_statvfs(data, sshc);
3045      break;
3046
3047    case SSH_SFTP_GETINFO:
3048      result = ssh_state_sftp_getinfo(data, sshc);
3049      break;
3050
3051    case SSH_SFTP_FILETIME:
3052      result = ssh_state_sftp_filetime(data, sshc, sshp);
3053      break;
3054
3055    case SSH_SFTP_TRANS_INIT:
3056      result = ssh_state_sftp_trans_init(data, sshc, sshp);
3057      break;
3058
3059    case SSH_SFTP_UPLOAD_INIT:
3060      result = ssh_state_sftp_upload_init(data, sshc, sshp, block);
3061      break;
3062
3063    case SSH_SFTP_CREATE_DIRS_INIT:
3064      result = ssh_state_sftp_create_dirs_init(data, sshc, sshp);
3065      break;
3066
3067    case SSH_SFTP_CREATE_DIRS:
3068      result = ssh_state_sftp_create_dirs(data, sshc, sshp);
3069      break;
3070
3071    case SSH_SFTP_CREATE_DIRS_MKDIR:
3072      result = ssh_state_sftp_create_dirs_mkdir(data, sshc, sshp);
3073      break;
3074
3075    case SSH_SFTP_READDIR_INIT:
3076      result = ssh_state_sftp_readdir_init(data, sshc, sshp);
3077      break;
3078
3079    case SSH_SFTP_READDIR:
3080      result = ssh_state_sftp_readdir(data, sshc, sshp, block);
3081      break;
3082
3083    case SSH_SFTP_READDIR_LINK:
3084      result = ssh_state_sftp_readdir_link(data, sshc, sshp);
3085      break;
3086
3087    case SSH_SFTP_READDIR_BOTTOM:
3088      result = ssh_state_sftp_readdir_bottom(data, sshc, sshp);
3089      break;
3090
3091    case SSH_SFTP_READDIR_DONE:
3092      result = ssh_state_sftp_readdir_done(data, sshc);
3093      break;
3094
3095    case SSH_SFTP_DOWNLOAD_INIT:
3096      result = ssh_state_sftp_download_init(data, sshc, sshp);
3097      break;
3098
3099    case SSH_SFTP_DOWNLOAD_STAT:
3100      result = ssh_state_sftp_download_stat(data, sshc, sshp, block);
3101      break;
3102
3103    case SSH_SFTP_CLOSE:
3104      result = ssh_state_sftp_close(data, sshc, sshp);
3105      break;
3106
3107    case SSH_SFTP_SHUTDOWN:
3108      result = ssh_state_sftp_shutdown(data, sshc);
3109      break;
3110
3111    case SSH_SCP_TRANS_INIT:
3112      result = ssh_state_scp_trans_init(data, sshc, sshp);
3113      break;
3114
3115    case SSH_SCP_UPLOAD_INIT:
3116      result = ssh_state_scp_upload_init(data, sshc, sshp);
3117      break;
3118
3119    case SSH_SCP_DOWNLOAD_INIT:
3120      result = ssh_state_scp_download_init(data, sshc, sshp);
3121      break;
3122
3123    case SSH_SCP_DONE:
3124      result = ssh_state_scp_done(data, sshc);
3125      break;
3126
3127    case SSH_SCP_SEND_EOF:
3128      result = ssh_state_scp_send_eof(data, sshc);
3129      break;
3130
3131    case SSH_SCP_WAIT_EOF:
3132      result = ssh_state_scp_wait_eof(data, sshc);
3133      break;
3134
3135    case SSH_SCP_WAIT_CLOSE:
3136      result = ssh_state_scp_wait_close(data, sshc);
3137      break;
3138
3139    case SSH_SCP_CHANNEL_FREE:
3140      result = ssh_state_scp_channel_free(data, sshc);
3141      break;
3142
3143    case SSH_SESSION_DISCONNECT:
3144      result = ssh_state_session_disconnect(data, sshc);
3145      break;
3146
3147    case SSH_SESSION_FREE:
3148      result = ssh_state_session_free(data, sshc);
3149      break;
3150
3151    case SSH_QUIT:
3152    default:
3153      /* internal error */
3154      myssh_to(data, sshc, SSH_STOP);
3155      break;
3156    }
3157
3158  } while(!result && (sshc->state != SSH_STOP) && !*block);
3159
3160  if(result == CURLE_AGAIN) {
3161    /* we would block, we need to wait for the socket to be ready (in the
3162       right direction too)! */
3163    *block = TRUE;
3164    result = CURLE_OK;
3165  }
3166  CURL_TRC_SSH(data, "[%s] statemachine() -> %d, block=%d",
3167               Curl_ssh_statename(sshc->state), result, *block);
3168
3169  return result;
3170}
3171
3172/* called by the multi interface to figure out what socket(s) to wait for and
3173   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
3174static CURLcode ssh_pollset(struct Curl_easy *data,
3175                            struct easy_pollset *ps)
3176{
3177  struct connectdata *conn = data->conn;
3178  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3179  curl_socket_t sock = conn->sock[FIRSTSOCKET];
3180  int waitfor;
3181
3182  if(!sshc || (sock == CURL_SOCKET_BAD))
3183    return CURLE_FAILED_INIT;
3184
3185  waitfor = sshc->waitfor ? sshc->waitfor : data->req.io_flags;
3186  if(waitfor) {
3187    int flags = 0;
3188    if(waitfor & REQ_IO_RECV)
3189      flags |= CURL_POLL_IN;
3190    if(waitfor & REQ_IO_SEND)
3191      flags |= CURL_POLL_OUT;
3192    DEBUGASSERT(flags);
3193    CURL_TRC_SSH(data, "pollset, flags=%x", flags);
3194    return Curl_pollset_change(data, ps, sock, flags, 0);
3195  }
3196  /* While we still have a session, we listen incoming data. */
3197  if(sshc->ssh_session)
3198    return Curl_pollset_change(data, ps, sock, CURL_POLL_IN, 0);
3199  return CURLE_OK;
3200}
3201
3202/*
3203 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
3204 * function is used to figure out in what direction and stores this info so
3205 * that the multi interface can take advantage of it. Make sure to call this
3206 * function in all cases so that when it _does not_ return EAGAIN we can
3207 * restore the default wait bits.
3208 */
3209static void ssh_block2waitfor(struct Curl_easy *data,
3210                              struct ssh_conn *sshc,
3211                              bool block)
3212{
3213  int dir = 0;
3214  (void)data;
3215  if(block) {
3216    dir = libssh2_session_block_directions(sshc->ssh_session);
3217    if(dir) {
3218      /* translate the libssh2 define bits into our own bit defines */
3219      sshc->waitfor =
3220        ((dir & LIBSSH2_SESSION_BLOCK_INBOUND) ? REQ_IO_RECV : 0) |
3221        ((dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) ? REQ_IO_SEND : 0);
3222    }
3223  }
3224  if(!dir)
3225    sshc->waitfor = 0;
3226}
3227
3228/* called repeatedly until done from multi.c */
3229static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done)
3230{
3231  struct connectdata *conn = data->conn;
3232  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3233  struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY);
3234  CURLcode result = CURLE_OK;
3235  bool block; /* we store the status and use that to provide a ssh_pollset()
3236                 implementation */
3237  if(!sshc || !sshp)
3238    return CURLE_FAILED_INIT;
3239
3240  do {
3241    result = ssh_statemachine(data, sshc, sshp, &block);
3242    *done = (sshc->state == SSH_STOP);
3243    /* if there is no error, it is not done and it did not EWOULDBLOCK, then
3244       try again */
3245  } while(!result && !*done && !block);
3246  ssh_block2waitfor(data, sshc, block);
3247
3248  return result;
3249}
3250
3251static CURLcode ssh_block_statemach(struct Curl_easy *data,
3252                                    struct ssh_conn *sshc,
3253                                    struct SSHPROTO *sshp,
3254                                    bool disconnect)
3255{
3256  CURLcode result = CURLE_OK;
3257  struct curltime start = *Curl_pgrs_now(data);
3258
3259  while((sshc->state != SSH_STOP) && !result) {
3260    bool block;
3261    timediff_t left_ms = 1000;
3262
3263    result = ssh_statemachine(data, sshc, sshp, &block);
3264    if(result)
3265      break;
3266
3267    if(!disconnect) {
3268      result = Curl_pgrsCheck(data);
3269      if(result)
3270        break;
3271
3272      left_ms = Curl_timeleft_ms(data);
3273      if(left_ms < 0) {
3274        failf(data, "Operation timed out");
3275        return CURLE_OPERATION_TIMEDOUT;
3276      }
3277    }
3278    else if(curlx_ptimediff_ms(Curl_pgrs_now(data), &start) > 1000) {
3279      /* disconnect timeout */
3280      failf(data, "Disconnect timed out");
3281      result = CURLE_OK;
3282      break;
3283    }
3284
3285    if(block) {
3286      int dir = libssh2_session_block_directions(sshc->ssh_session);
3287      curl_socket_t sock = data->conn->sock[FIRSTSOCKET];
3288      curl_socket_t fd_read = CURL_SOCKET_BAD;
3289      curl_socket_t fd_write = CURL_SOCKET_BAD;
3290      if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
3291        fd_read = sock;
3292      if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
3293        fd_write = sock;
3294      /* wait for the socket to become ready */
3295      (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
3296                              left_ms > 1000 ? 1000 : left_ms);
3297    }
3298  }
3299
3300  return result;
3301}
3302
3303static void myssh_easy_dtor(void *key, size_t klen, void *entry)
3304{
3305  struct SSHPROTO *sshp = entry;
3306  (void)key;
3307  (void)klen;
3308  curlx_safefree(sshp->path);
3309  curlx_dyn_free(&sshp->readdir);
3310  curlx_dyn_free(&sshp->readdir_link);
3311  curlx_free(sshp);
3312}
3313
3314static void myssh_conn_dtor(void *key, size_t klen, void *entry)
3315{
3316  struct ssh_conn *sshc = entry;
3317  (void)key;
3318  (void)klen;
3319  sshc_cleanup(sshc, NULL, TRUE);
3320  curlx_free(sshc);
3321}
3322
3323/*
3324 * SSH setup and connection
3325 */
3326static CURLcode ssh_setup_connection(struct Curl_easy *data,
3327                                     struct connectdata *conn)
3328{
3329  struct ssh_conn *sshc;
3330  struct SSHPROTO *sshp;
3331  (void)conn;
3332
3333  sshc = curlx_calloc(1, sizeof(*sshc));
3334  if(!sshc)
3335    return CURLE_OUT_OF_MEMORY;
3336
3337  if(Curl_conn_meta_set(conn, CURL_META_SSH_CONN, sshc, myssh_conn_dtor))
3338    return CURLE_OUT_OF_MEMORY;
3339
3340  sshp = curlx_calloc(1, sizeof(*sshp));
3341  if(!sshp)
3342    return CURLE_OUT_OF_MEMORY;
3343
3344  curlx_dyn_init(&sshp->readdir, CURL_PATH_MAX * 2);
3345  curlx_dyn_init(&sshp->readdir_link, CURL_PATH_MAX);
3346  if(Curl_meta_set(data, CURL_META_SSH_EASY, sshp, myssh_easy_dtor))
3347    return CURLE_OUT_OF_MEMORY;
3348
3349  return CURLE_OK;
3350}
3351
3352static Curl_recv scp_recv, sftp_recv;
3353static Curl_send scp_send, sftp_send;
3354
3355#ifndef CURL_DISABLE_PROXY
3356static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer,
3357                            size_t length, int flags, void **abstract)
3358{
3359  struct Curl_easy *data = (struct Curl_easy *)*abstract;
3360  int sockindex = Curl_conn_sockindex(data, sock);
3361  size_t nread;
3362  CURLcode result;
3363  struct connectdata *conn = data->conn;
3364  Curl_recv *backup = conn->recv[sockindex];
3365  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3366  (void)flags;
3367
3368  if(!sshc)
3369    return -1;
3370
3371  /* swap in the TLS reader function for this call only, and then swap back
3372     the SSH one again */
3373  conn->recv[sockindex] = sshc->tls_recv;
3374  result = Curl_conn_recv(data, sockindex, buffer, length, &nread);
3375  conn->recv[sockindex] = backup;
3376  if(result == CURLE_AGAIN)
3377    return -EAGAIN; /* magic return code for libssh2 */
3378  else if(result)
3379    return -1; /* generic error */
3380  Curl_debug(data, CURLINFO_DATA_IN, (const char *)buffer, nread);
3381  return (ssize_t)nread;
3382}
3383
3384static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer,
3385                            size_t length, int flags, void **abstract)
3386{
3387  struct Curl_easy *data = (struct Curl_easy *)*abstract;
3388  int sockindex = Curl_conn_sockindex(data, sock);
3389  size_t nwrite;
3390  CURLcode result;
3391  struct connectdata *conn = data->conn;
3392  Curl_send *backup = conn->send[sockindex];
3393  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3394  (void)flags;
3395
3396  if(!sshc)
3397    return -1;
3398
3399  /* swap in the TLS writer function for this call only, and then swap back
3400     the SSH one again */
3401  conn->send[sockindex] = sshc->tls_send;
3402  result = Curl_conn_send(data, sockindex, buffer, length, FALSE, &nwrite);
3403  conn->send[sockindex] = backup;
3404  if(result == CURLE_AGAIN)
3405    return -EAGAIN; /* magic return code for libssh2 */
3406  else if(result)
3407    return -1; /* error */
3408  Curl_debug(data, CURLINFO_DATA_OUT, (const char *)buffer, nwrite);
3409  return (ssize_t)nwrite;
3410}
3411#endif
3412
3413/*
3414 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
3415 * do protocol-specific actions at connect-time.
3416 */
3417static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
3418{
3419#ifdef CURL_LIBSSH2_DEBUG
3420  curl_socket_t sock;
3421#endif
3422  struct connectdata *conn = data->conn;
3423  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3424  CURLcode result;
3425
3426#if LIBSSH2_VERSION_NUM >= 0x010b00
3427  {
3428    const char *crypto_str;
3429    switch(libssh2_crypto_engine()) {
3430    case libssh2_gcrypt:
3431      crypto_str = "libgcrypt";
3432      break;
3433    case libssh2_mbedtls:
3434      crypto_str = "mbedTLS";
3435      break;
3436    case libssh2_openssl:
3437      crypto_str = "openssl compatible";
3438      break;
3439    case libssh2_os400qc3:
3440      crypto_str = "OS400QC3";
3441      break;
3442    case libssh2_wincng:
3443      crypto_str = "WinCNG";
3444      break;
3445    default:
3446      crypto_str = NULL;
3447      break;
3448    }
3449    if(crypto_str)
3450      infof(data, "libssh2 cryptography backend: %s", crypto_str);
3451  }
3452#endif
3453
3454  if(!sshc)
3455    return CURLE_FAILED_INIT;
3456
3457  infof(data, "User: '%s'", Curl_creds_user(conn->creds));
3458#ifdef CURL_LIBSSH2_DEBUG
3459  infof(data, "Password: %s", Curl_creds_passwd(conn->creds));
3460  sock = conn->sock[FIRSTSOCKET];
3461#endif /* CURL_LIBSSH2_DEBUG */
3462
3463  /* libcurl MUST to set custom memory functions so that the kbd_callback
3464     function's memory allocations can be properly freed */
3465  sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
3466                                              my_libssh2_free,
3467                                              my_libssh2_realloc, data);
3468
3469  if(!sshc->ssh_session) {
3470    failf(data, "Failure initialising ssh session");
3471    return CURLE_FAILED_INIT;
3472  }
3473
3474  /* Set the packet read timeout if the libssh2 version supports it */
3475#if LIBSSH2_VERSION_NUM >= 0x010B00
3476  if(data->set.server_response_timeout > 0) {
3477    libssh2_session_set_read_timeout(sshc->ssh_session,
3478                             (long)(data->set.server_response_timeout / 1000));
3479  }
3480#endif
3481
3482#ifndef CURL_DISABLE_PROXY
3483  if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
3484    /*
3485      Setup libssh2 callbacks to make it read/write TLS from the socket.
3486
3487      ssize_t
3488      recvcb(libssh2_socket_t sock, void *buffer, size_t length,
3489      int flags, void **abstract);
3490
3491      ssize_t
3492      sendcb(libssh2_socket_t sock, const void *buffer, size_t length,
3493      int flags, void **abstract);
3494
3495    */
3496#if LIBSSH2_VERSION_NUM >= 0x010b01
3497    infof(data, "Uses HTTPS proxy");
3498#if defined(__clang__) && __clang_major__ >= 16
3499#pragma clang diagnostic push
3500#pragma clang diagnostic ignored "-Wcast-function-type-strict"
3501#endif
3502    libssh2_session_callback_set2(sshc->ssh_session,
3503                                  LIBSSH2_CALLBACK_RECV,
3504                                  (libssh2_cb_generic *)ssh_tls_recv);
3505    libssh2_session_callback_set2(sshc->ssh_session,
3506                                  LIBSSH2_CALLBACK_SEND,
3507                                  (libssh2_cb_generic *)ssh_tls_send);
3508#if defined(__clang__) && __clang_major__ >= 16
3509#pragma clang diagnostic pop
3510#endif
3511#else
3512    /*
3513     * This crazy union dance is here to avoid assigning a void pointer a
3514     * function pointer as it is invalid C. The problem is of course that
3515     * libssh2 has such an API...
3516     */
3517    union receive {
3518      void *recvp;
3519      ssize_t (*recvptr)(libssh2_socket_t, void *, size_t, int, void **);
3520    };
3521    union transfer {
3522      void *sendp;
3523      ssize_t (*sendptr)(libssh2_socket_t, const void *, size_t, int, void **);
3524    };
3525    union receive sshrecv;
3526    union transfer sshsend;
3527
3528    sshrecv.recvptr = ssh_tls_recv;
3529    sshsend.sendptr = ssh_tls_send;
3530
3531    infof(data, "Uses HTTPS proxy");
3532    libssh2_session_callback_set(sshc->ssh_session,
3533                                 LIBSSH2_CALLBACK_RECV, sshrecv.recvp);
3534    libssh2_session_callback_set(sshc->ssh_session,
3535                                 LIBSSH2_CALLBACK_SEND, sshsend.sendp);
3536#endif
3537
3538    /* Store the underlying TLS recv/send function pointers to be used when
3539       reading from the proxy */
3540    sshc->tls_recv = conn->recv[FIRSTSOCKET];
3541    sshc->tls_send = conn->send[FIRSTSOCKET];
3542  }
3543
3544#endif /* CURL_DISABLE_PROXY */
3545  if(conn->scheme->protocol & CURLPROTO_SCP) {
3546    conn->recv[FIRSTSOCKET] = scp_recv;
3547    conn->send[FIRSTSOCKET] = scp_send;
3548  }
3549  else {
3550    conn->recv[FIRSTSOCKET] = sftp_recv;
3551    conn->send[FIRSTSOCKET] = sftp_send;
3552  }
3553
3554  if(data->set.ssh_compression &&
3555     libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) {
3556    infof(data, "Failed to enable compression for ssh session");
3557  }
3558
3559  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
3560    int rc;
3561    sshc->kh = libssh2_knownhost_init(sshc->ssh_session);
3562    if(!sshc->kh) {
3563      libssh2_session_free(sshc->ssh_session);
3564      sshc->ssh_session = NULL;
3565      return CURLE_FAILED_INIT;
3566    }
3567
3568    /* read all known hosts from there */
3569    rc = libssh2_knownhost_readfile(sshc->kh,
3570                                    data->set.str[STRING_SSH_KNOWNHOSTS],
3571                                    LIBSSH2_KNOWNHOST_FILE_OPENSSH);
3572    if(rc < 0)
3573      infof(data, "Failed to read known hosts from %s",
3574            data->set.str[STRING_SSH_KNOWNHOSTS]);
3575  }
3576
3577#ifdef CURL_LIBSSH2_DEBUG
3578  libssh2_trace(sshc->ssh_session, ~0);
3579  infof(data, "SSH socket: %d", (int)sock);
3580#endif /* CURL_LIBSSH2_DEBUG */
3581
3582  myssh_to(data, sshc, SSH_INIT);
3583
3584  result = ssh_multi_statemach(data, done);
3585
3586  return result;
3587}
3588
3589/*
3590 ***********************************************************************
3591 *
3592 * scp_perform()
3593 *
3594 * This is the actual DO function for SCP. Get a file according to
3595 * the options previously setup.
3596 */
3597
3598static CURLcode scp_perform(struct Curl_easy *data,
3599                            bool *connected,
3600                            bool *dophase_done)
3601{
3602  struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN);
3603  CURLcode result = CURLE_OK;
3604
3605  CURL_TRC_SSH(data, "DO phase starts");
3606
3607  *dophase_done = FALSE; /* not done yet */
3608  if(!sshc)
3609    return CURLE_FAILED_INIT;
3610
3611  /* start the first command in the DO phase */
3612  myssh_to(data, sshc, SSH_SCP_TRANS_INIT);
3613
3614  /* run the state-machine */
3615  result = ssh_multi_statemach(data, dophase_done);
3616
3617  *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
3618
3619  if(*dophase_done) {
3620    CURL_TRC_SSH(data, "DO phase is complete");
3621  }
3622
3623  return result;
3624}
3625
3626/* called from multi.c while DOing */
3627static CURLcode scp_doing(struct Curl_easy *data,
3628                          bool *dophase_done)
3629{
3630  CURLcode result;
3631  result = ssh_multi_statemach(data, dophase_done);
3632
3633  if(*dophase_done) {
3634    CURL_TRC_SSH(data, "DO phase is complete");
3635  }
3636  return result;
3637}
3638
3639/* BLOCKING, but the function is using the state machine so the only reason
3640   this is still blocking is that the multi interface code has no support for
3641   disconnecting operations that takes a while */
3642static CURLcode scp_disconnect(struct Curl_easy *data,
3643                               struct connectdata *conn,
3644                               bool dead_connection)
3645{
3646  CURLcode result = CURLE_OK;
3647  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3648  struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY);
3649  (void)dead_connection;
3650
3651  if(sshc && sshc->ssh_session) {
3652    /* only if there is a session still around to use! */
3653    myssh_to(data, sshc, SSH_SESSION_DISCONNECT);
3654    result = ssh_block_statemach(data, sshc, sshp, TRUE);
3655  }
3656
3657  if(sshc)
3658    return sshc_cleanup(sshc, data, TRUE);
3659  return result;
3660}
3661
3662/* generic done function for both SCP and SFTP called from their specific
3663   done functions */
3664static CURLcode ssh_done(struct Curl_easy *data, CURLcode status)
3665{
3666  struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN);
3667  struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY);
3668  CURLcode result = CURLE_OK;
3669
3670  if(!sshc || !sshp)
3671    return CURLE_FAILED_INIT;
3672
3673  if(!status)
3674    /* run the state-machine */
3675    result = ssh_block_statemach(data, sshc, sshp, FALSE);
3676  else
3677    result = status;
3678
3679  if(Curl_pgrsDone(data))
3680    return CURLE_ABORTED_BY_CALLBACK;
3681
3682  CURL_REQ_CLEAR_IO(data);
3683  return result;
3684}
3685
3686static CURLcode scp_done(struct Curl_easy *data, CURLcode status,
3687                         bool premature)
3688{
3689  struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN);
3690  (void)premature;
3691
3692  if(sshc && !status)
3693    myssh_to(data, sshc, SSH_SCP_DONE);
3694
3695  return ssh_done(data, status);
3696}
3697
3698static CURLcode scp_send(struct Curl_easy *data, int sockindex,
3699                         const uint8_t *mem, size_t len, bool eos,
3700                         size_t *pnwritten)
3701{
3702  struct connectdata *conn = data->conn;
3703  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3704  CURLcode result = CURLE_OK;
3705  ssize_t nwritten;
3706
3707  (void)sockindex; /* we only support SCP on the fixed known primary socket */
3708  (void)eos;
3709  *pnwritten = 0;
3710
3711  if(!sshc)
3712    return CURLE_FAILED_INIT;
3713
3714  /* libssh2_channel_write() returns int! */
3715  nwritten = (ssize_t)libssh2_channel_write(sshc->ssh_channel,
3716                                            (const char *)mem, len);
3717
3718  ssh_block2waitfor(data, sshc, (nwritten == LIBSSH2_ERROR_EAGAIN));
3719
3720  if(nwritten == LIBSSH2_ERROR_EAGAIN)
3721    result = CURLE_AGAIN;
3722  else if(nwritten < LIBSSH2_ERROR_NONE)
3723    result = libssh2_session_error_to_CURLE((int)nwritten);
3724  else
3725    *pnwritten = (size_t)nwritten;
3726
3727  return result;
3728}
3729
3730static CURLcode scp_recv(struct Curl_easy *data, int sockindex,
3731                         char *mem, size_t len, size_t *pnread)
3732{
3733  struct connectdata *conn = data->conn;
3734  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3735  CURLcode result = CURLE_OK;
3736  ssize_t nread;
3737
3738  (void)sockindex; /* we only support SCP on the fixed known primary socket */
3739  *pnread = 0;
3740
3741  if(!sshc)
3742    return CURLE_FAILED_INIT;
3743
3744  /* libssh2_channel_read() returns int */
3745  nread = (ssize_t)libssh2_channel_read(sshc->ssh_channel, mem, len);
3746
3747  ssh_block2waitfor(data, sshc, (nread == LIBSSH2_ERROR_EAGAIN));
3748  if(nread == LIBSSH2_ERROR_EAGAIN)
3749    return CURLE_AGAIN;
3750  else if(nread < LIBSSH2_ERROR_NONE)
3751    result = libssh2_session_error_to_CURLE((int)nread);
3752  else
3753    *pnread = (size_t)nread;
3754
3755  return result;
3756}
3757
3758/*
3759 * =============== SFTP ===============
3760 */
3761
3762/*
3763 ***********************************************************************
3764 *
3765 * sftp_perform()
3766 *
3767 * This is the actual DO function for SFTP. Get a file/directory according to
3768 * the options previously setup.
3769 */
3770
3771static CURLcode sftp_perform(struct Curl_easy *data,
3772                             bool *connected,
3773                             bool *dophase_done)
3774{
3775  struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN);
3776  CURLcode result = CURLE_OK;
3777
3778  CURL_TRC_SSH(data, "DO phase starts");
3779
3780  *dophase_done = FALSE; /* not done yet */
3781  if(!sshc)
3782    return CURLE_FAILED_INIT;
3783
3784  /* start the first command in the DO phase */
3785  myssh_to(data, sshc, SSH_SFTP_QUOTE_INIT);
3786
3787  /* run the state-machine */
3788  result = ssh_multi_statemach(data, dophase_done);
3789
3790  *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
3791
3792  if(*dophase_done) {
3793    CURL_TRC_SSH(data, "DO phase is complete");
3794  }
3795
3796  return result;
3797}
3798
3799/* called from multi.c while DOing */
3800static CURLcode sftp_doing(struct Curl_easy *data,
3801                           bool *dophase_done)
3802{
3803  CURLcode result = ssh_multi_statemach(data, dophase_done);
3804
3805  if(*dophase_done) {
3806    CURL_TRC_SSH(data, "DO phase is complete");
3807  }
3808  return result;
3809}
3810
3811/* BLOCKING, but the function is using the state machine so the only reason
3812   this is still blocking is that the multi interface code has no support for
3813   disconnecting operations that takes a while */
3814static CURLcode sftp_disconnect(struct Curl_easy *data,
3815                                struct connectdata *conn, bool dead_connection)
3816{
3817  CURLcode result = CURLE_OK;
3818  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3819  struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY);
3820  (void)dead_connection;
3821
3822  if(sshc) {
3823    if(sshc->ssh_session) {
3824      /* only if there is a session still around to use! */
3825      CURL_TRC_SSH(data, "DISCONNECT starts now");
3826      myssh_to(data, sshc, SSH_SFTP_SHUTDOWN);
3827      result = ssh_block_statemach(data, sshc, sshp, TRUE);
3828      CURL_TRC_SSH(data, "DISCONNECT is done -> %d", result);
3829    }
3830    sshc_cleanup(sshc, data, TRUE);
3831  }
3832  return result;
3833}
3834
3835static CURLcode sftp_done(struct Curl_easy *data, CURLcode status,
3836                          bool premature)
3837{
3838  struct connectdata *conn = data->conn;
3839  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3840
3841  if(!sshc)
3842    return CURLE_FAILED_INIT;
3843
3844  if(!status) {
3845    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3846       errors that could happen due to open file handles during POSTQUOTE
3847       operation */
3848    if(!premature && data->set.postquote && !conn->bits.retry)
3849      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3850    myssh_to(data, sshc, SSH_SFTP_CLOSE);
3851  }
3852  return ssh_done(data, status);
3853}
3854
3855/* return number of sent bytes */
3856static CURLcode sftp_send(struct Curl_easy *data, int sockindex,
3857                          const uint8_t *mem, size_t len, bool eos,
3858                          size_t *pnwritten)
3859{
3860  struct connectdata *conn = data->conn;
3861  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3862  ssize_t nwrite;
3863
3864  (void)sockindex;
3865  (void)eos;
3866  *pnwritten = 0;
3867
3868  if(!sshc)
3869    return CURLE_FAILED_INIT;
3870
3871  nwrite = libssh2_sftp_write(sshc->sftp_handle, (const char *)mem, len);
3872
3873  ssh_block2waitfor(data, sshc, (nwrite == LIBSSH2_ERROR_EAGAIN));
3874
3875  if(nwrite == LIBSSH2_ERROR_EAGAIN)
3876    return CURLE_AGAIN;
3877  else if(nwrite < LIBSSH2_ERROR_NONE)
3878    return libssh2_session_error_to_CURLE((int)nwrite);
3879  *pnwritten = (size_t)nwrite;
3880  return CURLE_OK;
3881}
3882
3883/*
3884 * Return number of received (decrypted) bytes
3885 * or <0 on error
3886 */
3887static CURLcode sftp_recv(struct Curl_easy *data, int sockindex,
3888                          char *mem, size_t len, size_t *pnread)
3889{
3890  struct connectdata *conn = data->conn;
3891  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3892  ssize_t nread;
3893
3894  (void)sockindex;
3895  *pnread = 0;
3896
3897  if(!sshc)
3898    return CURLE_FAILED_INIT;
3899
3900  nread = libssh2_sftp_read(sshc->sftp_handle, mem, len);
3901
3902  ssh_block2waitfor(data, sshc, (nread == LIBSSH2_ERROR_EAGAIN));
3903
3904  if(nread == LIBSSH2_ERROR_EAGAIN)
3905    return CURLE_AGAIN;
3906  else if(nread < 0)
3907    return libssh2_session_error_to_CURLE((int)nread);
3908
3909  *pnread = (size_t)nread;
3910  return CURLE_OK;
3911}
3912
3913/*
3914 * The DO function is generic for both protocols. There was previously two
3915 * separate ones but this way means less duplicated code.
3916 */
3917static CURLcode ssh_do(struct Curl_easy *data, bool *done)
3918{
3919  CURLcode result;
3920  bool connected = FALSE;
3921  struct connectdata *conn = data->conn;
3922  struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3923
3924  *done = FALSE; /* default to false */
3925  if(!sshc)
3926    return CURLE_FAILED_INIT;
3927
3928  data->req.size = -1; /* make sure this is unknown at this point */
3929  sshc->secondCreateDirs = 0;   /* reset the create directory attempt state
3930                                   variable */
3931
3932  Curl_pgrsReset(data);
3933
3934  if(conn->scheme->protocol & CURLPROTO_SCP)
3935    result = scp_perform(data, &connected, done);
3936  else
3937    result = sftp_perform(data, &connected, done);
3938
3939  return result;
3940}
3941
3942CURLcode Curl_ssh_init(void)
3943{
3944  if(libssh2_init(0)) {
3945    DEBUGF(curl_mfprintf(stderr, "Error: libssh2_init failed\n"));
3946    return CURLE_FAILED_INIT;
3947  }
3948  return CURLE_OK;
3949}
3950
3951void Curl_ssh_cleanup(void)
3952{
3953  libssh2_exit();
3954}
3955
3956void Curl_ssh_version(char *buffer, size_t buflen)
3957{
3958  (void)curl_msnprintf(buffer, buflen, "libssh2/%s", libssh2_version(0));
3959}
3960
3961/* The SSH session is associated with the *CONNECTION* but the callback user
3962 * pointer is an easy handle pointer. This function allows us to reassign the
3963 * user pointer to the *CURRENT* (new) easy handle.
3964 */
3965static void ssh_attach(struct Curl_easy *data, struct connectdata *conn)
3966{
3967  DEBUGASSERT(data);
3968  DEBUGASSERT(conn);
3969  if(conn->scheme->protocol & PROTO_FAMILY_SSH) {
3970    struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
3971    if(sshc && sshc->ssh_session) {
3972      /* only re-attach if the session already exists */
3973      void **abstract = libssh2_session_abstract(sshc->ssh_session);
3974      *abstract = data;
3975    }
3976  }
3977}
3978
3979/*
3980 * SCP protocol handler.
3981 */
3982const struct Curl_protocol Curl_protocol_scp = {
3983  ssh_setup_connection,                 /* setup_connection */
3984  ssh_do,                               /* do_it */
3985  scp_done,                             /* done */
3986  ZERO_NULL,                            /* do_more */
3987  ssh_connect,                          /* connect_it */
3988  ssh_multi_statemach,                  /* connecting */
3989  scp_doing,                            /* doing */
3990  ssh_pollset,                          /* proto_pollset */
3991  ssh_pollset,                          /* doing_pollset */
3992  ZERO_NULL,                            /* domore_pollset */
3993  ssh_pollset,                          /* perform_pollset */
3994  scp_disconnect,                       /* disconnect */
3995  ZERO_NULL,                            /* write_resp */
3996  ZERO_NULL,                            /* write_resp_hd */
3997  ZERO_NULL,                            /* connection_is_dead */
3998  ssh_attach,                           /* attach */
3999  ZERO_NULL,                            /* follow */
4000};
4001
4002/*
4003 * SFTP protocol handler.
4004 */
4005const struct Curl_protocol Curl_protocol_sftp = {
4006  ssh_setup_connection,                 /* setup_connection */
4007  ssh_do,                               /* do_it */
4008  sftp_done,                            /* done */
4009  ZERO_NULL,                            /* do_more */
4010  ssh_connect,                          /* connect_it */
4011  ssh_multi_statemach,                  /* connecting */
4012  sftp_doing,                           /* doing */
4013  ssh_pollset,                          /* proto_pollset */
4014  ssh_pollset,                          /* doing_pollset */
4015  ZERO_NULL,                            /* domore_pollset */
4016  ssh_pollset,                          /* perform_pollset */
4017  sftp_disconnect,                      /* disconnect */
4018  ZERO_NULL,                            /* write_resp */
4019  ZERO_NULL,                            /* write_resp_hd */
4020  ZERO_NULL,                            /* connection_is_dead */
4021  ssh_attach,                           /* attach */
4022  ZERO_NULL,                            /* follow */
4023};
4024
4025#endif /* USE_LIBSSH2 */