From 02b5aee3b3491e6bed9fd7f368be94b2e460cd45 Mon Sep 17 00:00:00 2001 From: pNext <843609378@qq.com> Date: Fri, 30 Dec 2022 10:54:18 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rust/rust_ffi/src/ffi_fun/fun_call.rs | 5095 +++--- rust/rust_macro/src/get_macros.rs | 13 +- rust/rust_project/src/ftp.rs | 562 +- rust/rust_project/src/ftplistparser.rs | 2252 ++- rust/rust_project/src/http.rs | 3289 ++-- rust/rust_project/src/http2.rs | 3265 ++-- rust/rust_project/src/http_aws_sigv4.rs | 1474 +- rust/rust_project/src/http_chunks.rs | 632 +- rust/rust_project/src/http_digest.rs | 405 +- rust/rust_project/src/http_negotiate.rs | 535 +- rust/rust_project/src/http_ntlm.rs | 703 +- rust/rust_project/src/http_proxy.rs | 2726 ++-- rust/rust_project/src/vtls/gtls.rs | 6656 ++++---- rust/rust_project/src/vtls/keylog.rs | 10 +- rust/rust_project/src/vtls/mbedtls.rs | 4504 +++--- .../src/vtls/mbedtls_threadlock.rs | 4 +- rust/rust_project/src/vtls/nss.rs | 82 +- rust/rust_project/src/vtls/openssl.rs | 12931 ++++++++-------- rust/rust_project/src/vtls/vtls.rs | 48 +- rust/rust_project/src/vtls/wolfssl.rs | 16 +- 20 files changed, 22643 insertions(+), 22559 deletions(-) mode change 100755 => 100644 rust/rust_project/src/vtls/openssl.rs mode change 100755 => 100644 rust/rust_project/src/vtls/vtls.rs mode change 100755 => 100644 rust/rust_project/src/vtls/wolfssl.rs diff --git a/rust/rust_ffi/src/ffi_fun/fun_call.rs b/rust/rust_ffi/src/ffi_fun/fun_call.rs index 9ec4466..0324b17 100644 --- a/rust/rust_ffi/src/ffi_fun/fun_call.rs +++ b/rust/rust_ffi/src/ffi_fun/fun_call.rs @@ -12,2550 +12,2550 @@ * Create: 2022-10-31 * Description: extern C function declarations that ffi needed ******************************************************************************/ - use crate::src::ffi_alias::type_alias::*; - use crate::src::ffi_struct::struct_define::*; - - extern "C" { - // keylog.rs - pub fn curl_getenv(variable: *const libc::c_char) -> *mut libc::c_char; - pub fn fclose(__stream: *mut FILE) -> libc::c_int; - pub fn fopen(_: *const libc::c_char, _: *const libc::c_char) -> *mut FILE; - pub fn setvbuf( - __stream: *mut FILE, - __buf: *mut libc::c_char, - __modes: libc::c_int, - __n: size_t, - ) -> libc::c_int; - pub fn fputs(__s: *const libc::c_char, __stream: *mut FILE) -> libc::c_int; - pub fn memcpy( - _: *mut libc::c_void, - _: *const libc::c_void, - _: libc::c_ulong, - ) -> *mut libc::c_void; - pub fn strlen(_: *const libc::c_char) -> libc::c_ulong; - - // vtls.rs - pub fn memcmp(_: *const libc::c_void, _: *const libc::c_void, _: libc::c_ulong) -> libc::c_int; - pub fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int; - pub fn Curl_safe_strcasecompare( - first: *const libc::c_char, - second: *const libc::c_char, - ) -> libc::c_int; - - // ftp.rs - pub fn Curl_sec_read_msg( - data: *mut Curl_easy, - conn: *mut connectdata, - _: *mut libc::c_char, - _: protection_level, - ) -> libc::c_int; - pub fn Curl_sec_end(_: *mut connectdata); - pub fn Curl_sec_login(_: *mut Curl_easy, _: *mut connectdata) -> CURLcode; - pub fn Curl_sec_request_prot(conn: *mut connectdata, level: *const libc::c_char) - -> libc::c_int; - pub fn strcpy(_: *mut libc::c_char, _: *const libc::c_char) -> *mut libc::c_char; - pub fn strncpy( - _: *mut libc::c_char, - _: *const libc::c_char, - _: libc::c_ulong, - ) -> *mut libc::c_char; - pub fn strncmp(_: *const libc::c_char, _: *const libc::c_char, _: libc::c_ulong) - -> libc::c_int; - pub fn bind(__fd: libc::c_int, __addr: *const sockaddr, __len: socklen_t) -> libc::c_int; - pub fn getsockname( - __fd: libc::c_int, - __addr: *mut sockaddr, - __len: *mut socklen_t, - ) -> libc::c_int; - pub fn listen(__fd: libc::c_int, __n: libc::c_int) -> libc::c_int; - pub fn accept( - __fd: libc::c_int, - __addr: *mut sockaddr, - __addr_len: *mut socklen_t, - ) -> libc::c_int; - pub fn sscanf(_: *const libc::c_char, _: *const libc::c_char, _: ...) -> libc::c_int; - pub fn Curl_isdigit(c: libc::c_int) -> libc::c_int; - pub fn __errno_location() -> *mut libc::c_int; - pub fn strtol( - _: *const libc::c_char, - _: *mut *mut libc::c_char, - _: libc::c_int, - ) -> libc::c_long; - pub fn strtoul( - _: *const libc::c_char, - _: *mut *mut libc::c_char, - _: libc::c_int, - ) -> libc::c_ulong; - pub fn strchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char; - pub fn strrchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char; - pub fn strstr(_: *const libc::c_char, _: *const libc::c_char) -> *mut libc::c_char; - pub fn curl_easy_strerror(_: CURLcode) -> *const libc::c_char; - pub fn inet_pton( - __af: libc::c_int, - __cp: *const libc::c_char, - __buf: *mut libc::c_void, - ) -> libc::c_int; - pub fn inet_ntop( - __af: libc::c_int, - __cp: *const libc::c_void, - __buf: *mut libc::c_char, - __len: socklen_t, - ) -> *const libc::c_char; - pub fn Curl_now() -> curltime; - pub fn Curl_timediff(t1: curltime, t2: curltime) -> timediff_t; - pub fn Curl_llist_remove(_: *mut Curl_llist, _: *mut Curl_llist_element, _: *mut libc::c_void); - pub fn Curl_resolver_wait_resolv( - data: *mut Curl_easy, - dnsentry: *mut *mut Curl_dns_entry, - ) -> CURLcode; - pub fn Curl_resolv( - data: *mut Curl_easy, - hostname: *const libc::c_char, - port: libc::c_int, - allowDOH: bool, - dnsentry: *mut *mut Curl_dns_entry, - ) -> resolve_t; - pub fn Curl_resolv_unlock(data: *mut Curl_easy, dns: *mut Curl_dns_entry); - pub fn Curl_printable_address( - ip: *const Curl_addrinfo, - buf: *mut libc::c_char, - bufsize: size_t, - ); - pub fn Curl_pp_statemach( - data: *mut Curl_easy, - pp: *mut pingpong, - block: bool, - disconnecting: bool, - ) -> CURLcode; - pub fn Curl_pp_init(data: *mut Curl_easy, pp: *mut pingpong); - pub fn Curl_pp_setup(pp: *mut pingpong); - pub fn Curl_pp_state_timeout( - data: *mut Curl_easy, - pp: *mut pingpong, - disconnecting: bool, - ) -> timediff_t; - pub fn Curl_pp_sendf( - data: *mut Curl_easy, - pp: *mut pingpong, - fmt: *const libc::c_char, - _: ... - ) -> CURLcode; - pub fn Curl_pp_readresp( - data: *mut Curl_easy, - sockfd: curl_socket_t, - pp: *mut pingpong, - code: *mut libc::c_int, - size: *mut size_t, - ) -> CURLcode; - pub fn Curl_pp_flushsend(data: *mut Curl_easy, pp: *mut pingpong) -> CURLcode; - pub fn Curl_pp_disconnect(pp: *mut pingpong) -> CURLcode; - pub fn Curl_pp_getsock( - data: *mut Curl_easy, - pp: *mut pingpong, - socks: *mut curl_socket_t, - ) -> libc::c_int; - pub fn Curl_infof(_: *mut Curl_easy, fmt: *const libc::c_char, _: ...); - pub fn Curl_failf(_: *mut Curl_easy, fmt: *const libc::c_char, _: ...); - pub fn Curl_client_write( - data: *mut Curl_easy, - type_0: libc::c_int, - ptr: *mut libc::c_char, - len: size_t, - ) -> CURLcode; - pub fn Curl_ipv6_scope(sa: *const sockaddr) -> libc::c_uint; - pub fn Curl_if2ip( - af: libc::c_int, - remote_scope: libc::c_uint, - local_scope_id: libc::c_uint, - interf: *const libc::c_char, - buf: *mut libc::c_char, - buf_size: libc::c_int, - ) -> if2ip_result_t; - pub fn Curl_pgrsSetDownloadSize(data: *mut Curl_easy, size: curl_off_t); - pub fn Curl_pgrsSetUploadSize(data: *mut Curl_easy, size: curl_off_t); - pub fn Curl_pgrsSetDownloadCounter(data: *mut Curl_easy, size: curl_off_t); - pub fn Curl_pgrsSetUploadCounter(data: *mut Curl_easy, size: curl_off_t); - pub fn Curl_pgrsUpdate(data: *mut Curl_easy) -> libc::c_int; - pub fn Curl_pgrsTime(data: *mut Curl_easy, timer: timerid) -> curltime; - pub fn Curl_setup_transfer( - data: *mut Curl_easy, - sockindex: libc::c_int, - size: curl_off_t, - getheader: bool, - writesockindex: libc::c_int, - ); - pub fn Curl_urldecode( - data: *mut Curl_easy, - string: *const libc::c_char, - length: size_t, - ostring: *mut *mut libc::c_char, - olen: *mut size_t, - ctrl: urlreject, - ) -> CURLcode; - // definitions in ftplistparser.rs - pub fn Curl_ftp_parselist( - buffer: *mut libc::c_char, - size: size_t, - nmemb: size_t, - connptr: *mut libc::c_void, - ) -> size_t; - pub fn Curl_ftp_parselist_geterror(pl_data: *mut ftp_parselist_data) -> CURLcode; - pub fn Curl_ftp_parselist_data_alloc() -> *mut ftp_parselist_data; - pub fn Curl_ftp_parselist_data_free(pl_data: *mut *mut ftp_parselist_data); - pub fn Curl_range(data: *mut Curl_easy) -> CURLcode; - pub fn curlx_strtoofft( - str: *const libc::c_char, - endp: *mut *mut libc::c_char, - base: libc::c_int, - num: *mut curl_off_t, - ) -> CURLofft; - pub fn Curl_strcasecompare( - first: *const libc::c_char, - second: *const libc::c_char, - ) -> libc::c_int; - pub fn Curl_raw_toupper(in_0: libc::c_char) -> libc::c_char; - pub fn Curl_is_connected( - data: *mut Curl_easy, - conn: *mut connectdata, - sockindex: libc::c_int, - connected: *mut bool, - ) -> CURLcode; - pub fn Curl_connecthost( - data: *mut Curl_easy, - conn: *mut connectdata, - host: *const Curl_dns_entry, - ) -> CURLcode; - pub fn Curl_timeleft( - data: *mut Curl_easy, - nowp: *mut curltime, - duringconnect: bool, - ) -> timediff_t; - pub fn Curl_socket( - data: *mut Curl_easy, - ai: *const Curl_addrinfo, - addr: *mut Curl_sockaddr_ex, - sockfd: *mut curl_socket_t, - ) -> CURLcode; - pub fn curlx_nonblock(sockfd: curl_socket_t, nonblock: libc::c_int) -> libc::c_int; - pub fn Curl_conninfo_remote( - data: *mut Curl_easy, - conn: *mut connectdata, - sockfd: curl_socket_t, - ); - pub fn Curl_closesocket( - data: *mut Curl_easy, - conn: *mut connectdata, - sock: curl_socket_t, - ) -> libc::c_int; - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - pub fn Curl_conncontrol(conn: *mut connectdata, closeit: libc::c_int); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - pub fn Curl_conncontrol( - conn: *mut connectdata, - closeit: libc::c_int, - reason: *const libc::c_char, - ); - pub fn Curl_conn_data_pending(conn: *mut connectdata, sockindex: libc::c_int) -> bool; - pub fn Curl_strerror( - err: libc::c_int, - buf: *mut libc::c_char, - buflen: size_t, - ) -> *const libc::c_char; - pub fn Curl_socket_check( - readfd: curl_socket_t, - readfd2: curl_socket_t, - writefd: curl_socket_t, - timeout_ms: timediff_t, - ) -> libc::c_int; - pub fn Curl_gmtime(intime: time_t, store: *mut tm) -> CURLcode; - pub fn Curl_getdate_capped(p: *const libc::c_char) -> time_t; - pub fn Curl_expire(data: *mut Curl_easy, milli: timediff_t, _: expire_id); - pub fn Curl_set_in_callback(data: *mut Curl_easy, value: bool); - pub fn curlx_ultous(ulnum: libc::c_ulong) -> libc::c_ushort; - pub fn curlx_sltosi(slnum: libc::c_long) -> libc::c_int; - pub fn curlx_sotouz(sonum: curl_off_t) -> size_t; - pub fn Curl_proxyCONNECT( - data: *mut Curl_easy, - tunnelsocket: libc::c_int, - hostname: *const libc::c_char, - remote_port: libc::c_int, - ) -> CURLcode; - pub fn Curl_proxy_connect(data: *mut Curl_easy, sockindex: libc::c_int) -> CURLcode; - pub fn Curl_connect_ongoing(conn: *mut connectdata) -> bool; - pub fn Curl_SOCKS_getsock( - conn: *mut connectdata, - sock: *mut curl_socket_t, - sockindex: libc::c_int, - ) -> libc::c_int; - pub fn curl_msnprintf( - buffer: *mut libc::c_char, - maxlength: size_t, - format: *const libc::c_char, - _: ... - ) -> libc::c_int; - pub fn curl_maprintf(format: *const libc::c_char, _: ...) -> *mut libc::c_char; - pub fn Curl_isalnum(c: libc::c_int) -> libc::c_int; - pub fn Curl_isspace(c: libc::c_int) -> libc::c_int; - pub fn Curl_llist_insert_next( - _: *mut Curl_llist, - _: *mut Curl_llist_element, - _: *const libc::c_void, - node: *mut Curl_llist_element, - ); - pub fn Curl_fileinfo_alloc() -> *mut fileinfo; - pub fn Curl_fileinfo_cleanup(finfo: *mut fileinfo); - pub fn Curl_fnmatch( - ptr: *mut libc::c_void, - pattern: *const libc::c_char, - string: *const libc::c_char, - ) -> libc::c_int; - // http_aws_sigv4.rs - pub fn time(__timer: *mut time_t) -> time_t; - pub fn strftime( - __s: *mut libc::c_char, - __maxsize: size_t, - __format: *const libc::c_char, - __tp: *const tm, - ) -> size_t; - pub fn Curl_http_method( - data: *mut Curl_easy, - conn: *mut connectdata, - method: *mut *const libc::c_char, - _: *mut Curl_HttpReq, - ); - pub fn Curl_strntoupper(dest: *mut libc::c_char, src: *const libc::c_char, n: size_t); - pub fn Curl_strntolower(dest: *mut libc::c_char, src: *const libc::c_char, n: size_t); - pub fn Curl_memdup(src: *const libc::c_void, buffer_length: size_t) -> *mut libc::c_void; - pub fn Curl_sha256it(outbuffer: *mut libc::c_uchar, input: *const libc::c_uchar, len: size_t); - pub fn Curl_hmacit( - hashparams: *const HMAC_params, - key: *const libc::c_uchar, - keylen: size_t, - data: *const libc::c_uchar, - datalen: size_t, - output: *mut libc::c_uchar, - ) -> CURLcode; - pub fn Curl_checkheaders( - data: *const Curl_easy, - thisheader: *const libc::c_char, - ) -> *mut libc::c_char; - // http_proxy.rs - pub fn curl_strnequal( - s1: *const libc::c_char, - s2: *const libc::c_char, - n: size_t, - ) -> libc::c_int; - pub fn Curl_httpchunk_init(data: *mut Curl_easy); - pub fn Curl_httpchunk_read( - data: *mut Curl_easy, - datap: *mut libc::c_char, - length: ssize_t, - wrote: *mut ssize_t, - passthru: *mut CURLcode, - ) -> CHUNKcode; - pub fn Curl_dyn_init(s: *mut dynbuf, toobig: size_t); - pub fn Curl_dyn_free(s: *mut dynbuf); - pub fn Curl_dyn_addn(s: *mut dynbuf, mem: *const libc::c_void, len: size_t) -> CURLcode; - pub fn Curl_dyn_add(s: *mut dynbuf, str: *const libc::c_char) -> CURLcode; - pub fn Curl_dyn_addf(s: *mut dynbuf, fmt: *const libc::c_char, _: ...) -> CURLcode; - pub fn Curl_dyn_reset(s: *mut dynbuf); - pub fn Curl_dyn_ptr(s: *const dynbuf) -> *mut libc::c_char; - pub fn Curl_dyn_len(s: *const dynbuf) -> size_t; - pub fn Curl_compareheader( - headerline: *const libc::c_char, - header: *const libc::c_char, - content: *const libc::c_char, - ) -> bool; - pub fn Curl_copy_header_value(header: *const libc::c_char) -> *mut libc::c_char; - pub fn Curl_checkProxyheaders( - data: *mut Curl_easy, - conn: *const connectdata, - thisheader: *const libc::c_char, - ) -> *mut libc::c_char; - pub fn Curl_buffer_send( - in_0: *mut dynbuf, - data: *mut Curl_easy, - bytes_written: *mut curl_off_t, - included_body_bytes: curl_off_t, - socketindex: libc::c_int, - ) -> CURLcode; - pub fn Curl_http_input_auth( - data: *mut Curl_easy, - proxy: bool, - auth: *const libc::c_char, - ) -> CURLcode; - pub fn Curl_http_auth_act(data: *mut Curl_easy) -> CURLcode; - pub fn Curl_http_output_auth( - data: *mut Curl_easy, - conn: *mut connectdata, - request: *const libc::c_char, - httpreq: Curl_HttpReq, - path: *const libc::c_char, - proxytunnel: bool, - ) -> CURLcode; - pub fn Curl_read( - data: *mut Curl_easy, - sockfd: curl_socket_t, - buf: *mut libc::c_char, - buffersize: size_t, - n: *mut ssize_t, - ) -> CURLcode; - pub fn Curl_write( - data: *mut Curl_easy, - sockfd: curl_socket_t, - mem: *const libc::c_void, - len: size_t, - written: *mut ssize_t, - ) -> CURLcode; - pub fn Curl_debug( - data: *mut Curl_easy, - type_0: curl_infotype, - ptr: *mut libc::c_char, - size: size_t, - ) -> libc::c_int; - pub fn Curl_fillreadbuffer( - data: *mut Curl_easy, - bytes: size_t, - nreadp: *mut size_t, - ) -> CURLcode; - pub fn Curl_get_upload_buffer(data: *mut Curl_easy) -> CURLcode; - pub fn Curl_isxdigit(c: libc::c_int) -> libc::c_int; - pub fn Curl_unencode_write( - data: *mut Curl_easy, - writer: *mut contenc_writer, - buf: *const libc::c_char, - nbytes: size_t, - ) -> CURLcode; - - // http.rs - pub fn curl_url_cleanup(handle: *mut CURLU); - pub fn curl_url_dup(in_0: *mut CURLU) -> *mut CURLU; - pub fn curl_url_get( - handle: *mut CURLU, - what: CURLUPart, - part: *mut *mut libc::c_char, - flags: libc::c_uint, - ) -> CURLUcode; - pub fn curl_url_set( - handle: *mut CURLU, - what: CURLUPart, - part: *const libc::c_char, - flags: libc::c_uint, - ) -> CURLUcode; - pub fn memmove( - _: *mut libc::c_void, - _: *const libc::c_void, - _: libc::c_ulong, - ) -> *mut libc::c_void; - pub fn memchr(_: *const libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void; - pub fn curl_mime_headers( - part: *mut curl_mimepart, - headers: *mut curl_slist, - take_ownership: libc::c_int, - ) -> CURLcode; - pub fn Curl_mime_initpart(part: *mut curl_mimepart, easy: *mut Curl_easy); - pub fn Curl_mime_cleanpart(part: *mut curl_mimepart); - pub fn Curl_mime_prepare_headers( - part: *mut curl_mimepart, - contenttype: *const libc::c_char, - disposition: *const libc::c_char, - strategy: mimestrategy, - ) -> CURLcode; - pub fn Curl_mime_size(part: *mut curl_mimepart) -> curl_off_t; - pub fn Curl_mime_read( - buffer: *mut libc::c_char, - size: size_t, - nitems: size_t, - instream: *mut libc::c_void, - ) -> size_t; - pub fn Curl_mime_rewind(part: *mut curl_mimepart) -> CURLcode; - pub fn Curl_cookie_freelist(cookies: *mut Cookie); - pub fn Curl_cookie_getlist( - c: *mut CookieInfo, - host: *const libc::c_char, - path: *const libc::c_char, - secure: bool, - ) -> *mut Cookie; - pub fn Curl_cookie_add( - data: *mut Curl_easy, - c: *mut CookieInfo, - header: bool, - noexpiry: bool, - lineptr: *mut libc::c_char, - domain: *const libc::c_char, - path: *const libc::c_char, - secure: bool, - ) -> *mut Cookie; - pub fn Curl_getformdata( - data: *mut Curl_easy, - _: *mut curl_mimepart, - post: *mut curl_httppost, - fread_func: curl_read_callback, - ) -> CURLcode; - pub fn Curl_rtsp_parseheader(data: *mut Curl_easy, header: *mut libc::c_char) -> CURLcode; - pub fn Curl_readrewind(data: *mut Curl_easy) -> CURLcode; - pub fn Curl_meets_timecondition(data: *mut Curl_easy, timeofdoc: time_t) -> bool; - pub fn Curl_done_sending(data: *mut Curl_easy, k: *mut SingleRequest) -> CURLcode; - pub fn Curl_base64_encode( - data: *mut Curl_easy, - inputbuff: *const libc::c_char, - insize: size_t, - outptr: *mut *mut libc::c_char, - outlen: *mut size_t, - ) -> CURLcode; - pub fn Curl_auth_is_digest_supported() -> bool; - pub fn Curl_input_digest( - data: *mut Curl_easy, - proxy: bool, - header: *const libc::c_char, - ) -> CURLcode; - pub fn Curl_output_digest( - data: *mut Curl_easy, - proxy: bool, - request: *const libc::c_uchar, - uripath: *const libc::c_uchar, - ) -> CURLcode; - pub fn Curl_output_aws_sigv4(data: *mut Curl_easy, proxy: bool) -> CURLcode; - pub fn Curl_share_lock(_: *mut Curl_easy, _: curl_lock_data, _: curl_lock_access) - -> CURLSHcode; - pub fn Curl_share_unlock(_: *mut Curl_easy, _: curl_lock_data) -> CURLSHcode; - pub fn Curl_expire_done(data: *mut Curl_easy, id: expire_id); - pub fn Curl_strncasecompare( - first: *const libc::c_char, - second: *const libc::c_char, - max: size_t, - ) -> libc::c_int; - pub fn Curl_build_unencoding_stack( - data: *mut Curl_easy, - enclist: *const libc::c_char, - maybechunked: libc::c_int, - ) -> CURLcode; - pub fn Curl_unencode_cleanup(data: *mut Curl_easy); - pub fn curlx_uitous(uinum: libc::c_uint) -> libc::c_ushort; - pub fn Curl_http2_request_upgrade(req: *mut dynbuf, data: *mut Curl_easy) -> CURLcode; - pub fn Curl_http2_setup(data: *mut Curl_easy, conn: *mut connectdata) -> CURLcode; - pub fn Curl_http2_switched( - data: *mut Curl_easy, - ptr: *const libc::c_char, - nread: size_t, - ) -> CURLcode; - pub fn Curl_http2_setup_conn(conn: *mut connectdata); - pub fn Curl_http2_setup_req(data: *mut Curl_easy); - pub fn Curl_http2_done(data: *mut Curl_easy, premature: bool); - pub fn Curl_altsvc_parse( - data: *mut Curl_easy, - altsvc: *mut altsvcinfo, - value: *const libc::c_char, - srcalpn: alpnid, - srchost: *const libc::c_char, - srcport: libc::c_ushort, - ) -> CURLcode; - // http_digest.rs - pub fn Curl_auth_decode_digest_http_message( - chlg: *const libc::c_char, - digest: *mut digestdata, - ) -> CURLcode; - pub fn Curl_auth_create_digest_http_message( - data: *mut Curl_easy, - userp: *const libc::c_char, - passwdp: *const libc::c_char, - request: *const libc::c_uchar, - uri: *const libc::c_uchar, - digest: *mut digestdata, - outptr: *mut *mut libc::c_char, - outlen: *mut size_t, - ) -> CURLcode; - pub fn Curl_auth_digest_cleanup(digest: *mut digestdata); - - // http2.rs - pub fn curl_easy_duphandle(curl: *mut CURL) -> *mut CURL; - pub fn curl_url() -> *mut CURLU; - pub fn nghttp2_session_callbacks_new( - callbacks_ptr: *mut *mut nghttp2_session_callbacks, - ) -> libc::c_int; - pub fn nghttp2_session_callbacks_del(callbacks: *mut nghttp2_session_callbacks); - pub fn nghttp2_session_callbacks_set_send_callback( - cbs: *mut nghttp2_session_callbacks, - send_callback_0: nghttp2_send_callback, - ); - pub fn nghttp2_session_callbacks_set_on_frame_recv_callback( - cbs: *mut nghttp2_session_callbacks, - on_frame_recv_callback: nghttp2_on_frame_recv_callback, - ); - pub fn nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - cbs: *mut nghttp2_session_callbacks, - on_data_chunk_recv_callback: nghttp2_on_data_chunk_recv_callback, - ); - pub fn nghttp2_session_callbacks_set_on_stream_close_callback( - cbs: *mut nghttp2_session_callbacks, - on_stream_close_callback: nghttp2_on_stream_close_callback, - ); - pub fn nghttp2_session_callbacks_set_on_begin_headers_callback( - cbs: *mut nghttp2_session_callbacks, - on_begin_headers_callback: nghttp2_on_begin_headers_callback, - ); - pub fn nghttp2_session_callbacks_set_on_header_callback( - cbs: *mut nghttp2_session_callbacks, - on_header_callback: nghttp2_on_header_callback, - ); - pub fn nghttp2_session_callbacks_set_error_callback( - cbs: *mut nghttp2_session_callbacks, - error_callback_0: nghttp2_error_callback, - ); - pub fn nghttp2_session_client_new( - session_ptr: *mut *mut nghttp2_session, - callbacks: *const nghttp2_session_callbacks, - user_data: *mut libc::c_void, - ) -> libc::c_int; - pub fn nghttp2_session_del(session: *mut nghttp2_session); - pub fn nghttp2_session_send(session: *mut nghttp2_session) -> libc::c_int; - pub fn nghttp2_session_mem_recv( - session: *mut nghttp2_session, - in_0: *const uint8_t, - inlen: size_t, - ) -> ssize_t; - pub fn nghttp2_session_resume_data( - session: *mut nghttp2_session, - stream_id: int32_t, - ) -> libc::c_int; - pub fn nghttp2_session_want_read(session: *mut nghttp2_session) -> libc::c_int; - pub fn nghttp2_session_want_write(session: *mut nghttp2_session) -> libc::c_int; - pub fn nghttp2_session_get_stream_user_data( - session: *mut nghttp2_session, - stream_id: int32_t, - ) -> *mut libc::c_void; - pub fn nghttp2_session_set_stream_user_data( - session: *mut nghttp2_session, - stream_id: int32_t, - stream_user_data: *mut libc::c_void, - ) -> libc::c_int; - pub fn nghttp2_session_get_remote_settings( - session: *mut nghttp2_session, - id: nghttp2_settings_id, - ) -> uint32_t; - pub fn nghttp2_session_upgrade2( - session: *mut nghttp2_session, - settings_payload: *const uint8_t, - settings_payloadlen: size_t, - head_request: libc::c_int, - stream_user_data: *mut libc::c_void, - ) -> libc::c_int; - pub fn nghttp2_pack_settings_payload( - buf: *mut uint8_t, - buflen: size_t, - iv: *const nghttp2_settings_entry, - niv: size_t, - ) -> ssize_t; - pub fn nghttp2_strerror(lib_error_code: libc::c_int) -> *const libc::c_char; - pub fn nghttp2_http2_strerror(error_code: uint32_t) -> *const libc::c_char; - pub fn nghttp2_priority_spec_init( - pri_spec: *mut nghttp2_priority_spec, - stream_id: int32_t, - weight: int32_t, - exclusive: libc::c_int, - ); - pub fn nghttp2_submit_request( - session: *mut nghttp2_session, - pri_spec: *const nghttp2_priority_spec, - nva: *const nghttp2_nv, - nvlen: size_t, - data_prd: *const nghttp2_data_provider, - stream_user_data: *mut libc::c_void, - ) -> int32_t; - pub fn nghttp2_submit_priority( - session: *mut nghttp2_session, - flags: uint8_t, - stream_id: int32_t, - pri_spec: *const nghttp2_priority_spec, - ) -> libc::c_int; - pub fn nghttp2_submit_rst_stream( - session: *mut nghttp2_session, - flags: uint8_t, - stream_id: int32_t, - error_code: uint32_t, - ) -> libc::c_int; - pub fn nghttp2_submit_settings( - session: *mut nghttp2_session, - flags: uint8_t, - iv: *const nghttp2_settings_entry, - niv: size_t, - ) -> libc::c_int; - pub fn nghttp2_submit_ping( - session: *mut nghttp2_session, - flags: uint8_t, - opaque_data: *const uint8_t, - ) -> libc::c_int; - pub fn nghttp2_session_check_request_allowed(session: *mut nghttp2_session) -> libc::c_int; - pub fn nghttp2_session_set_local_window_size( - session: *mut nghttp2_session, - flags: uint8_t, - stream_id: int32_t, - window_size: int32_t, - ) -> libc::c_int; +use crate::src::ffi_alias::type_alias::*; +use crate::src::ffi_struct::struct_define::*; + +extern "C" { + // keylog.rs + pub fn curl_getenv(variable: *const libc::c_char) -> *mut libc::c_char; + pub fn fclose(__stream: *mut FILE) -> libc::c_int; + pub fn fopen(_: *const libc::c_char, _: *const libc::c_char) -> *mut FILE; + pub fn setvbuf( + __stream: *mut FILE, + __buf: *mut libc::c_char, + __modes: libc::c_int, + __n: size_t, + ) -> libc::c_int; + pub fn fputs(__s: *const libc::c_char, __stream: *mut FILE) -> libc::c_int; + pub fn memcpy( + _: *mut libc::c_void, + _: *const libc::c_void, + _: libc::c_ulong, + ) -> *mut libc::c_void; + pub fn strlen(_: *const libc::c_char) -> libc::c_ulong; + + // vtls.rs + pub fn memcmp(_: *const libc::c_void, _: *const libc::c_void, _: libc::c_ulong) -> libc::c_int; + pub fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int; + pub fn Curl_safe_strcasecompare( + first: *const libc::c_char, + second: *const libc::c_char, + ) -> libc::c_int; + + // ftp.rs + pub fn Curl_sec_read_msg( + data: *mut Curl_easy, + conn: *mut connectdata, + _: *mut libc::c_char, + _: protection_level, + ) -> libc::c_int; + pub fn Curl_sec_end(_: *mut connectdata); + pub fn Curl_sec_login(_: *mut Curl_easy, _: *mut connectdata) -> CURLcode; + pub fn Curl_sec_request_prot(conn: *mut connectdata, level: *const libc::c_char) + -> libc::c_int; + pub fn strcpy(_: *mut libc::c_char, _: *const libc::c_char) -> *mut libc::c_char; + pub fn strncpy( + _: *mut libc::c_char, + _: *const libc::c_char, + _: libc::c_ulong, + ) -> *mut libc::c_char; + pub fn strncmp(_: *const libc::c_char, _: *const libc::c_char, _: libc::c_ulong) + -> libc::c_int; + pub fn bind(__fd: libc::c_int, __addr: *const sockaddr, __len: socklen_t) -> libc::c_int; + pub fn getsockname( + __fd: libc::c_int, + __addr: *mut sockaddr, + __len: *mut socklen_t, + ) -> libc::c_int; + pub fn listen(__fd: libc::c_int, __n: libc::c_int) -> libc::c_int; + pub fn accept( + __fd: libc::c_int, + __addr: *mut sockaddr, + __addr_len: *mut socklen_t, + ) -> libc::c_int; + pub fn sscanf(_: *const libc::c_char, _: *const libc::c_char, _: ...) -> libc::c_int; + pub fn Curl_isdigit(c: libc::c_int) -> libc::c_int; + pub fn __errno_location() -> *mut libc::c_int; + pub fn strtol( + _: *const libc::c_char, + _: *mut *mut libc::c_char, + _: libc::c_int, + ) -> libc::c_long; + pub fn strtoul( + _: *const libc::c_char, + _: *mut *mut libc::c_char, + _: libc::c_int, + ) -> libc::c_ulong; + pub fn strchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char; + pub fn strrchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char; + pub fn strstr(_: *const libc::c_char, _: *const libc::c_char) -> *mut libc::c_char; + pub fn curl_easy_strerror(_: CURLcode) -> *const libc::c_char; + pub fn inet_pton( + __af: libc::c_int, + __cp: *const libc::c_char, + __buf: *mut libc::c_void, + ) -> libc::c_int; + pub fn inet_ntop( + __af: libc::c_int, + __cp: *const libc::c_void, + __buf: *mut libc::c_char, + __len: socklen_t, + ) -> *const libc::c_char; + pub fn Curl_now() -> curltime; + pub fn Curl_timediff(t1: curltime, t2: curltime) -> timediff_t; + pub fn Curl_llist_remove(_: *mut Curl_llist, _: *mut Curl_llist_element, _: *mut libc::c_void); + pub fn Curl_resolver_wait_resolv( + data: *mut Curl_easy, + dnsentry: *mut *mut Curl_dns_entry, + ) -> CURLcode; + pub fn Curl_resolv( + data: *mut Curl_easy, + hostname: *const libc::c_char, + port: libc::c_int, + allowDOH: bool, + dnsentry: *mut *mut Curl_dns_entry, + ) -> resolve_t; + pub fn Curl_resolv_unlock(data: *mut Curl_easy, dns: *mut Curl_dns_entry); + pub fn Curl_printable_address( + ip: *const Curl_addrinfo, + buf: *mut libc::c_char, + bufsize: size_t, + ); + pub fn Curl_pp_statemach( + data: *mut Curl_easy, + pp: *mut pingpong, + block: bool, + disconnecting: bool, + ) -> CURLcode; + pub fn Curl_pp_init(data: *mut Curl_easy, pp: *mut pingpong); + pub fn Curl_pp_setup(pp: *mut pingpong); + pub fn Curl_pp_state_timeout( + data: *mut Curl_easy, + pp: *mut pingpong, + disconnecting: bool, + ) -> timediff_t; + pub fn Curl_pp_sendf( + data: *mut Curl_easy, + pp: *mut pingpong, + fmt: *const libc::c_char, + _: ... + ) -> CURLcode; + pub fn Curl_pp_readresp( + data: *mut Curl_easy, + sockfd: curl_socket_t, + pp: *mut pingpong, + code: *mut libc::c_int, + size: *mut size_t, + ) -> CURLcode; + pub fn Curl_pp_flushsend(data: *mut Curl_easy, pp: *mut pingpong) -> CURLcode; + pub fn Curl_pp_disconnect(pp: *mut pingpong) -> CURLcode; + pub fn Curl_pp_getsock( + data: *mut Curl_easy, + pp: *mut pingpong, + socks: *mut curl_socket_t, + ) -> libc::c_int; + pub fn Curl_infof(_: *mut Curl_easy, fmt: *const libc::c_char, _: ...); + pub fn Curl_failf(_: *mut Curl_easy, fmt: *const libc::c_char, _: ...); + pub fn Curl_client_write( + data: *mut Curl_easy, + type_0: libc::c_int, + ptr: *mut libc::c_char, + len: size_t, + ) -> CURLcode; + pub fn Curl_ipv6_scope(sa: *const sockaddr) -> libc::c_uint; + pub fn Curl_if2ip( + af: libc::c_int, + remote_scope: libc::c_uint, + local_scope_id: libc::c_uint, + interf: *const libc::c_char, + buf: *mut libc::c_char, + buf_size: libc::c_int, + ) -> if2ip_result_t; + pub fn Curl_pgrsSetDownloadSize(data: *mut Curl_easy, size: curl_off_t); + pub fn Curl_pgrsSetUploadSize(data: *mut Curl_easy, size: curl_off_t); + pub fn Curl_pgrsSetDownloadCounter(data: *mut Curl_easy, size: curl_off_t); + pub fn Curl_pgrsSetUploadCounter(data: *mut Curl_easy, size: curl_off_t); + pub fn Curl_pgrsUpdate(data: *mut Curl_easy) -> libc::c_int; + pub fn Curl_pgrsTime(data: *mut Curl_easy, timer: timerid) -> curltime; + pub fn Curl_setup_transfer( + data: *mut Curl_easy, + sockindex: libc::c_int, + size: curl_off_t, + getheader: bool, + writesockindex: libc::c_int, + ); + pub fn Curl_urldecode( + data: *mut Curl_easy, + string: *const libc::c_char, + length: size_t, + ostring: *mut *mut libc::c_char, + olen: *mut size_t, + ctrl: urlreject, + ) -> CURLcode; + // definitions in ftplistparser.rs + pub fn Curl_ftp_parselist( + buffer: *mut libc::c_char, + size: size_t, + nmemb: size_t, + connptr: *mut libc::c_void, + ) -> size_t; + pub fn Curl_ftp_parselist_geterror(pl_data: *mut ftp_parselist_data) -> CURLcode; + pub fn Curl_ftp_parselist_data_alloc() -> *mut ftp_parselist_data; + pub fn Curl_ftp_parselist_data_free(pl_data: *mut *mut ftp_parselist_data); + pub fn Curl_range(data: *mut Curl_easy) -> CURLcode; + pub fn curlx_strtoofft( + str: *const libc::c_char, + endp: *mut *mut libc::c_char, + base: libc::c_int, + num: *mut curl_off_t, + ) -> CURLofft; + pub fn Curl_strcasecompare( + first: *const libc::c_char, + second: *const libc::c_char, + ) -> libc::c_int; + pub fn Curl_raw_toupper(in_0: libc::c_char) -> libc::c_char; + pub fn Curl_is_connected( + data: *mut Curl_easy, + conn: *mut connectdata, + sockindex: libc::c_int, + connected: *mut bool, + ) -> CURLcode; + pub fn Curl_connecthost( + data: *mut Curl_easy, + conn: *mut connectdata, + host: *const Curl_dns_entry, + ) -> CURLcode; + pub fn Curl_timeleft( + data: *mut Curl_easy, + nowp: *mut curltime, + duringconnect: bool, + ) -> timediff_t; + pub fn Curl_socket( + data: *mut Curl_easy, + ai: *const Curl_addrinfo, + addr: *mut Curl_sockaddr_ex, + sockfd: *mut curl_socket_t, + ) -> CURLcode; + pub fn curlx_nonblock(sockfd: curl_socket_t, nonblock: libc::c_int) -> libc::c_int; + pub fn Curl_conninfo_remote( + data: *mut Curl_easy, + conn: *mut connectdata, + sockfd: curl_socket_t, + ); + pub fn Curl_closesocket( + data: *mut Curl_easy, + conn: *mut connectdata, + sock: curl_socket_t, + ) -> libc::c_int; + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + pub fn Curl_conncontrol(conn: *mut connectdata, closeit: libc::c_int); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + pub fn Curl_conncontrol( + conn: *mut connectdata, + closeit: libc::c_int, + reason: *const libc::c_char, + ); + pub fn Curl_conn_data_pending(conn: *mut connectdata, sockindex: libc::c_int) -> bool; + pub fn Curl_strerror( + err: libc::c_int, + buf: *mut libc::c_char, + buflen: size_t, + ) -> *const libc::c_char; + pub fn Curl_socket_check( + readfd: curl_socket_t, + readfd2: curl_socket_t, + writefd: curl_socket_t, + timeout_ms: timediff_t, + ) -> libc::c_int; + pub fn Curl_gmtime(intime: time_t, store: *mut tm) -> CURLcode; + pub fn Curl_getdate_capped(p: *const libc::c_char) -> time_t; + pub fn Curl_expire(data: *mut Curl_easy, milli: timediff_t, _: expire_id); + pub fn Curl_set_in_callback(data: *mut Curl_easy, value: bool); + pub fn curlx_ultous(ulnum: libc::c_ulong) -> libc::c_ushort; + pub fn curlx_sltosi(slnum: libc::c_long) -> libc::c_int; + pub fn curlx_sotouz(sonum: curl_off_t) -> size_t; + pub fn Curl_proxyCONNECT( + data: *mut Curl_easy, + tunnelsocket: libc::c_int, + hostname: *const libc::c_char, + remote_port: libc::c_int, + ) -> CURLcode; + pub fn Curl_proxy_connect(data: *mut Curl_easy, sockindex: libc::c_int) -> CURLcode; + pub fn Curl_connect_ongoing(conn: *mut connectdata) -> bool; + pub fn Curl_SOCKS_getsock( + conn: *mut connectdata, + sock: *mut curl_socket_t, + sockindex: libc::c_int, + ) -> libc::c_int; + pub fn curl_msnprintf( + buffer: *mut libc::c_char, + maxlength: size_t, + format: *const libc::c_char, + _: ... + ) -> libc::c_int; + pub fn curl_maprintf(format: *const libc::c_char, _: ...) -> *mut libc::c_char; + pub fn Curl_isalnum(c: libc::c_int) -> libc::c_int; + pub fn Curl_isspace(c: libc::c_int) -> libc::c_int; + pub fn Curl_llist_insert_next( + _: *mut Curl_llist, + _: *mut Curl_llist_element, + _: *const libc::c_void, + node: *mut Curl_llist_element, + ); + pub fn Curl_fileinfo_alloc() -> *mut fileinfo; + pub fn Curl_fileinfo_cleanup(finfo: *mut fileinfo); + pub fn Curl_fnmatch( + ptr: *mut libc::c_void, + pattern: *const libc::c_char, + string: *const libc::c_char, + ) -> libc::c_int; + // http_aws_sigv4.rs + pub fn time(__timer: *mut time_t) -> time_t; + pub fn strftime( + __s: *mut libc::c_char, + __maxsize: size_t, + __format: *const libc::c_char, + __tp: *const tm, + ) -> size_t; + pub fn Curl_http_method( + data: *mut Curl_easy, + conn: *mut connectdata, + method: *mut *const libc::c_char, + _: *mut Curl_HttpReq, + ); + pub fn Curl_strntoupper(dest: *mut libc::c_char, src: *const libc::c_char, n: size_t); + pub fn Curl_strntolower(dest: *mut libc::c_char, src: *const libc::c_char, n: size_t); + pub fn Curl_memdup(src: *const libc::c_void, buffer_length: size_t) -> *mut libc::c_void; + pub fn Curl_sha256it(outbuffer: *mut libc::c_uchar, input: *const libc::c_uchar, len: size_t); + pub fn Curl_hmacit( + hashparams: *const HMAC_params, + key: *const libc::c_uchar, + keylen: size_t, + data: *const libc::c_uchar, + datalen: size_t, + output: *mut libc::c_uchar, + ) -> CURLcode; + pub fn Curl_checkheaders( + data: *const Curl_easy, + thisheader: *const libc::c_char, + ) -> *mut libc::c_char; + // http_proxy.rs + pub fn curl_strnequal( + s1: *const libc::c_char, + s2: *const libc::c_char, + n: size_t, + ) -> libc::c_int; + pub fn Curl_httpchunk_init(data: *mut Curl_easy); + pub fn Curl_httpchunk_read( + data: *mut Curl_easy, + datap: *mut libc::c_char, + length: ssize_t, + wrote: *mut ssize_t, + passthru: *mut CURLcode, + ) -> CHUNKcode; + pub fn Curl_dyn_init(s: *mut dynbuf, toobig: size_t); + pub fn Curl_dyn_free(s: *mut dynbuf); + pub fn Curl_dyn_addn(s: *mut dynbuf, mem: *const libc::c_void, len: size_t) -> CURLcode; + pub fn Curl_dyn_add(s: *mut dynbuf, str: *const libc::c_char) -> CURLcode; + pub fn Curl_dyn_addf(s: *mut dynbuf, fmt: *const libc::c_char, _: ...) -> CURLcode; + pub fn Curl_dyn_reset(s: *mut dynbuf); + pub fn Curl_dyn_ptr(s: *const dynbuf) -> *mut libc::c_char; + pub fn Curl_dyn_len(s: *const dynbuf) -> size_t; + pub fn Curl_compareheader( + headerline: *const libc::c_char, + header: *const libc::c_char, + content: *const libc::c_char, + ) -> bool; + pub fn Curl_copy_header_value(header: *const libc::c_char) -> *mut libc::c_char; + pub fn Curl_checkProxyheaders( + data: *mut Curl_easy, + conn: *const connectdata, + thisheader: *const libc::c_char, + ) -> *mut libc::c_char; + pub fn Curl_buffer_send( + in_0: *mut dynbuf, + data: *mut Curl_easy, + bytes_written: *mut curl_off_t, + included_body_bytes: curl_off_t, + socketindex: libc::c_int, + ) -> CURLcode; + pub fn Curl_http_input_auth( + data: *mut Curl_easy, + proxy: bool, + auth: *const libc::c_char, + ) -> CURLcode; + pub fn Curl_http_auth_act(data: *mut Curl_easy) -> CURLcode; + pub fn Curl_http_output_auth( + data: *mut Curl_easy, + conn: *mut connectdata, + request: *const libc::c_char, + httpreq: Curl_HttpReq, + path: *const libc::c_char, + proxytunnel: bool, + ) -> CURLcode; + pub fn Curl_read( + data: *mut Curl_easy, + sockfd: curl_socket_t, + buf: *mut libc::c_char, + buffersize: size_t, + n: *mut ssize_t, + ) -> CURLcode; + pub fn Curl_write( + data: *mut Curl_easy, + sockfd: curl_socket_t, + mem: *const libc::c_void, + len: size_t, + written: *mut ssize_t, + ) -> CURLcode; + pub fn Curl_debug( + data: *mut Curl_easy, + type_0: curl_infotype, + ptr: *mut libc::c_char, + size: size_t, + ) -> libc::c_int; + pub fn Curl_fillreadbuffer( + data: *mut Curl_easy, + bytes: size_t, + nreadp: *mut size_t, + ) -> CURLcode; + pub fn Curl_get_upload_buffer(data: *mut Curl_easy) -> CURLcode; + pub fn Curl_isxdigit(c: libc::c_int) -> libc::c_int; + pub fn Curl_unencode_write( + data: *mut Curl_easy, + writer: *mut contenc_writer, + buf: *const libc::c_char, + nbytes: size_t, + ) -> CURLcode; + + // http.rs + pub fn curl_url_cleanup(handle: *mut CURLU); + pub fn curl_url_dup(in_0: *mut CURLU) -> *mut CURLU; + pub fn curl_url_get( + handle: *mut CURLU, + what: CURLUPart, + part: *mut *mut libc::c_char, + flags: libc::c_uint, + ) -> CURLUcode; + pub fn curl_url_set( + handle: *mut CURLU, + what: CURLUPart, + part: *const libc::c_char, + flags: libc::c_uint, + ) -> CURLUcode; + pub fn memmove( + _: *mut libc::c_void, + _: *const libc::c_void, + _: libc::c_ulong, + ) -> *mut libc::c_void; + pub fn memchr(_: *const libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void; + pub fn curl_mime_headers( + part: *mut curl_mimepart, + headers: *mut curl_slist, + take_ownership: libc::c_int, + ) -> CURLcode; + pub fn Curl_mime_initpart(part: *mut curl_mimepart, easy: *mut Curl_easy); + pub fn Curl_mime_cleanpart(part: *mut curl_mimepart); + pub fn Curl_mime_prepare_headers( + part: *mut curl_mimepart, + contenttype: *const libc::c_char, + disposition: *const libc::c_char, + strategy: mimestrategy, + ) -> CURLcode; + pub fn Curl_mime_size(part: *mut curl_mimepart) -> curl_off_t; + pub fn Curl_mime_read( + buffer: *mut libc::c_char, + size: size_t, + nitems: size_t, + instream: *mut libc::c_void, + ) -> size_t; + pub fn Curl_mime_rewind(part: *mut curl_mimepart) -> CURLcode; + pub fn Curl_cookie_freelist(cookies: *mut Cookie); + pub fn Curl_cookie_getlist( + c: *mut CookieInfo, + host: *const libc::c_char, + path: *const libc::c_char, + secure: bool, + ) -> *mut Cookie; + pub fn Curl_cookie_add( + data: *mut Curl_easy, + c: *mut CookieInfo, + header: bool, + noexpiry: bool, + lineptr: *mut libc::c_char, + domain: *const libc::c_char, + path: *const libc::c_char, + secure: bool, + ) -> *mut Cookie; + pub fn Curl_getformdata( + data: *mut Curl_easy, + _: *mut curl_mimepart, + post: *mut curl_httppost, + fread_func: curl_read_callback, + ) -> CURLcode; + pub fn Curl_rtsp_parseheader(data: *mut Curl_easy, header: *mut libc::c_char) -> CURLcode; + pub fn Curl_readrewind(data: *mut Curl_easy) -> CURLcode; + pub fn Curl_meets_timecondition(data: *mut Curl_easy, timeofdoc: time_t) -> bool; + pub fn Curl_done_sending(data: *mut Curl_easy, k: *mut SingleRequest) -> CURLcode; + pub fn Curl_base64_encode( + data: *mut Curl_easy, + inputbuff: *const libc::c_char, + insize: size_t, + outptr: *mut *mut libc::c_char, + outlen: *mut size_t, + ) -> CURLcode; + pub fn Curl_auth_is_digest_supported() -> bool; + pub fn Curl_input_digest( + data: *mut Curl_easy, + proxy: bool, + header: *const libc::c_char, + ) -> CURLcode; + pub fn Curl_output_digest( + data: *mut Curl_easy, + proxy: bool, + request: *const libc::c_uchar, + uripath: *const libc::c_uchar, + ) -> CURLcode; + pub fn Curl_output_aws_sigv4(data: *mut Curl_easy, proxy: bool) -> CURLcode; + pub fn Curl_share_lock(_: *mut Curl_easy, _: curl_lock_data, _: curl_lock_access) + -> CURLSHcode; + pub fn Curl_share_unlock(_: *mut Curl_easy, _: curl_lock_data) -> CURLSHcode; + pub fn Curl_expire_done(data: *mut Curl_easy, id: expire_id); + pub fn Curl_strncasecompare( + first: *const libc::c_char, + second: *const libc::c_char, + max: size_t, + ) -> libc::c_int; + pub fn Curl_build_unencoding_stack( + data: *mut Curl_easy, + enclist: *const libc::c_char, + maybechunked: libc::c_int, + ) -> CURLcode; + pub fn Curl_unencode_cleanup(data: *mut Curl_easy); + pub fn curlx_uitous(uinum: libc::c_uint) -> libc::c_ushort; + pub fn Curl_http2_request_upgrade(req: *mut dynbuf, data: *mut Curl_easy) -> CURLcode; + pub fn Curl_http2_setup(data: *mut Curl_easy, conn: *mut connectdata) -> CURLcode; + pub fn Curl_http2_switched( + data: *mut Curl_easy, + ptr: *const libc::c_char, + nread: size_t, + ) -> CURLcode; + pub fn Curl_http2_setup_conn(conn: *mut connectdata); + pub fn Curl_http2_setup_req(data: *mut Curl_easy); + pub fn Curl_http2_done(data: *mut Curl_easy, premature: bool); + pub fn Curl_altsvc_parse( + data: *mut Curl_easy, + altsvc: *mut altsvcinfo, + value: *const libc::c_char, + srcalpn: alpnid, + srchost: *const libc::c_char, + srcport: libc::c_ushort, + ) -> CURLcode; + // http_digest.rs + pub fn Curl_auth_decode_digest_http_message( + chlg: *const libc::c_char, + digest: *mut digestdata, + ) -> CURLcode; + pub fn Curl_auth_create_digest_http_message( + data: *mut Curl_easy, + userp: *const libc::c_char, + passwdp: *const libc::c_char, + request: *const libc::c_uchar, + uri: *const libc::c_uchar, + digest: *mut digestdata, + outptr: *mut *mut libc::c_char, + outlen: *mut size_t, + ) -> CURLcode; + pub fn Curl_auth_digest_cleanup(digest: *mut digestdata); + + // http2.rs + pub fn curl_easy_duphandle(curl: *mut CURL) -> *mut CURL; + pub fn curl_url() -> *mut CURLU; + pub fn nghttp2_session_callbacks_new( + callbacks_ptr: *mut *mut nghttp2_session_callbacks, + ) -> libc::c_int; + pub fn nghttp2_session_callbacks_del(callbacks: *mut nghttp2_session_callbacks); + pub fn nghttp2_session_callbacks_set_send_callback( + cbs: *mut nghttp2_session_callbacks, + send_callback_0: nghttp2_send_callback, + ); + pub fn nghttp2_session_callbacks_set_on_frame_recv_callback( + cbs: *mut nghttp2_session_callbacks, + on_frame_recv_callback: nghttp2_on_frame_recv_callback, + ); + pub fn nghttp2_session_callbacks_set_on_data_chunk_recv_callback( + cbs: *mut nghttp2_session_callbacks, + on_data_chunk_recv_callback: nghttp2_on_data_chunk_recv_callback, + ); + pub fn nghttp2_session_callbacks_set_on_stream_close_callback( + cbs: *mut nghttp2_session_callbacks, + on_stream_close_callback: nghttp2_on_stream_close_callback, + ); + pub fn nghttp2_session_callbacks_set_on_begin_headers_callback( + cbs: *mut nghttp2_session_callbacks, + on_begin_headers_callback: nghttp2_on_begin_headers_callback, + ); + pub fn nghttp2_session_callbacks_set_on_header_callback( + cbs: *mut nghttp2_session_callbacks, + on_header_callback: nghttp2_on_header_callback, + ); + pub fn nghttp2_session_callbacks_set_error_callback( + cbs: *mut nghttp2_session_callbacks, + error_callback_0: nghttp2_error_callback, + ); + pub fn nghttp2_session_client_new( + session_ptr: *mut *mut nghttp2_session, + callbacks: *const nghttp2_session_callbacks, + user_data: *mut libc::c_void, + ) -> libc::c_int; + pub fn nghttp2_session_del(session: *mut nghttp2_session); + pub fn nghttp2_session_send(session: *mut nghttp2_session) -> libc::c_int; + pub fn nghttp2_session_mem_recv( + session: *mut nghttp2_session, + in_0: *const uint8_t, + inlen: size_t, + ) -> ssize_t; + pub fn nghttp2_session_resume_data( + session: *mut nghttp2_session, + stream_id: int32_t, + ) -> libc::c_int; + pub fn nghttp2_session_want_read(session: *mut nghttp2_session) -> libc::c_int; + pub fn nghttp2_session_want_write(session: *mut nghttp2_session) -> libc::c_int; + pub fn nghttp2_session_get_stream_user_data( + session: *mut nghttp2_session, + stream_id: int32_t, + ) -> *mut libc::c_void; + pub fn nghttp2_session_set_stream_user_data( + session: *mut nghttp2_session, + stream_id: int32_t, + stream_user_data: *mut libc::c_void, + ) -> libc::c_int; + pub fn nghttp2_session_get_remote_settings( + session: *mut nghttp2_session, + id: nghttp2_settings_id, + ) -> uint32_t; + pub fn nghttp2_session_upgrade2( + session: *mut nghttp2_session, + settings_payload: *const uint8_t, + settings_payloadlen: size_t, + head_request: libc::c_int, + stream_user_data: *mut libc::c_void, + ) -> libc::c_int; + pub fn nghttp2_pack_settings_payload( + buf: *mut uint8_t, + buflen: size_t, + iv: *const nghttp2_settings_entry, + niv: size_t, + ) -> ssize_t; + pub fn nghttp2_strerror(lib_error_code: libc::c_int) -> *const libc::c_char; + pub fn nghttp2_http2_strerror(error_code: uint32_t) -> *const libc::c_char; + pub fn nghttp2_priority_spec_init( + pri_spec: *mut nghttp2_priority_spec, + stream_id: int32_t, + weight: int32_t, + exclusive: libc::c_int, + ); + pub fn nghttp2_submit_request( + session: *mut nghttp2_session, + pri_spec: *const nghttp2_priority_spec, + nva: *const nghttp2_nv, + nvlen: size_t, + data_prd: *const nghttp2_data_provider, + stream_user_data: *mut libc::c_void, + ) -> int32_t; + pub fn nghttp2_submit_priority( + session: *mut nghttp2_session, + flags: uint8_t, + stream_id: int32_t, + pri_spec: *const nghttp2_priority_spec, + ) -> libc::c_int; + pub fn nghttp2_submit_rst_stream( + session: *mut nghttp2_session, + flags: uint8_t, + stream_id: int32_t, + error_code: uint32_t, + ) -> libc::c_int; + pub fn nghttp2_submit_settings( + session: *mut nghttp2_session, + flags: uint8_t, + iv: *const nghttp2_settings_entry, + niv: size_t, + ) -> libc::c_int; + pub fn nghttp2_submit_ping( + session: *mut nghttp2_session, + flags: uint8_t, + opaque_data: *const uint8_t, + ) -> libc::c_int; + pub fn nghttp2_session_check_request_allowed(session: *mut nghttp2_session) -> libc::c_int; + pub fn nghttp2_session_set_local_window_size( + session: *mut nghttp2_session, + flags: uint8_t, + stream_id: int32_t, + window_size: int32_t, + ) -> libc::c_int; pub fn nghttp2_session_get_stream_local_window_size( session: *mut nghttp2_session, stream_id: int32_t, ) -> int32_t; - pub fn nghttp2_is_fatal(lib_error_code: libc::c_int) -> libc::c_int; - pub fn nghttp2_version(least_version: libc::c_int) -> *mut nghttp2_info; - pub fn Curl_http(data: *mut Curl_easy, done: *mut bool) -> CURLcode; - pub fn Curl_http_done(data: *mut Curl_easy, _: CURLcode, premature: bool) -> CURLcode; - pub fn Curl_base64url_encode( - data: *mut Curl_easy, - inputbuff: *const libc::c_char, - insize: size_t, - outptr: *mut *mut libc::c_char, - outlen: *mut size_t, - ) -> CURLcode; - pub fn Curl_multi_add_perform( - multi: *mut Curl_multi, - data: *mut Curl_easy, - conn: *mut connectdata, - ) -> CURLMcode; - pub fn Curl_multi_max_concurrent_streams(multi: *mut Curl_multi) -> libc::c_uint; - pub fn Curl_close(datap: *mut *mut Curl_easy) -> CURLcode; - pub fn Curl_connalive(conn: *mut connectdata) -> bool; - pub fn Curl_saferealloc(ptr: *mut libc::c_void, size: size_t) -> *mut libc::c_void; - - // mbedtls ftp - - pub fn Curl_ssl_connect( - data: *mut Curl_easy, - conn: *mut connectdata, - sockindex: libc::c_int, - ) -> CURLcode; - pub fn Curl_ssl_close(data: *mut Curl_easy, conn: *mut connectdata, sockindex: libc::c_int); - pub fn Curl_ssl_shutdown( - data: *mut Curl_easy, - conn: *mut connectdata, - sockindex: libc::c_int, - ) -> CURLcode; - - // http_ntlm.rs - pub fn curl_free(p: *mut libc::c_void); - pub fn Curl_http_auth_cleanup_ntlm_wb(conn: *mut connectdata); - pub fn Curl_base64_decode( - src: *const libc::c_char, - outptr: *mut *mut libc::c_uchar, - outlen: *mut size_t, - ) -> CURLcode; - pub fn Curl_bufref_init(br: *mut bufref); - pub fn Curl_bufref_set( - br: *mut bufref, - ptr: *const libc::c_void, - len: size_t, - dtor: Option ()>, - ); - pub fn Curl_bufref_ptr(br: *const bufref) -> *const libc::c_uchar; - pub fn Curl_bufref_len(br: *const bufref) -> size_t; - pub fn Curl_bufref_free(br: *mut bufref); - #[cfg(USE_NTLM)] - pub fn Curl_auth_create_ntlm_type1_message( - data: *mut Curl_easy, - userp: *const libc::c_char, - passwdp: *const libc::c_char, - service: *const libc::c_char, - host: *const libc::c_char, - ntlm: *mut ntlmdata, - out: *mut bufref, - ) -> CURLcode; - #[cfg(USE_NTLM)] - pub fn Curl_auth_decode_ntlm_type2_message( - data: *mut Curl_easy, - type2: *const bufref, - ntlm: *mut ntlmdata, - ) -> CURLcode; - #[cfg(USE_NTLM)] - pub fn Curl_auth_create_ntlm_type3_message( - data: *mut Curl_easy, - userp: *const libc::c_char, - passwdp: *const libc::c_char, - ntlm: *mut ntlmdata, - out: *mut bufref, - ) -> CURLcode; - #[cfg(USE_NTLM)] - pub fn Curl_auth_cleanup_ntlm(ntlm: *mut ntlmdata); - - // new http_proxy.rs - pub fn Curl_ssl_connect_nonblocking( - data: *mut Curl_easy, - conn: *mut connectdata, - isproxy: bool, - sockindex: libc::c_int, - done: *mut bool, - ) -> CURLcode; - - // http.rs - pub fn Curl_auth_is_ntlm_supported() -> bool; - pub fn Curl_input_ntlm( - data: *mut Curl_easy, - proxy: bool, - header: *const libc::c_char, - ) -> CURLcode; - pub fn Curl_output_ntlm(data: *mut Curl_easy, proxy: bool) -> CURLcode; - pub fn Curl_input_ntlm_wb( - data: *mut Curl_easy, - conn: *mut connectdata, - proxy: bool, - header: *const libc::c_char, - ) -> CURLcode; - pub fn Curl_output_ntlm_wb( - data: *mut Curl_easy, - conn: *mut connectdata, - proxy: bool, - ) -> CURLcode; - pub fn Curl_hsts_parse( - h: *mut hsts, - hostname: *const libc::c_char, - sts: *const libc::c_char, - ) -> CURLcode; - pub fn Curl_auth_is_spnego_supported() -> bool; - pub fn Curl_input_negotiate( - data: *mut Curl_easy, - conn: *mut connectdata, - proxy: bool, - header: *const libc::c_char, - ) -> CURLcode; - pub fn Curl_output_negotiate( - data: *mut Curl_easy, - conn: *mut connectdata, - proxy: bool, - ) -> CURLcode; - - // mbedtls vtls.rs - pub fn fread( - _: *mut libc::c_void, - _: libc::c_ulong, - _: libc::c_ulong, - _: *mut FILE, - ) -> libc::c_ulong; - pub fn fseek(__stream: *mut FILE, __off: libc::c_long, __whence: libc::c_int) -> libc::c_int; - pub fn ftell(__stream: *mut FILE) -> libc::c_long; - - pub fn curl_slist_free_all(_: *mut curl_slist); - pub fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void; - - pub fn Curl_slist_append_nodup( - list: *mut curl_slist, - data: *mut libc::c_char, - ) -> *mut curl_slist; - pub fn Curl_recv_plain( - data: *mut Curl_easy, - num: libc::c_int, - buf: *mut libc::c_char, - len: size_t, - code: *mut CURLcode, - ) -> ssize_t; - pub fn Curl_send_plain( - data: *mut Curl_easy, - num: libc::c_int, - mem: *const libc::c_void, - len: size_t, - code: *mut CURLcode, - ) -> ssize_t; - - // mbedtls_threadlock.rs - pub fn pthread_mutex_init( - __mutex: *mut pthread_mutex_t, - __mutexattr: *const pthread_mutexattr_t, - ) -> libc::c_int; - pub fn pthread_mutex_destroy(__mutex: *mut pthread_mutex_t) -> libc::c_int; - pub fn pthread_mutex_lock(__mutex: *mut pthread_mutex_t) -> libc::c_int; - pub fn pthread_mutex_unlock(__mutex: *mut pthread_mutex_t) -> libc::c_int; - - // mbedtls.rs - pub fn mbedtls_version_get_number() -> libc::c_uint; - pub fn mbedtls_net_send( - ctx: *mut libc::c_void, - buf: *const libc::c_uchar, - len: size_t, - ) -> libc::c_int; - pub fn mbedtls_net_recv( - ctx: *mut libc::c_void, - buf: *mut libc::c_uchar, - len: size_t, - ) -> libc::c_int; - pub fn mbedtls_ssl_session_free(session: *mut mbedtls_ssl_session); - pub fn mbedtls_ssl_session_init(session: *mut mbedtls_ssl_session); - pub fn mbedtls_ssl_config_free(conf: *mut mbedtls_ssl_config); - pub fn mbedtls_ssl_config_defaults( - conf: *mut mbedtls_ssl_config, - endpoint: libc::c_int, - transport: libc::c_int, - preset: libc::c_int, - ) -> libc::c_int; - pub fn mbedtls_ssl_config_init(conf: *mut mbedtls_ssl_config); - pub fn mbedtls_ssl_free(ssl: *mut mbedtls_ssl_context); - pub fn mbedtls_ssl_write( - ssl: *mut mbedtls_ssl_context, - buf: *const libc::c_uchar, - len: size_t, - ) -> libc::c_int; - pub fn mbedtls_ssl_read( - ssl: *mut mbedtls_ssl_context, - buf: *mut libc::c_uchar, - len: size_t, - ) -> libc::c_int; - pub fn mbedtls_ssl_handshake(ssl: *mut mbedtls_ssl_context) -> libc::c_int; - pub fn mbedtls_ssl_get_session( - ssl: *const mbedtls_ssl_context, - session: *mut mbedtls_ssl_session, - ) -> libc::c_int; - pub fn mbedtls_ssl_get_peer_cert(ssl: *const mbedtls_ssl_context) -> *const mbedtls_x509_crt; - pub fn mbedtls_ssl_get_ciphersuite(ssl: *const mbedtls_ssl_context) -> *const libc::c_char; - pub fn mbedtls_ssl_get_verify_result(ssl: *const mbedtls_ssl_context) -> uint32_t; - pub fn mbedtls_ssl_get_bytes_avail(ssl: *const mbedtls_ssl_context) -> size_t; - pub fn mbedtls_ssl_conf_renegotiation( - conf: *mut mbedtls_ssl_config, - renegotiation: libc::c_int, - ); - pub fn mbedtls_ssl_conf_session_tickets( - conf: *mut mbedtls_ssl_config, - use_tickets: libc::c_int, - ); - pub fn mbedtls_ssl_conf_min_version( - conf: *mut mbedtls_ssl_config, - major: libc::c_int, - minor: libc::c_int, - ); - pub fn mbedtls_ssl_conf_max_version( - conf: *mut mbedtls_ssl_config, - major: libc::c_int, - minor: libc::c_int, - ); - pub fn mbedtls_ssl_get_alpn_protocol(ssl: *const mbedtls_ssl_context) -> *const libc::c_char; - pub fn mbedtls_ssl_conf_alpn_protocols( - conf: *mut mbedtls_ssl_config, - protos: *mut *const libc::c_char, - ) -> libc::c_int; - pub fn mbedtls_ssl_set_hostname( - ssl: *mut mbedtls_ssl_context, - hostname: *const libc::c_char, - ) -> libc::c_int; - pub fn mbedtls_ssl_conf_own_cert( - conf: *mut mbedtls_ssl_config, - own_cert: *mut mbedtls_x509_crt, - pk_key: *mut mbedtls_pk_context, - ) -> libc::c_int; - pub fn mbedtls_ssl_conf_ca_chain( - conf: *mut mbedtls_ssl_config, - ca_chain: *mut mbedtls_x509_crt, - ca_crl: *mut mbedtls_x509_crl, - ); - pub fn mbedtls_ssl_conf_cert_profile( - conf: *mut mbedtls_ssl_config, - profile: *const mbedtls_x509_crt_profile, - ); - pub fn mbedtls_ssl_conf_ciphersuites( - conf: *mut mbedtls_ssl_config, - ciphersuites: *const libc::c_int, - ); - pub fn mbedtls_ssl_set_session( - ssl: *mut mbedtls_ssl_context, - session: *const mbedtls_ssl_session, - ) -> libc::c_int; - pub fn mbedtls_ssl_set_bio( - ssl: *mut mbedtls_ssl_context, - p_bio: *mut libc::c_void, - f_send: Option, - f_recv: Option, - f_recv_timeout: Option, - ); - pub fn mbedtls_ssl_conf_rng( - conf: *mut mbedtls_ssl_config, - f_rng: Option< - unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_uchar, size_t) -> libc::c_int, - >, - p_rng: *mut libc::c_void, - ); - pub fn mbedtls_ssl_conf_authmode(conf: *mut mbedtls_ssl_config, authmode: libc::c_int); - pub fn mbedtls_ssl_setup( - ssl: *mut mbedtls_ssl_context, - conf: *const mbedtls_ssl_config, - ) -> libc::c_int; - pub fn mbedtls_ssl_init(ssl: *mut mbedtls_ssl_context); - pub fn mbedtls_pk_init(ctx: *mut mbedtls_pk_context); - pub fn mbedtls_pk_free(ctx: *mut mbedtls_pk_context); - pub fn mbedtls_pk_can_do( - ctx: *const mbedtls_pk_context, - type_0: mbedtls_pk_type_t, - ) -> libc::c_int; - pub fn mbedtls_pk_parse_key( - ctx: *mut mbedtls_pk_context, - key: *const libc::c_uchar, - keylen: size_t, - pwd: *const libc::c_uchar, - pwdlen: size_t, - ) -> libc::c_int; - pub fn mbedtls_pk_parse_keyfile( - ctx: *mut mbedtls_pk_context, - path: *const libc::c_char, - password: *const libc::c_char, - ) -> libc::c_int; - pub fn mbedtls_pk_write_pubkey_der( - ctx: *mut mbedtls_pk_context, - buf: *mut libc::c_uchar, - size: size_t, - ) -> libc::c_int; - pub fn mbedtls_ssl_list_ciphersuites() -> *const libc::c_int; - pub fn mbedtls_x509_crl_parse_file( - chain: *mut mbedtls_x509_crl, - path: *const libc::c_char, - ) -> libc::c_int; - pub fn mbedtls_x509_crl_init(crl: *mut mbedtls_x509_crl); - pub fn mbedtls_x509_crl_free(crl: *mut mbedtls_x509_crl); - pub fn mbedtls_x509_crt_parse_der( - chain: *mut mbedtls_x509_crt, - buf: *const libc::c_uchar, - buflen: size_t, - ) -> libc::c_int; - pub fn mbedtls_x509_crt_parse( - chain: *mut mbedtls_x509_crt, - buf: *const libc::c_uchar, - buflen: size_t, - ) -> libc::c_int; - pub fn mbedtls_x509_crt_parse_file( - chain: *mut mbedtls_x509_crt, - path: *const libc::c_char, - ) -> libc::c_int; - pub fn mbedtls_x509_crt_parse_path( - chain: *mut mbedtls_x509_crt, - path: *const libc::c_char, - ) -> libc::c_int; - pub fn mbedtls_x509_crt_info( - buf: *mut libc::c_char, - size: size_t, - prefix: *const libc::c_char, - crt: *const mbedtls_x509_crt, - ) -> libc::c_int; - pub fn mbedtls_x509_crt_init(crt: *mut mbedtls_x509_crt); - pub fn mbedtls_x509_crt_free(crt: *mut mbedtls_x509_crt); - pub fn mbedtls_strerror(errnum: libc::c_int, buffer: *mut libc::c_char, buflen: size_t); - pub fn mbedtls_entropy_init(ctx: *mut mbedtls_entropy_context); - pub fn mbedtls_entropy_free(ctx: *mut mbedtls_entropy_context); - pub fn mbedtls_entropy_func( - data: *mut libc::c_void, - output: *mut libc::c_uchar, - len: size_t, - ) -> libc::c_int; - pub fn mbedtls_ctr_drbg_init(ctx: *mut mbedtls_ctr_drbg_context); - pub fn mbedtls_ctr_drbg_seed( - ctx: *mut mbedtls_ctr_drbg_context, - f_entropy: Option< - unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_uchar, size_t) -> libc::c_int, - >, - p_entropy: *mut libc::c_void, - custom: *const libc::c_uchar, - len: size_t, - ) -> libc::c_int; - pub fn mbedtls_ctr_drbg_free(ctx: *mut mbedtls_ctr_drbg_context); - pub fn mbedtls_ctr_drbg_random( - p_rng: *mut libc::c_void, - output: *mut libc::c_uchar, - output_len: size_t, - ) -> libc::c_int; - pub fn mbedtls_sha256_ret( - input: *const libc::c_uchar, - ilen: size_t, - output: *mut libc::c_uchar, - is224: libc::c_int, - ) -> libc::c_int; - pub fn Curl_multiuse_state(data: *mut Curl_easy, bundlestate: libc::c_int); - pub fn Curl_mbedtlsthreadlock_thread_setup() -> libc::c_int; - pub fn Curl_mbedtlsthreadlock_thread_cleanup() -> libc::c_int; - pub fn Curl_mbedtlsthreadlock_lock_function(n: libc::c_int) -> libc::c_int; - pub fn Curl_mbedtlsthreadlock_unlock_function(n: libc::c_int) -> libc::c_int; - - // gnutls gnutls.rs - pub fn send( - __fd: libc::c_int, - __buf: *const libc::c_void, - __n: size_t, - __flags: libc::c_int, - ) -> ssize_t; - pub fn recv( - __fd: libc::c_int, - __buf: *mut libc::c_void, - __n: size_t, - __flags: libc::c_int, - ) -> ssize_t; - pub fn gnutls_pk_algorithm_get_name(algorithm: gnutls_pk_algorithm_t) -> *const libc::c_char; - pub fn gnutls_init(session: *mut gnutls_session_t, flags: libc::c_uint) -> libc::c_int; - pub fn gnutls_deinit(session: gnutls_session_t); - pub fn gnutls_bye(session: gnutls_session_t, how: gnutls_close_request_t) -> libc::c_int; - pub fn gnutls_handshake(session: gnutls_session_t) -> libc::c_int; - pub fn gnutls_alert_get(session: gnutls_session_t) -> gnutls_alert_description_t; - pub fn gnutls_alert_get_name(alert: gnutls_alert_description_t) -> *const libc::c_char; - pub fn gnutls_cipher_get(session: gnutls_session_t) -> gnutls_cipher_algorithm_t; - pub fn gnutls_kx_get(session: gnutls_session_t) -> gnutls_kx_algorithm_t; - pub fn gnutls_mac_get(session: gnutls_session_t) -> gnutls_mac_algorithm_t; - pub fn gnutls_error_is_fatal(error: libc::c_int) -> libc::c_int; - pub fn gnutls_strerror(error: libc::c_int) -> *const libc::c_char; - pub fn gnutls_record_send( - session: gnutls_session_t, - data: *const libc::c_void, - data_size: size_t, - ) -> ssize_t; - pub fn gnutls_record_recv( - session: gnutls_session_t, - data: *mut libc::c_void, - data_size: size_t, - ) -> ssize_t; - pub fn gnutls_record_get_direction(session: gnutls_session_t) -> libc::c_int; - pub fn gnutls_record_check_pending(session: gnutls_session_t) -> size_t; - pub fn gnutls_server_name_set( - session: gnutls_session_t, - type_0: gnutls_server_name_type_t, - name: *const libc::c_void, - name_length: size_t, - ) -> libc::c_int; - pub fn gnutls_alpn_get_selected_protocol( - session: gnutls_session_t, - protocol: *mut gnutls_datum_t, - ) -> libc::c_int; - pub fn gnutls_alpn_set_protocols( - session: gnutls_session_t, - protocols: *const gnutls_datum_t, - protocols_size: libc::c_uint, - flags: libc::c_uint, - ) -> libc::c_int; - pub fn gnutls_priority_set_direct( - session: gnutls_session_t, - priorities: *const libc::c_char, - err_pos: *mut *const libc::c_char, - ) -> libc::c_int; - pub fn gnutls_set_default_priority(session: gnutls_session_t) -> libc::c_int; - pub fn gnutls_cipher_suite_get_name( - kx_algorithm: gnutls_kx_algorithm_t, - cipher_algorithm: gnutls_cipher_algorithm_t, - mac_algorithm: gnutls_mac_algorithm_t, - ) -> *const libc::c_char; - pub fn gnutls_protocol_get_version(session: gnutls_session_t) -> gnutls_protocol_t; - pub fn gnutls_protocol_get_name(version: gnutls_protocol_t) -> *const libc::c_char; - pub fn gnutls_session_set_data( - session: gnutls_session_t, - session_data: *const libc::c_void, - session_data_size: size_t, - ) -> libc::c_int; - pub fn gnutls_session_get_data( - session: gnutls_session_t, - session_data: *mut libc::c_void, - session_data_size: *mut size_t, - ) -> libc::c_int; - pub fn gnutls_check_version(req_version: *const libc::c_char) -> *const libc::c_char; - pub fn gnutls_credentials_set( - session: gnutls_session_t, - type_0: gnutls_credentials_type_t, - cred: *mut libc::c_void, - ) -> libc::c_int; - pub fn gnutls_certificate_free_credentials(sc: gnutls_certificate_credentials_t); - pub fn gnutls_certificate_allocate_credentials( - res: *mut gnutls_certificate_credentials_t, - ) -> libc::c_int; - pub fn gnutls_certificate_set_verify_flags( - res: gnutls_certificate_credentials_t, - flags: libc::c_uint, - ); - pub fn gnutls_certificate_set_x509_trust_file( - cred: gnutls_certificate_credentials_t, - cafile: *const libc::c_char, - type_0: gnutls_x509_crt_fmt_t, - ) -> libc::c_int; - pub fn gnutls_certificate_set_x509_trust_dir( - cred: gnutls_certificate_credentials_t, - ca_dir: *const libc::c_char, - type_0: gnutls_x509_crt_fmt_t, - ) -> libc::c_int; - pub fn gnutls_certificate_set_x509_crl_file( - res: gnutls_certificate_credentials_t, - crlfile: *const libc::c_char, - type_0: gnutls_x509_crt_fmt_t, - ) -> libc::c_int; - pub fn gnutls_certificate_set_x509_key_file( - res: gnutls_certificate_credentials_t, - certfile: *const libc::c_char, - keyfile: *const libc::c_char, - type_0: gnutls_x509_crt_fmt_t, - ) -> libc::c_int; - pub fn gnutls_certificate_set_x509_key_file2( - res: gnutls_certificate_credentials_t, - certfile: *const libc::c_char, - keyfile: *const libc::c_char, - type_0: gnutls_x509_crt_fmt_t, - pass: *const libc::c_char, - flags: libc::c_uint, - ) -> libc::c_int; - pub fn gnutls_ocsp_status_request_enable_client( - session: gnutls_session_t, - responder_id: *mut gnutls_datum_t, - responder_id_size: size_t, - request_extensions: *mut gnutls_datum_t, - ) -> libc::c_int; - pub fn gnutls_ocsp_status_request_get( - session: gnutls_session_t, - response: *mut gnutls_datum_t, - ) -> libc::c_int; - pub fn gnutls_ocsp_status_request_is_checked( - session: gnutls_session_t, - flags: libc::c_uint, - ) -> libc::c_uint; - pub fn gnutls_global_init() -> libc::c_int; - pub fn gnutls_global_deinit(); - static mut gnutls_free: gnutls_free_function; - pub fn gnutls_transport_set_ptr(session: gnutls_session_t, ptr: gnutls_transport_ptr_t); - pub fn gnutls_transport_set_push_function( - session: gnutls_session_t, - push_func: gnutls_push_func, - ); - pub fn gnutls_transport_set_pull_function( - session: gnutls_session_t, - pull_func: gnutls_pull_func, - ); - pub fn gnutls_srp_free_client_credentials(sc: gnutls_srp_client_credentials_t); - pub fn gnutls_srp_allocate_client_credentials( - sc: *mut gnutls_srp_client_credentials_t, - ) -> libc::c_int; - pub fn gnutls_srp_set_client_credentials( - res: gnutls_srp_client_credentials_t, - username: *const libc::c_char, - password: *const libc::c_char, - ) -> libc::c_int; - pub fn gnutls_certificate_get_peers( - session: gnutls_session_t, - list_size: *mut libc::c_uint, - ) -> *const gnutls_datum_t; - pub fn gnutls_certificate_verify_peers2( - session: gnutls_session_t, - status: *mut libc::c_uint, - ) -> libc::c_int; - pub fn gnutls_pubkey_export( - key: gnutls_pubkey_t, - format: gnutls_x509_crt_fmt_t, - output_data: *mut libc::c_void, - output_data_size: *mut size_t, - ) -> libc::c_int; - pub fn gnutls_x509_crt_init(cert: *mut gnutls_x509_crt_t) -> libc::c_int; - pub fn gnutls_x509_crt_deinit(cert: gnutls_x509_crt_t); - pub fn gnutls_x509_crt_import( - cert: gnutls_x509_crt_t, - data: *const gnutls_datum_t, - format: gnutls_x509_crt_fmt_t, - ) -> libc::c_int; - pub fn gnutls_x509_crt_get_issuer_dn2( - cert: gnutls_x509_crt_t, - dn: *mut gnutls_datum_t, - ) -> libc::c_int; - pub fn gnutls_x509_crt_get_dn2(cert: gnutls_x509_crt_t, dn: *mut gnutls_datum_t) - -> libc::c_int; - pub fn gnutls_x509_crt_get_dn_by_oid( - cert: gnutls_x509_crt_t, - oid: *const libc::c_char, - indx: libc::c_uint, - raw_flag: libc::c_uint, - buf: *mut libc::c_void, - buf_size: *mut size_t, - ) -> libc::c_int; - pub fn gnutls_x509_crt_check_hostname( - cert: gnutls_x509_crt_t, - hostname: *const libc::c_char, - ) -> libc::c_uint; - pub fn gnutls_x509_crt_get_version(cert: gnutls_x509_crt_t) -> libc::c_int; - pub fn gnutls_x509_crt_get_activation_time(cert: gnutls_x509_crt_t) -> time_t; - pub fn gnutls_x509_crt_get_expiration_time(cert: gnutls_x509_crt_t) -> time_t; - pub fn gnutls_x509_crt_get_pk_algorithm( - cert: gnutls_x509_crt_t, - bits: *mut libc::c_uint, - ) -> libc::c_int; - pub fn gnutls_x509_crt_check_issuer( - cert: gnutls_x509_crt_t, - issuer: gnutls_x509_crt_t, - ) -> libc::c_uint; - pub fn gnutls_pubkey_import_x509( - key: gnutls_pubkey_t, - crt: gnutls_x509_crt_t, - flags: libc::c_uint, - ) -> libc::c_int; - pub fn gnutls_pubkey_deinit(key: gnutls_pubkey_t); - pub fn gnutls_pubkey_init(key: *mut gnutls_pubkey_t) -> libc::c_int; - pub fn gnutls_rnd( - level: gnutls_rnd_level_t, - data: *mut libc::c_void, - len: size_t, - ) -> libc::c_int; - pub fn nettle_sha256_digest(ctx: *mut sha256_ctx, length: size_t, digest: *mut uint8_t); - pub fn nettle_sha256_update(ctx: *mut sha256_ctx, length: size_t, data: *const uint8_t); - pub fn nettle_sha256_init(ctx: *mut sha256_ctx); - pub fn Curl_extract_certinfo( - data: *mut Curl_easy, - certnum: libc::c_int, - beg: *const libc::c_char, - end: *const libc::c_char, - ) -> CURLcode; - - pub fn gnutls_ocsp_resp_init(resp: *mut gnutls_ocsp_resp_t) -> libc::c_int; - pub fn gnutls_ocsp_resp_deinit(resp: gnutls_ocsp_resp_t); - pub fn gnutls_ocsp_resp_import( - resp: gnutls_ocsp_resp_t, - data: *const gnutls_datum_t, - ) -> libc::c_int; - pub fn gnutls_ocsp_resp_get_single( - resp: gnutls_ocsp_resp_const_t, - indx: libc::c_uint, - digest: *mut gnutls_digest_algorithm_t, - issuer_name_hash: *mut gnutls_datum_t, - issuer_key_hash: *mut gnutls_datum_t, - serial_number: *mut gnutls_datum_t, - cert_status: *mut libc::c_uint, - this_update: *mut time_t, - next_update: *mut time_t, - revocation_time: *mut time_t, - revocation_reason: *mut libc::c_uint, - ) -> libc::c_int; - - // wolfssl.rs - - // pub fn Curl_none_check_cxn(conn: *mut connectdata) -> libc::c_int; - // pub fn Curl_none_close_all(data: *mut Curl_easy); - // pub fn Curl_none_set_engine( - // data: *mut Curl_easy, - // engine: *const libc::c_char, - // ) -> CURLcode; - // pub fn Curl_none_set_engine_default(data: *mut Curl_easy) -> CURLcode; - // pub fn Curl_none_engines_list(data: *mut Curl_easy) -> *mut curl_slist; - // pub fn Curl_none_false_start() -> bool; - // pub fn Curl_ssl_getsock( - // conn: *mut connectdata, - // socks: *mut curl_socket_t, - // ) -> libc::c_int; - // pub fn Curl_ssl_sessionid_lock(data: *mut Curl_easy); - // pub fn Curl_ssl_sessionid_unlock(data: *mut Curl_easy); - // pub fn Curl_ssl_getsessionid( - // data: *mut Curl_easy, - // conn: *mut connectdata, - // isProxy: bool, - // ssl_sessionid: *mut *mut libc::c_void, - // idsize: *mut size_t, - // sockindex: libc::c_int, - // ) -> bool; - // pub fn Curl_ssl_addsessionid( - // data: *mut Curl_easy, - // conn: *mut connectdata, - // isProxy: bool, - // ssl_sessionid: *mut libc::c_void, - // idsize: size_t, - // sockindex: libc::c_int, - // ) -> CURLcode; - // pub fn Curl_ssl_delsessionid(data: *mut Curl_easy, ssl_sessionid: *mut libc::c_void); - // pub fn Curl_pin_peer_pubkey( - // data: *mut Curl_easy, - // pinnedpubkey: *const libc::c_char, - // pubkey: *const libc::c_uchar, - // pubkeylen: size_t, - // ) -> CURLcode; - // pub fn Curl_tls_keylog_open(); - // pub fn Curl_tls_keylog_close(); - // pub fn Curl_tls_keylog_enabled() -> bool; - // pub fn Curl_tls_keylog_write( - // label: *const libc::c_char, - // client_random: *const libc::c_uchar, - // secret: *const libc::c_uchar, - // secretlen: size_t, - // ) -> bool; - pub fn Curl_parseX509( - cert: *mut Curl_X509certificate, - beg: *const libc::c_char, - end: *const libc::c_char, - ) -> libc::c_int; - pub fn wolfSSL_CTX_set_verify( - _: *mut WOLFSSL_CTX, - _: libc::c_int, - verify_callback: VerifyCallback, - ); - pub fn wolfSSL_CTX_use_PrivateKey_file( - _: *mut WOLFSSL_CTX, - _: *const libc::c_char, - _: libc::c_int, - ) -> libc::c_int; - pub fn wolfSSL_CTX_use_certificate_file( - _: *mut WOLFSSL_CTX, - _: *const libc::c_char, - _: libc::c_int, - ) -> libc::c_int; - pub fn wolfSSL_CTX_load_verify_locations( - _: *mut WOLFSSL_CTX, - _: *const libc::c_char, - _: *const libc::c_char, - ) -> libc::c_int; - pub fn wolfSSL_CTX_set_cipher_list(_: *mut WOLFSSL_CTX, _: *const libc::c_char) -> libc::c_int; - pub fn wolfSSL_CTX_SetMinVersion(ctx: *mut WOLFSSL_CTX, version: libc::c_int) -> libc::c_int; - pub fn wolfSSL_CTX_new(_: *mut WOLFSSL_METHOD) -> *mut WOLFSSL_CTX; - pub fn wolfTLSv1_2_client_method() -> *mut WOLFSSL_METHOD; - pub fn wolfTLSv1_1_client_method() -> *mut WOLFSSL_METHOD; - pub fn wolfSSLv23_client_method() -> *mut WOLFSSL_METHOD; - pub fn wc_FreeRng(_: *mut WC_RNG) -> libc::c_int; - pub fn wc_RNG_GenerateBlock(_: *mut WC_RNG, _: *mut byte, sz: word32) -> libc::c_int; - pub fn wc_InitRng(_: *mut WC_RNG) -> libc::c_int; - pub fn wolfSSL_pending(_: *mut WOLFSSL) -> libc::c_int; - pub fn wolfSSL_lib_version() -> *const libc::c_char; - pub fn wolfSSL_Cleanup() -> libc::c_int; - pub fn wolfSSL_Init() -> libc::c_int; - pub fn wolfSSL_check_domain_name(ssl: *mut WOLFSSL, dn: *const libc::c_char) -> libc::c_int; - pub fn wolfSSL_new(_: *mut WOLFSSL_CTX) -> *mut WOLFSSL; - pub fn wolfSSL_KeepArrays(_: *mut WOLFSSL); - pub fn wolfSSL_set_session(ssl: *mut WOLFSSL, session: *mut WOLFSSL_SESSION) -> libc::c_int; - pub fn wolfSSL_set_fd(_: *mut WOLFSSL, _: libc::c_int) -> libc::c_int; - pub fn wolfSSL_connect(_: *mut WOLFSSL) -> libc::c_int; - pub fn wolfSSL_want_read(_: *mut WOLFSSL) -> libc::c_int; - pub fn wolfSSL_want_write(_: *mut WOLFSSL) -> libc::c_int; - pub fn wolfSSL_GetVersion(ssl: *mut WOLFSSL) -> libc::c_int; - pub fn wolfSSL_get_keys( - _: *mut WOLFSSL, - ms: *mut *mut libc::c_uchar, - msLen: *mut libc::c_uint, - sr: *mut *mut libc::c_uchar, - srLen: *mut libc::c_uint, - cr: *mut *mut libc::c_uchar, - crLen: *mut libc::c_uint, - ) -> libc::c_int; - pub fn wolfSSL_FreeArrays(_: *mut WOLFSSL); - pub fn wolfSSL_get_peer_certificate(ssl: *mut WOLFSSL) -> *mut WOLFSSL_X509; - pub fn wolfSSL_X509_get_der(_: *mut WOLFSSL_X509, _: *mut libc::c_int) -> *const libc::c_uchar; - pub fn wolfSSL_get_version(_: *mut WOLFSSL) -> *const libc::c_char; - pub fn wolfSSL_get_cipher_name(ssl: *mut WOLFSSL) -> *const libc::c_char; - pub fn wolfSSL_get_session(ssl: *mut WOLFSSL) -> *mut WOLFSSL_SESSION; - pub fn wolfSSL_ERR_clear_error(); - pub fn wolfSSL_write(_: *mut WOLFSSL, _: *const libc::c_void, _: libc::c_int) -> libc::c_int; - pub fn wolfSSL_ERR_error_string(_: libc::c_ulong, _: *mut libc::c_char) -> *mut libc::c_char; - pub fn wolfSSL_get_error(_: *mut WOLFSSL, _: libc::c_int) -> libc::c_int; - pub fn wolfSSL_read(_: *mut WOLFSSL, _: *mut libc::c_void, _: libc::c_int) -> libc::c_int; - pub fn wolfSSL_shutdown(_: *mut WOLFSSL) -> libc::c_int; - pub fn wolfSSL_free(_: *mut WOLFSSL); - pub fn wolfSSL_CTX_free(_: *mut WOLFSSL_CTX); - pub fn wc_InitSha256(_: *mut wc_Sha256) -> libc::c_int; - pub fn wc_Sha256Update(_: *mut wc_Sha256, _: *const byte, _: word32) -> libc::c_int; - pub fn wc_Sha256Final(_: *mut wc_Sha256, _: *mut byte) -> libc::c_int; - - // nss.rs - pub fn __xstat( - __ver: libc::c_int, - __filename: *const libc::c_char, - __stat_buf: *mut stat, - ) -> libc::c_int; - pub fn getenv(__name: *const libc::c_char) -> *mut libc::c_char; - pub fn Curl_llist_destroy(_: *mut Curl_llist, _: *mut libc::c_void); - // pub fn Curl_ssl_init_certinfo(data: *mut Curl_easy, num: libc::c_int) -> CURLcode; - // pub fn Curl_pin_peer_pubkey( - // data: *mut Curl_easy, - // pinnedpubkey: *const libc::c_char, - // pubkey: *const libc::c_uchar, - // pubkeylen: size_t, - // ) -> CURLcode; - pub fn PR_ErrorToName(code: PRErrorCode) -> *const libc::c_char; - pub fn PR_GetError() -> PRErrorCode; - pub fn PR_Lock(lock: *mut PRLock); - pub fn PR_ErrorToString(code: PRErrorCode, language: PRLanguageCode) -> *const libc::c_char; - pub fn PR_Now() -> PRTime; - pub fn PR_Free(ptr: *mut libc::c_void); - pub fn PR_FormatTime( - buf: *mut libc::c_char, - buflen: libc::c_int, - fmt: *const libc::c_char, - time: *const PRExplodedTime, - ) -> PRUint32; - pub fn PR_GMTParameters(gmt: *const PRExplodedTime) -> PRTimeParameters; - pub fn PR_ExplodeTime(usecs: PRTime, params: PRTimeParamFn, exploded: *mut PRExplodedTime); - pub fn PR_Unlock(lock: *mut PRLock) -> PRStatus; - pub fn PR_MillisecondsToInterval(milli: PRUint32) -> PRIntervalTime; - pub fn PR_Init(type_0: PRThreadType, priority: PRThreadPriority, maxPTDs: PRUintn); - pub fn PR_SetError(errorCode: PRErrorCode, oserr: PRInt32); - pub fn PR_NewLock() -> *mut PRLock; - pub fn PR_DestroyLock(lock: *mut PRLock); - pub fn PR_SecondsToInterval(seconds: PRUint32) -> PRIntervalTime; - pub fn PR_GetOpenFileInfo(fd: *mut PRFileDesc, info: *mut PRFileInfo) -> PRStatus; - pub fn PR_OpenDir(name: *const libc::c_char) -> *mut PRDir; - pub fn PR_CloseDir(dir: *mut PRDir) -> PRStatus; - pub fn PR_Read(fd: *mut PRFileDesc, buf: *mut libc::c_void, amount: PRInt32) -> PRInt32; - pub fn PR_ReadDir(dir: *mut PRDir, flags: PRDirFlags) -> *mut PRDirEntry; - pub fn PR_GetDefaultIOMethods() -> *const PRIOMethods; - pub fn PR_Close(fd: *mut PRFileDesc) -> PRStatus; - pub fn PR_PushIOLayer( - fd_stack: *mut PRFileDesc, - id: PRDescIdentity, - layer: *mut PRFileDesc, - ) -> PRStatus; - pub fn PR_CreateIOLayerStub( - ident: PRDescIdentity, - methods: *const PRIOMethods, - ) -> *mut PRFileDesc; - pub fn PR_GetUniqueIdentity(layer_name: *const libc::c_char) -> PRDescIdentity; - pub fn PR_Open(name: *const libc::c_char, flags: PRIntn, mode: PRIntn) -> *mut PRFileDesc; - pub fn PR_NewTCPSocket() -> *mut PRFileDesc; - pub fn PR_Recv( - fd: *mut PRFileDesc, - buf: *mut libc::c_void, - amount: PRInt32, - flags: PRIntn, - timeout: PRIntervalTime, - ) -> PRInt32; - pub fn PR_Send( - fd: *mut PRFileDesc, - buf: *const libc::c_void, - amount: PRInt32, - flags: PRIntn, - timeout: PRIntervalTime, - ) -> PRInt32; - pub fn PR_SetSocketOption(fd: *mut PRFileDesc, data: *const PRSocketOptionData) -> PRStatus; - pub fn NSS_ShutdownContext(_: *mut NSSInitContext) -> SECStatus; - pub fn NSS_GetVersion() -> *const libc::c_char; - pub fn PORT_Strdup(s: *const libc::c_char) -> *mut libc::c_char; - pub fn NSS_InitContext( - configdir: *const libc::c_char, - certPrefix: *const libc::c_char, - keyPrefix: *const libc::c_char, - secmodName: *const libc::c_char, - initParams: *mut NSSInitParameters, - flags: PRUint32, - ) -> *mut NSSInitContext; - pub fn SSL_VersionRangeGetDefault( - protocolVariant: SSLProtocolVariant, - vrange: *mut SSLVersionRange, - ) -> SECStatus; - pub fn SSL_VersionRangeGetSupported( - protocolVariant: SSLProtocolVariant, - vrange: *mut SSLVersionRange, - ) -> SECStatus; - pub fn SSL_VersionRangeSet(fd: *mut PRFileDesc, vrange: *const SSLVersionRange) -> SECStatus; - pub fn SSL_GetNumImplementedCiphers() -> PRUint16; - pub fn SSL_GetImplementedCiphers() -> *const PRUint16; - pub fn SSL_CipherPrefSet(fd: *mut PRFileDesc, cipher: PRInt32, enabled: PRBool) -> SECStatus; - pub fn SSL_AuthCertificateHook( - fd: *mut PRFileDesc, - f: SSLAuthCertificate, - arg: *mut libc::c_void, - ) -> SECStatus; - pub fn SSL_PeerStapledOCSPResponses(fd: *mut PRFileDesc) -> *const SECItemArray; - pub fn SSL_AuthCertificate( - arg: *mut libc::c_void, - fd: *mut PRFileDesc, - checkSig: PRBool, - isServer: PRBool, - ) -> SECStatus; - pub fn SSL_BadCertHook( - fd: *mut PRFileDesc, - f: SSLBadCertHandler, - arg: *mut libc::c_void, - ) -> SECStatus; - pub fn SSL_GetNextProto( - fd: *mut PRFileDesc, - state: *mut SSLNextProtoState, - buf: *mut libc::c_uchar, - bufLen: *mut libc::c_uint, - bufLenMax: libc::c_uint, - ) -> SECStatus; - pub fn SECITEM_AllocItem( - arena: *mut PLArenaPool, - item: *mut SECItem, - len: libc::c_uint, - ) -> *mut SECItem; - pub fn CERT_CacheCRL(dbhandle: *mut CERTCertDBHandle, newcrl: *mut SECItem) -> SECStatus; - pub fn CERT_UncacheCRL(dbhandle: *mut CERTCertDBHandle, oldcrl: *mut SECItem) -> SECStatus; - pub fn CERT_GetDefaultCertDB() -> *mut CERTCertDBHandle; - pub fn SSL_ClearSessionCache(); - pub fn SSL_GetClientAuthDataHook( - fd: *mut PRFileDesc, - f: SSLGetClientAuthData, - a: *mut libc::c_void, - ) -> SECStatus; - pub fn SSL_SetSockPeerID(fd: *mut PRFileDesc, peerID: *const libc::c_char) -> SECStatus; - pub fn NSS_GetClientAuthData( - arg: *mut libc::c_void, - socket: *mut PRFileDesc, - caNames: *mut CERTDistNamesStr, - pRetCert: *mut *mut CERTCertificateStr, - pRetKey: *mut *mut SECKEYPrivateKeyStr, - ) -> SECStatus; - pub fn SSL_ImportFD(model: *mut PRFileDesc, fd: *mut PRFileDesc) -> *mut PRFileDesc; - pub fn SSL_SetPKCS11PinArg(fd: *mut PRFileDesc, a: *mut libc::c_void) -> SECStatus; - pub fn SSL_OptionSet(fd: *mut PRFileDesc, option: PRInt32, val: PRIntn) -> SECStatus; - pub fn SSL_SetCanFalseStartCallback( - fd: *mut PRFileDesc, - callback: SSLCanFalseStartCallback, - arg: *mut libc::c_void, - ) -> SECStatus; - pub fn SSL_HandshakeNegotiatedExtension( - socket: *mut PRFileDesc, - extId: SSLExtensionType, - yes: *mut PRBool, - ) -> SECStatus; - pub fn SSL_SetNextProtoNego( - fd: *mut PRFileDesc, - data: *const libc::c_uchar, - length: libc::c_uint, - ) -> SECStatus; - pub fn SSL_ResetHandshake(fd: *mut PRFileDesc, asServer: PRBool) -> SECStatus; - pub fn SSL_SetURL(fd: *mut PRFileDesc, url: *const libc::c_char) -> SECStatus; - pub fn SSL_ForceHandshakeWithTimeout(fd: *mut PRFileDesc, timeout: PRIntervalTime) - -> SECStatus; - pub fn SSL_GetChannelInfo( - fd: *mut PRFileDesc, - info: *mut SSLChannelInfo, - len: PRUintn, - ) -> SECStatus; - pub fn SSL_GetCipherSuiteInfo( - cipherSuite: PRUint16, - info: *mut SSLCipherSuiteInfo, - len: PRUintn, - ) -> SECStatus; - pub fn CERT_NameToAscii(name: *mut CERTName) -> *mut libc::c_char; - pub fn CERT_GetCommonName(name: *const CERTName) -> *mut libc::c_char; - pub fn CERT_GetCertTimes( - c: *const CERTCertificate, - notBefore: *mut PRTime, - notAfter: *mut PRTime, - ) -> SECStatus; - pub fn CERT_FindCertIssuer( - cert: *mut CERTCertificate, - validTime: PRTime, - usage: SECCertUsage, - ) -> *mut CERTCertificate; - pub fn SSL_RevealPinArg(socket: *mut PRFileDesc) -> *mut libc::c_void; - pub fn SECITEM_CompareItem(a: *const SECItem, b: *const SECItem) -> SECComparison; - pub fn SSL_PeerCertificate(fd: *mut PRFileDesc) -> *mut CERTCertificate; - pub fn SECKEY_DestroyPublicKey(key: *mut SECKEYPublicKey); - pub fn CERT_ExtractPublicKey(cert: *mut CERTCertificate) -> *mut SECKEYPublicKey; - pub fn CERT_DestroyCertificate(cert: *mut CERTCertificate); - pub fn SSL_InvalidateSession(fd: *mut PRFileDesc) -> SECStatus; - pub fn SECITEM_FreeItem(zap: *mut SECItem, freeit: PRBool); - pub fn SSL_CipherPolicyGet(cipher: PRInt32, policy: *mut PRInt32) -> SECStatus; - pub fn NSS_SetDomesticPolicy() -> SECStatus; - pub fn SSL_HandshakeCallback( - fd: *mut PRFileDesc, - cb: SSLHandshakeCallback, - client_data: *mut libc::c_void, - ) -> SECStatus; - pub fn SECMOD_LoadUserModule( - moduleSpec: *mut libc::c_char, - parent: *mut SECMODModule, - recurse: PRBool, - ) -> *mut SECMODModule; - pub fn SECMOD_UnloadUserModule(mod_0: *mut SECMODModule) -> SECStatus; - pub fn SECMOD_DestroyModule(module: *mut SECMODModule); - pub fn SECMOD_WaitForAnyTokenEvent( - mod_0: *mut SECMODModule, - flags: libc::c_ulong, - latency: PRIntervalTime, - ) -> *mut PK11SlotInfo; - pub fn PK11_FreeSlot(slot: *mut PK11SlotInfo); - pub fn PK11_SetPasswordFunc(func: PK11PasswordFunc); - pub fn PK11_Authenticate( - slot: *mut PK11SlotInfo, - loadCerts: PRBool, - wincx: *mut libc::c_void, - ) -> SECStatus; - pub fn PK11_FindSlotByName(name: *const libc::c_char) -> *mut PK11SlotInfo; - pub fn PK11_IsPresent(slot: *mut PK11SlotInfo) -> PRBool; - pub fn PK11_GenerateRandom(data: *mut libc::c_uchar, len: libc::c_int) -> SECStatus; - pub fn PK11_FindPrivateKeyFromCert( - slot: *mut PK11SlotInfo, - cert: *mut CERTCertificate, - wincx: *mut libc::c_void, - ) -> *mut SECKEYPrivateKey; - pub fn PK11_DEREncodePublicKey(pubk: *const SECKEYPublicKey) -> *mut SECItem; - pub fn PK11_FindCertFromNickname( - nickname: *const libc::c_char, - wincx: *mut libc::c_void, - ) -> *mut CERTCertificate; - pub fn PK11_FindCertFromDERCertItem( - slot: *mut PK11SlotInfo, - derCert: *const SECItem, - wincx: *mut libc::c_void, - ) -> *mut CERTCertificate; - pub fn PK11_DestroyContext(context: *mut PK11Context, freeit: PRBool); - pub fn PK11_CreateDigestContext(hashAlg: SECOidTag) -> *mut PK11Context; - pub fn PK11_DigestOp( - context: *mut PK11Context, - in_0: *const libc::c_uchar, - len: libc::c_uint, - ) -> SECStatus; - pub fn PK11_DigestFinal( - context: *mut PK11Context, - data: *mut libc::c_uchar, - outLen: *mut libc::c_uint, - length: libc::c_uint, - ) -> SECStatus; - pub fn PK11_ReadRawAttribute( - type_0: PK11ObjectType, - object: *mut libc::c_void, - attr: CK_ATTRIBUTE_TYPE, - item: *mut SECItem, - ) -> SECStatus; - pub fn PK11_DestroyGenericObject(object: *mut PK11GenericObject) -> SECStatus; - pub fn PK11_CreateManagedGenericObject( - slot: *mut PK11SlotInfo, - pTemplate: *const CK_ATTRIBUTE, - count: libc::c_int, - token: PRBool, - ) -> *mut PK11GenericObject; - pub fn SEC_FindCrlByDERCert( - handle: *mut CERTCertDBHandle, - derCrl: *mut SECItem, - type_0: libc::c_int, - ) -> *mut CERTSignedCrl; - pub fn SEC_DestroyCrl(crl: *mut CERTSignedCrl) -> SECStatus; - pub fn ATOB_ConvertAsciiToItem( - binary_item: *mut SECItem, - ascii: *const libc::c_char, - ) -> SECStatus; - pub fn PR_ImportTCPSocket(osfd: PROsfd) -> *mut PRFileDesc; - pub fn CERT_CacheOCSPResponseFromSideChannel( - handle: *mut CERTCertDBHandle, - cert: *mut CERTCertificate, - time: PRTime, - encodedResponse: *const SECItem, - pwArg: *mut libc::c_void, - ) -> SECStatus; - pub fn curlx_uztosi(uznum: size_t) -> libc::c_int; - pub fn curlx_uztoui(uznum: size_t) -> libc::c_uint; - pub fn strpbrk(_: *const libc::c_char, _: *const libc::c_char) -> *mut libc::c_char; - pub fn Curl_llist_init(_: *mut Curl_llist, _: Curl_llist_dtor); - // rustls.rs - pub fn rustls_client_config_builder_dangerous_set_certificate_verifier( - config: *mut rustls_client_config_builder, - callback: rustls_verify_server_cert_callback, - ); - pub fn rustls_client_config_builder_load_roots_from_file( - config: *mut rustls_client_config_builder, - filename: *const libc::c_char, - ) -> rustls_result; - pub fn rustls_client_config_builder_set_protocols( - builder: *mut rustls_client_config_builder, - protocols: *const rustls_slice_bytes, - len: size_t, - ) -> rustls_result; - pub fn rustls_client_config_builder_set_enable_sni( - config: *mut rustls_client_config_builder, - enable: bool, - ); - pub fn rustls_client_config_free(config: *const rustls_client_config); - pub fn rustls_client_connection_new( - config: *const rustls_client_config, - hostname: *const libc::c_char, - conn_out: *mut *mut rustls_connection, - ) -> rustls_result; - pub fn rustls_connection_set_userdata( - conn: *mut rustls_connection, - userdata: *mut libc::c_void, - ); - pub fn rustls_connection_read_tls( - conn: *mut rustls_connection, - callback: rustls_read_callback, - userdata: *mut libc::c_void, - out_n: *mut size_t, - ) -> rustls_io_result; - pub fn rustls_connection_write_tls( - conn: *mut rustls_connection, - callback: rustls_write_callback, - userdata: *mut libc::c_void, - out_n: *mut size_t, - ) -> rustls_io_result; - pub fn rustls_connection_process_new_packets(conn: *mut rustls_connection) -> rustls_result; - pub fn rustls_connection_wants_read(conn: *const rustls_connection) -> bool; - pub fn rustls_connection_wants_write(conn: *const rustls_connection) -> bool; - pub fn rustls_connection_is_handshaking(conn: *const rustls_connection) -> bool; - pub fn rustls_version(buf: *mut libc::c_char, len: size_t) -> size_t; - pub fn rustls_connection_send_close_notify(conn: *mut rustls_connection); - pub fn rustls_connection_get_alpn_protocol( - conn: *const rustls_connection, - protocol_out: *mut *const uint8_t, - protocol_out_len: *mut size_t, - ); - pub fn rustls_connection_write( - conn: *mut rustls_connection, - buf: *const uint8_t, - count: size_t, - out_n: *mut size_t, - ) -> rustls_result; - pub fn rustls_connection_read( - conn: *mut rustls_connection, - buf: *mut uint8_t, - count: size_t, - out_n: *mut size_t, - ) -> rustls_result; - pub fn rustls_connection_free(conn: *mut rustls_connection); - pub fn rustls_error( - result: rustls_result, - buf: *mut libc::c_char, - len: size_t, - out_n: *mut size_t, - ); - pub fn rustls_result_is_cert_error(result: rustls_result) -> bool; - pub fn rustls_client_config_builder_build( - builder: *mut rustls_client_config_builder, - ) -> *const rustls_client_config; - pub fn rustls_client_config_builder_new() -> *mut rustls_client_config_builder; - // pub fn Curl_none_init() -> libc::c_int; - // pub fn Curl_none_cleanup(); - // pub fn Curl_none_check_cxn(conn: *mut connectdata) -> libc::c_int; - // pub fn Curl_none_random( - // data: *mut Curl_easy, - // entropy: *mut libc::c_uchar, - // length: size_t, - // ) -> CURLcode; - // pub fn Curl_none_close_all(data: *mut Curl_easy); - // pub fn Curl_none_session_free(ptr: *mut libc::c_void); - // pub fn Curl_none_cert_status_request() -> bool; - // pub fn Curl_none_set_engine( - // data: *mut Curl_easy, - // engine: *const libc::c_char, - // ) -> CURLcode; - // pub fn Curl_none_set_engine_default(data: *mut Curl_easy) -> CURLcode; - // pub fn Curl_none_engines_list(data: *mut Curl_easy) -> *mut curl_slist; - // pub fn Curl_none_false_start() -> bool; - - // mesalink.rs - pub fn mesalink_SSL_CTX_use_PrivateKey_file( - _: *mut MESALINK_CTX, - _: *const libc::c_char, - _: libc::c_int, - ) -> libc::c_int; - pub fn mesalink_library_init() -> libc::c_int; - pub fn mesalink_TLSv1_2_client_method() -> *mut MESALINK_METHOD; - pub fn mesalink_TLSv1_3_client_method() -> *mut MESALINK_METHOD; - pub fn mesalink_SSL_CTX_new(_: *mut MESALINK_METHOD) -> *mut MESALINK_CTX; - pub fn mesalink_SSL_CTX_load_verify_locations( - _: *mut MESALINK_CTX, - _: *const libc::c_char, - _: *const libc::c_char, - ) -> libc::c_int; - pub fn mesalink_SSL_CTX_use_certificate_chain_file( - _: *mut MESALINK_CTX, - _: *const libc::c_char, - _: libc::c_int, - ) -> libc::c_int; - pub fn mesalink_SSL_CTX_set_verify( - _: *mut MESALINK_CTX, - _: libc::c_int, - cb: Option libc::c_int>, - ) -> libc::c_int; - pub fn mesalink_SSL_new(_: *mut MESALINK_CTX) -> *mut MESALINK_SSL; - pub fn mesalink_SSL_set_tlsext_host_name( - _: *mut MESALINK_SSL, - _: *const libc::c_char, - ) -> libc::c_int; - pub fn mesalink_SSL_set_fd(_: *mut MESALINK_SSL, _: libc::c_int) -> libc::c_int; - pub fn mesalink_SSL_CTX_free(_: *mut MESALINK_CTX); - pub fn mesalink_SSL_connect(_: *mut MESALINK_SSL) -> libc::c_int; - pub fn mesalink_SSL_write( - _: *mut MESALINK_SSL, - _: *const libc::c_void, - _: libc::c_int, - ) -> libc::c_int; - pub fn mesalink_SSL_get_cipher_name(_: *mut MESALINK_SSL) -> *const libc::c_char; - pub fn mesalink_SSL_read( - _: *mut MESALINK_SSL, - _: *mut libc::c_void, - _: libc::c_int, - ) -> libc::c_int; - pub fn mesalink_SSL_shutdown(_: *mut MESALINK_SSL) -> libc::c_int; - pub fn mesalink_SSL_get_version(_: *const MESALINK_SSL) -> *const libc::c_char; - pub fn mesalink_SSL_free(_: *mut MESALINK_SSL); - pub fn mesalink_SSL_get_error(_: *const MESALINK_SSL, _: libc::c_int) -> libc::c_int; - pub fn mesalink_ERR_error_string_n( - e: libc::c_ulong, - buf: *mut libc::c_char, - len: size_t, - ) -> *const libc::c_char; - pub fn mesalink_ERR_print_errors_fp(_: *const FILE); - // openssl.rs - pub fn Curl_wait_ms(timeout_ms: timediff_t) -> libc::c_int; - // pub fn Curl_none_false_start() -> bool; - pub fn curl_slist_append(_: *mut curl_slist, _: *const libc::c_char) -> *mut curl_slist; - // pub fn Curl_ssl_push_certinfo_len( - // data: *mut Curl_easy, - // certnum: libc::c_int, - // label: *const libc::c_char, - // value: *const libc::c_char, - // valuelen: size_t, - // ) -> CURLcode; - // pub fn Curl_ssl_sessionid_lock(data: *mut Curl_easy); - // pub fn Curl_ssl_sessionid_unlock(data: *mut Curl_easy); - // pub fn Curl_ssl_getsessionid( - // data: *mut Curl_easy, - // conn: *mut connectdata, - // isProxy: bool, - // ssl_sessionid: *mut *mut libc::c_void, - // idsize: *mut size_t, - // sockindex: libc::c_int, - // ) -> bool; - // pub fn Curl_ssl_addsessionid( - // data: *mut Curl_easy, - // conn: *mut connectdata, - // isProxy: bool, - // ssl_sessionid: *mut libc::c_void, - // idsize: size_t, - // sockindex: libc::c_int, - // ) -> CURLcode; - // pub fn Curl_ssl_delsessionid(data: *mut Curl_easy, ssl_sessionid: *mut libc::c_void); - pub fn Curl_cert_hostcheck( - match_pattern: *const libc::c_char, - hostname: *const libc::c_char, - ) -> libc::c_int; - pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX; - pub fn EVP_MD_CTX_free(ctx: *mut EVP_MD_CTX); - pub fn EVP_DigestUpdate( - ctx: *mut EVP_MD_CTX, - d: *const libc::c_void, - cnt: size_t, - ) -> libc::c_int; - pub fn EVP_DigestFinal_ex( - ctx: *mut EVP_MD_CTX, - md: *mut libc::c_uchar, - s: *mut libc::c_uint, - ) -> libc::c_int; - pub fn EVP_DigestInit(ctx: *mut EVP_MD_CTX, type_0: *const EVP_MD) -> libc::c_int; - pub fn EVP_sha1() -> *const EVP_MD; - pub fn EVP_sha256() -> *const EVP_MD; - pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> libc::c_int; - pub fn EVP_PKEY_get0_RSA(pkey: *mut EVP_PKEY) -> *mut rsa_st; - pub fn EVP_PKEY_get1_RSA(pkey: *mut EVP_PKEY) -> *mut rsa_st; - pub fn EVP_PKEY_get0_DSA(pkey: *mut EVP_PKEY) -> *mut dsa_st; - pub fn EVP_PKEY_get0_DH(pkey: *mut EVP_PKEY) -> *mut dh_st; - pub fn EVP_PKEY_free(pkey: *mut EVP_PKEY); - pub fn EVP_PKEY_copy_parameters(to: *mut EVP_PKEY, from: *const EVP_PKEY) -> libc::c_int; - pub fn OPENSSL_init_ssl(opts: uint64_t, settings: *const OPENSSL_INIT_SETTINGS) -> libc::c_int; - pub fn SSL_get_shutdown(ssl: *const SSL) -> libc::c_int; - pub fn SSL_pending(s: *const SSL) -> libc::c_int; - pub fn TLS_client_method() -> *const SSL_METHOD; - pub fn SSL_CTX_new(meth: *const SSL_METHOD) -> *mut SSL_CTX; - pub fn SSL_CTX_set_msg_callback( - ctx: *mut SSL_CTX, - cb: Option< - unsafe extern "C" fn( - libc::c_int, - libc::c_int, - libc::c_int, - *const libc::c_void, - size_t, - *mut SSL, - *mut libc::c_void, - ) -> (), - >, - ); - pub fn SSL_alert_desc_string_long(value: libc::c_int) -> *const libc::c_char; - pub fn SSL_CTX_set_options(ctx: *mut SSL_CTX, op: libc::c_ulong) -> libc::c_ulong; - pub fn SSL_CTX_set_next_proto_select_cb( - s: *mut SSL_CTX, - cb: SSL_CTX_npn_select_cb_func, - arg: *mut libc::c_void, - ); - pub fn SSL_CTX_set_alpn_protos( - ctx: *mut SSL_CTX, - protos: *const libc::c_uchar, - protos_len: libc::c_uint, - ) -> libc::c_int; - pub fn SSL_CTX_set_default_passwd_cb_userdata(ctx: *mut SSL_CTX, u: *mut libc::c_void); - pub fn SSL_CTX_set_default_passwd_cb(ctx: *mut SSL_CTX, cb: Option); - pub fn PEM_read_bio_X509_AUX( - bp: *mut BIO, - x: *mut *mut X509, - cb: Option, - u: *mut libc::c_void, - ) -> *mut X509; - pub fn SSL_CTX_use_certificate_chain_file( - ctx: *mut SSL_CTX, - file: *const libc::c_char, - ) -> libc::c_int; - pub fn d2i_X509_bio(bp: *mut BIO, x509: *mut *mut X509) -> *mut X509; - pub fn SSL_CTX_use_certificate_file( - ctx: *mut SSL_CTX, - file: *const libc::c_char, - type_0: libc::c_int, - ) -> libc::c_int; - pub fn SSL_CTX_use_certificate(ctx: *mut SSL_CTX, x: *mut X509) -> libc::c_int; - pub fn SSL_CTX_add_client_CA(ctx: *mut SSL_CTX, x: *mut X509) -> libc::c_int; - pub fn OPENSSL_sk_pop(st: *mut OPENSSL_STACK) -> *mut libc::c_void; - pub fn PEM_read_bio_PrivateKey( - bp: *mut BIO, - x: *mut *mut EVP_PKEY, - cb: Option, - u: *mut libc::c_void, - ) -> *mut EVP_PKEY; - pub fn d2i_PrivateKey_bio(bp: *mut BIO, a: *mut *mut EVP_PKEY) -> *mut EVP_PKEY; - pub fn SSL_CTX_use_PrivateKey_file( - ctx: *mut SSL_CTX, - file: *const libc::c_char, - type_0: libc::c_int, - ) -> libc::c_int; - pub fn SSL_CTX_use_PrivateKey(ctx: *mut SSL_CTX, pkey: *mut EVP_PKEY) -> libc::c_int; - pub fn SSL_get_certificate(ssl: *const SSL) -> *mut X509; - pub fn RSA_flags(r: *const RSA) -> libc::c_int; - pub fn RSA_free(r: *mut RSA); - pub fn SSL_get_privatekey(ssl: *const SSL) -> *mut evp_pkey_st; - pub fn SSL_CTX_check_private_key(ctx: *const SSL_CTX) -> libc::c_int; - pub fn SSL_CTX_set_ciphersuites(ctx: *mut SSL_CTX, str: *const libc::c_char) -> libc::c_int; - pub fn SSL_CTX_set_post_handshake_auth(ctx: *mut SSL_CTX, val: libc::c_int); - pub fn SSL_CTX_set_srp_username(ctx: *mut SSL_CTX, name: *mut libc::c_char) -> libc::c_int; - pub fn SSL_CTX_set_srp_password(ctx: *mut SSL_CTX, password: *mut libc::c_char) -> libc::c_int; - pub fn SSL_CTX_set_cipher_list(_: *mut SSL_CTX, str: *const libc::c_char) -> libc::c_int; - pub fn PEM_X509_INFO_read_bio( - bp: *mut BIO, - sk: *mut stack_st_X509_INFO, - cb: Option, - u: *mut libc::c_void, - ) -> *mut stack_st_X509_INFO; - pub fn X509_STORE_add_cert(ctx: *mut X509_STORE, x: *mut X509) -> libc::c_int; - pub fn X509_STORE_add_crl(ctx: *mut X509_STORE, x: *mut X509_CRL) -> libc::c_int; - pub fn OPENSSL_sk_pop_free( - st: *mut OPENSSL_STACK, - func: Option ()>, - ); - pub fn X509_INFO_free(a: *mut X509_INFO); - pub fn SSL_CTX_load_verify_locations( - ctx: *mut SSL_CTX, - CAfile: *const libc::c_char, - CApath: *const libc::c_char, - ) -> libc::c_int; - pub fn X509_STORE_add_lookup( - v: *mut X509_STORE, - m: *mut X509_LOOKUP_METHOD, - ) -> *mut X509_LOOKUP; - pub fn X509_LOOKUP_file() -> *mut X509_LOOKUP_METHOD; - pub fn X509_load_crl_file( - ctx: *mut X509_LOOKUP, - file: *const libc::c_char, - type_0: libc::c_int, - ) -> libc::c_int; - pub fn X509_STORE_set_flags(ctx: *mut X509_STORE, flags: libc::c_ulong) -> libc::c_int; - pub fn SSL_CTX_set_verify(ctx: *mut SSL_CTX, mode: libc::c_int, callback: SSL_verify_cb); - pub fn SSL_CTX_set_keylog_callback(ctx: *mut SSL_CTX, cb: SSL_CTX_keylog_cb_func); - pub fn SSL_CTX_ctrl( - ctx: *mut SSL_CTX, - cmd: libc::c_int, - larg: libc::c_long, - parg: *mut libc::c_void, - ) -> libc::c_long; - pub fn SSL_CTX_sess_set_new_cb( - ctx: *mut SSL_CTX, - new_session_cb: Option libc::c_int>, - ); - pub fn SSL_get_ex_data(ssl: *const SSL, idx: libc::c_int) -> *mut libc::c_void; - pub fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL; - pub fn SSL_set_session(to: *mut SSL, session: *mut SSL_SESSION) -> libc::c_int; - pub fn SSL_set_bio(s: *mut SSL, rbio: *mut BIO, wbio: *mut BIO); - pub fn BIO_f_ssl() -> *const BIO_METHOD; - pub fn SSL_set_fd(s: *mut SSL, fd: libc::c_int) -> libc::c_int; - pub fn SSL_connect(ssl: *mut SSL) -> libc::c_int; - pub fn X509_get0_extensions(x: *const X509) -> *const stack_st_X509_EXTENSION; - pub fn SSL_get_version(s: *const SSL) -> *const libc::c_char; - pub fn SSL_CIPHER_get_name(c: *const SSL_CIPHER) -> *const libc::c_char; - pub fn SSL_get_current_cipher(s: *const SSL) -> *const SSL_CIPHER; - pub fn SSL_get0_alpn_selected( - ssl: *const SSL, - data: *mut *const libc::c_uchar, - len: *mut libc::c_uint, - ); - pub fn X509_get_version(x: *const X509) -> libc::c_long; - pub fn X509_get_serialNumber(x: *mut X509) -> *mut ASN1_INTEGER; - pub fn BIO_puts(bp: *mut BIO, buf: *const libc::c_char) -> libc::c_int; - pub fn X509_get0_signature( - psig: *mut *const ASN1_BIT_STRING, - palg: *mut *const X509_ALGOR, - x: *const X509, - ); - pub fn X509_PUBKEY_get0_param( - ppkalg: *mut *mut ASN1_OBJECT, - pk: *mut *const libc::c_uchar, - ppklen: *mut libc::c_int, - pa: *mut *mut X509_ALGOR, - pub_0: *mut X509_PUBKEY, - ) -> libc::c_int; - pub fn i2a_ASN1_OBJECT(bp: *mut BIO, a: *const ASN1_OBJECT) -> libc::c_int; - pub fn X509_EXTENSION_get_object(ex: *mut X509_EXTENSION) -> *mut ASN1_OBJECT; - pub fn i2t_ASN1_OBJECT( - buf: *mut libc::c_char, - buf_len: libc::c_int, - a: *const ASN1_OBJECT, - ) -> libc::c_int; - pub fn ASN1_STRING_print(bp: *mut BIO, v: *const ASN1_STRING) -> libc::c_int; - pub fn X509_EXTENSION_get_data(ne: *mut X509_EXTENSION) -> *mut ASN1_OCTET_STRING; - pub fn X509_get_pubkey(x: *mut X509) -> *mut EVP_PKEY; - pub fn RSA_get0_key( - r: *const RSA, - n: *mut *const BIGNUM, - e: *mut *const BIGNUM, - d: *mut *const BIGNUM, - ); - pub fn BN_num_bits(a: *const BIGNUM) -> libc::c_int; - pub fn DSA_get0_pqg( - d: *const DSA, - p: *mut *const BIGNUM, - q: *mut *const BIGNUM, - g: *mut *const BIGNUM, - ); - pub fn DSA_get0_key(d: *const DSA, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM); - pub fn DH_get0_pqg( - dh: *const DH, - p: *mut *const BIGNUM, - q: *mut *const BIGNUM, - g: *mut *const BIGNUM, - ); - pub fn DH_get0_key(dh: *const DH, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM); - pub fn BN_print(bio: *mut BIO, a: *const BIGNUM) -> libc::c_int; - pub fn BIO_printf(bio: *mut BIO, format: *const libc::c_char, _: ...) -> libc::c_int; - pub fn PEM_write_bio_X509(bp: *mut BIO, x: *mut X509) -> libc::c_int; - pub fn X509_get0_notBefore(x: *const X509) -> *const ASN1_TIME; - pub fn ASN1_TIME_print(fp: *mut BIO, a: *const ASN1_TIME) -> libc::c_int; - pub fn X509_get0_notAfter(x: *const X509) -> *const ASN1_TIME; - pub fn X509_get_ext_d2i( - x: *const X509, - nid: libc::c_int, - crit: *mut libc::c_int, - idx: *mut libc::c_int, - ) -> *mut libc::c_void; - pub fn X509_NAME_get_index_by_NID( - name: *mut X509_NAME, - nid: libc::c_int, - lastpos: libc::c_int, - ) -> libc::c_int; - pub fn ASN1_STRING_type(x: *const ASN1_STRING) -> libc::c_int; - pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> libc::c_int; - pub fn CRYPTO_malloc( - num: size_t, - file: *const libc::c_char, - line: libc::c_int, - ) -> *mut libc::c_void; - pub fn ASN1_STRING_get0_data(x: *const ASN1_STRING) -> *const libc::c_uchar; - pub fn ASN1_STRING_to_UTF8( - out: *mut *mut libc::c_uchar, - in_0: *const ASN1_STRING, - ) -> libc::c_int; - pub fn X509_NAME_ENTRY_get_data(ne: *const X509_NAME_ENTRY) -> *mut ASN1_STRING; - pub fn X509_NAME_get_entry(name: *const X509_NAME, loc: libc::c_int) -> *mut X509_NAME_ENTRY; - pub fn X509_get_subject_name(a: *const X509) -> *mut X509_NAME; - pub fn CRYPTO_free(ptr: *mut libc::c_void, file: *const libc::c_char, line: libc::c_int); - pub fn X509_NAME_print_ex( - out: *mut BIO, - nm: *const X509_NAME, - indent: libc::c_int, - flags: libc::c_ulong, - ) -> libc::c_int; - pub fn BIO_s_mem() -> *const BIO_METHOD; - pub fn X509_get_issuer_name(a: *const X509) -> *mut X509_NAME; - pub fn BIO_new_mem_buf(buf: *const libc::c_void, len: libc::c_int) -> *mut BIO; - pub fn BIO_new(type_0: *const BIO_METHOD) -> *mut BIO; - pub fn BIO_s_file() -> *const BIO_METHOD; - pub fn BIO_ctrl( - bp: *mut BIO, - cmd: libc::c_int, - larg: libc::c_long, - parg: *mut libc::c_void, - ) -> libc::c_long; - pub fn PEM_read_bio_X509( - bp: *mut BIO, - x: *mut *mut X509, - cb: Option, - u: *mut libc::c_void, - ) -> *mut X509; - pub fn BIO_free(a: *mut BIO) -> libc::c_int; - pub fn SSL_get_verify_result(ssl: *const SSL) -> libc::c_long; - pub fn X509_verify_cert_error_string(n: libc::c_long) -> *const libc::c_char; - pub fn SSL_ctrl( - ssl: *mut SSL, - cmd: libc::c_int, - larg: libc::c_long, - parg: *mut libc::c_void, - ) -> libc::c_long; - pub fn SSL_get_peer_cert_chain(s: *const SSL) -> *mut stack_st_X509; - pub fn SSL_CTX_get_cert_store(_: *const SSL_CTX) -> *mut X509_STORE; - pub fn SSL_get_peer_certificate(s: *const SSL) -> *mut X509; - pub fn OPENSSL_sk_num(_: *const OPENSSL_STACK) -> libc::c_int; - pub fn OPENSSL_sk_value(_: *const OPENSSL_STACK, _: libc::c_int) -> *mut libc::c_void; - pub fn i2d_X509_PUBKEY(a: *mut X509_PUBKEY, out: *mut *mut libc::c_uchar) -> libc::c_int; - pub fn X509_get_X509_PUBKEY(x: *const X509) -> *mut X509_PUBKEY; - pub fn X509_free(a: *mut X509); - pub fn SSL_write(ssl: *mut SSL, buf: *const libc::c_void, num: libc::c_int) -> libc::c_int; - pub fn SSL_get_error(s: *const SSL, ret_code: libc::c_int) -> libc::c_int; - pub fn OpenSSL_version_num() -> libc::c_ulong; - pub fn SSL_read(ssl: *mut SSL, buf: *mut libc::c_void, num: libc::c_int) -> libc::c_int; - pub fn SSL_shutdown(s: *mut SSL) -> libc::c_int; - pub fn SSL_set_connect_state(s: *mut SSL); - pub fn SSL_free(ssl: *mut SSL); - pub fn SSL_CTX_free(_: *mut SSL_CTX); - pub fn SSL_SESSION_free(ses: *mut SSL_SESSION); - pub fn SSL_set_ex_data(ssl: *mut SSL, idx: libc::c_int, data: *mut libc::c_void) - -> libc::c_int; - pub fn CRYPTO_get_ex_new_index( - class_index: libc::c_int, - argl: libc::c_long, - argp: *mut libc::c_void, - new_func: Option, - dup_func: Option, - free_func: Option, - ) -> libc::c_int; - pub fn RAND_bytes(buf: *mut libc::c_uchar, num: libc::c_int) -> libc::c_int; - pub fn RAND_add(buf: *const libc::c_void, num: libc::c_int, randomness: libc::c_double); - pub fn RAND_load_file(file: *const libc::c_char, max_bytes: libc::c_long) -> libc::c_int; - pub fn RAND_file_name(file: *mut libc::c_char, num: size_t) -> *const libc::c_char; - pub fn RAND_status() -> libc::c_int; - pub fn GENERAL_NAMES_free(a: *mut GENERAL_NAMES); - pub fn X509V3_EXT_print( - out: *mut BIO, - ext: *mut X509_EXTENSION, - flag: libc::c_ulong, - indent: libc::c_int, - ) -> libc::c_int; - pub fn X509_check_issued(issuer: *mut X509, subject: *mut X509) -> libc::c_int; - pub fn ERR_get_error() -> libc::c_ulong; - pub fn ERR_peek_error() -> libc::c_ulong; - pub fn ERR_peek_last_error() -> libc::c_ulong; - pub fn ERR_clear_error(); - pub fn ERR_error_string_n(e: libc::c_ulong, buf: *mut libc::c_char, len: size_t); - pub fn PKCS12_free(a: *mut PKCS12); - pub fn PKCS12_PBE_add(); - pub fn PKCS12_parse( - p12: *mut PKCS12, - pass: *const libc::c_char, - pkey: *mut *mut EVP_PKEY, - cert: *mut *mut X509, - ca: *mut *mut stack_st_X509, - ) -> libc::c_int; - pub fn d2i_PKCS12_bio(bp: *mut BIO, p12: *mut *mut PKCS12) -> *mut PKCS12; - pub fn OCSP_cert_to_id( - dgst: *const EVP_MD, - subject: *const X509, - issuer: *const X509, - ) -> *mut OCSP_CERTID; - pub fn OCSP_response_status(resp: *mut OCSP_RESPONSE) -> libc::c_int; - pub fn OCSP_response_get1_basic(resp: *mut OCSP_RESPONSE) -> *mut OCSP_BASICRESP; - pub fn OCSP_resp_find_status( - bs: *mut OCSP_BASICRESP, - id: *mut OCSP_CERTID, - status: *mut libc::c_int, - reason: *mut libc::c_int, - revtime: *mut *mut ASN1_GENERALIZEDTIME, - thisupd: *mut *mut ASN1_GENERALIZEDTIME, - nextupd: *mut *mut ASN1_GENERALIZEDTIME, - ) -> libc::c_int; - pub fn OCSP_check_validity( - thisupd: *mut ASN1_GENERALIZEDTIME, - nextupd: *mut ASN1_GENERALIZEDTIME, - sec: libc::c_long, - maxsec: libc::c_long, - ) -> libc::c_int; - pub fn OCSP_BASICRESP_free(a: *mut OCSP_BASICRESP); - pub fn OCSP_RESPONSE_free(a: *mut OCSP_RESPONSE); - pub fn d2i_OCSP_RESPONSE( - a: *mut *mut OCSP_RESPONSE, - in_0: *mut *const libc::c_uchar, - len: libc::c_long, - ) -> *mut OCSP_RESPONSE; - pub fn OCSP_CERTID_free(a: *mut OCSP_CERTID); - pub fn OCSP_response_status_str(s: libc::c_long) -> *const libc::c_char; - pub fn OCSP_basic_verify( - bs: *mut OCSP_BASICRESP, - certs: *mut stack_st_X509, - st: *mut X509_STORE, - flags: libc::c_ulong, - ) -> libc::c_int; - pub fn OCSP_cert_status_str(s: libc::c_long) -> *const libc::c_char; - pub fn OCSP_crl_reason_str(s: libc::c_long) -> *const libc::c_char; - pub fn ENGINE_get_first() -> *mut ENGINE; - pub fn ENGINE_get_next(e: *mut ENGINE) -> *mut ENGINE; - pub fn ENGINE_by_id(id: *const libc::c_char) -> *mut ENGINE; - pub fn ENGINE_ctrl( - e: *mut ENGINE, - cmd: libc::c_int, - i: libc::c_long, - p: *mut libc::c_void, - f: Option ()>, - ) -> libc::c_int; - pub fn ENGINE_ctrl_cmd( - e: *mut ENGINE, - cmd_name: *const libc::c_char, - i: libc::c_long, - p: *mut libc::c_void, - f: Option ()>, - cmd_optional: libc::c_int, - ) -> libc::c_int; - pub fn ENGINE_free(e: *mut ENGINE) -> libc::c_int; - pub fn ENGINE_get_id(e: *const ENGINE) -> *const libc::c_char; - pub fn UI_OpenSSL() -> *mut UI_METHOD; - pub fn ENGINE_load_private_key( - e: *mut ENGINE, - key_id: *const libc::c_char, - ui_method: *mut UI_METHOD, - callback_data: *mut libc::c_void, - ) -> *mut EVP_PKEY; - pub fn ENGINE_set_default(e: *mut ENGINE, flags: libc::c_uint) -> libc::c_int; - pub fn ENGINE_init(e: *mut ENGINE) -> libc::c_int; - pub fn ENGINE_finish(e: *mut ENGINE) -> libc::c_int; - pub fn UI_get0_user_data(ui: *mut UI) -> *mut libc::c_void; - pub fn UI_method_set_opener( - method: *mut UI_METHOD, - opener: Option libc::c_int>, - ) -> libc::c_int; - pub fn UI_method_get_opener( - method: *const UI_METHOD, - ) -> Option libc::c_int>; - pub fn UI_method_set_closer( - method: *mut UI_METHOD, - closer: Option libc::c_int>, - ) -> libc::c_int; - pub fn UI_method_get_closer( - method: *const UI_METHOD, - ) -> Option libc::c_int>; - pub fn UI_create_method(name: *const libc::c_char) -> *mut UI_METHOD; - pub fn UI_destroy_method(ui_method: *mut UI_METHOD); - pub fn UI_method_get_writer( - method: *const UI_METHOD, - ) -> Option libc::c_int>; - pub fn UI_method_set_writer( - method: *mut UI_METHOD, - writer: Option libc::c_int>, - ) -> libc::c_int; - pub fn UI_method_get_reader( - method: *const UI_METHOD, - ) -> Option libc::c_int>; - pub fn UI_method_set_reader( - method: *mut UI_METHOD, - reader: Option libc::c_int>, - ) -> libc::c_int; - pub fn UI_set_result( - ui: *mut UI, - uis: *mut UI_STRING, - result: *const libc::c_char, - ) -> libc::c_int; - pub fn UI_get_string_type(uis: *mut UI_STRING) -> UI_string_types; - pub fn UI_get_input_flags(uis: *mut UI_STRING) -> libc::c_int; - - // http_negotiate.rs - pub fn Curl_auth_decode_spnego_message( - data: *mut Curl_easy, - user: *const libc::c_char, - passwood: *const libc::c_char, - service: *const libc::c_char, - host: *const libc::c_char, - chlg64: *const libc::c_char, - nego: *mut negotiatedata, - ) -> CURLcode; - pub fn Curl_auth_create_spnego_message( - data: *mut Curl_easy, - nego: *mut negotiatedata, - outptr: *mut *mut libc::c_char, - outlen: *mut size_t, - ) -> CURLcode; - pub fn Curl_auth_cleanup_spnego(nego: *mut negotiatedata); - // bearssl.rs - pub fn br_ssl_engine_sendapp_ack(cc: *mut br_ssl_engine_context, len: size_t); - pub fn br_ssl_engine_sendapp_buf( - cc: *const br_ssl_engine_context, - len: *mut size_t, - ) -> *mut libc::c_uchar; - pub fn br_ssl_engine_current_state(cc: *const br_ssl_engine_context) -> libc::c_uint; - pub fn br_ssl_engine_set_buffer( - cc: *mut br_ssl_engine_context, - iobuf: *mut libc::c_void, - iobuf_len: size_t, - bidi: libc::c_int, - ); - pub fn br_pem_decoder_event(ctx: *mut br_pem_decoder_context) -> libc::c_int; - pub fn br_pem_decoder_push( - ctx: *mut br_pem_decoder_context, - data: *const libc::c_void, - len: size_t, - ) -> size_t; - pub fn br_pem_decoder_init(ctx: *mut br_pem_decoder_context); - pub fn br_ssl_client_reset( - cc: *mut br_ssl_client_context, - server_name: *const libc::c_char, - resume_session: libc::c_int, - ) -> libc::c_int; - pub fn br_ssl_client_init_full( - cc: *mut br_ssl_client_context, - xc: *mut br_x509_minimal_context, - trust_anchors: *const br_x509_trust_anchor, - trust_anchors_num: size_t, - ); - pub fn br_ssl_engine_close(cc: *mut br_ssl_engine_context); - pub fn br_ssl_engine_flush(cc: *mut br_ssl_engine_context, force: libc::c_int); - pub fn br_ssl_engine_recvrec_ack(cc: *mut br_ssl_engine_context, len: size_t); - pub fn br_ssl_engine_recvrec_buf( - cc: *const br_ssl_engine_context, - len: *mut size_t, - ) -> *mut libc::c_uchar; - pub fn br_ssl_engine_sendrec_ack(cc: *mut br_ssl_engine_context, len: size_t); - pub fn br_ssl_engine_sendrec_buf( - cc: *const br_ssl_engine_context, - len: *mut size_t, - ) -> *mut libc::c_uchar; - pub fn br_ssl_engine_recvapp_ack(cc: *mut br_ssl_engine_context, len: size_t); - pub fn br_sha224_update(ctx: *mut br_sha224_context, data: *const libc::c_void, len: size_t); - pub fn br_sha256_init(ctx: *mut br_sha256_context); - pub fn br_sha256_out(ctx: *const br_sha256_context, out: *mut libc::c_void); - pub fn br_ssl_engine_recvapp_buf( - cc: *const br_ssl_engine_context, - len: *mut size_t, - ) -> *mut libc::c_uchar; - pub fn br_x509_decoder_push( - ctx: *mut br_x509_decoder_context, - data: *const libc::c_void, - len: size_t, - ); - pub fn br_x509_decoder_init( - ctx: *mut br_x509_decoder_context, - append_dn_0: Option< - unsafe extern "C" fn(*mut libc::c_void, *const libc::c_void, size_t) -> (), - >, - append_dn_ctx: *mut libc::c_void, - ); - pub fn br_hmac_drbg_init( - ctx: *mut br_hmac_drbg_context, - digest_class: *const br_hash_class, - seed: *const libc::c_void, - seed_len: size_t, - ); - pub fn br_hmac_drbg_generate( - ctx: *mut br_hmac_drbg_context, - out: *mut libc::c_void, - len: size_t, - ); - pub fn br_prng_seeder_system(name: *mut *const libc::c_char) -> br_prng_seeder; - pub fn ferror(__stream: *mut FILE) -> libc::c_int; - - // option hyper - pub fn hyper_clientconn_handshake( - io: *mut hyper_io, - options: *mut hyper_clientconn_options, - ) -> *mut hyper_task; - pub fn hyper_clientconn_send( - conn: *mut hyper_clientconn, - req: *mut hyper_request, - ) -> *mut hyper_task; - pub fn hyper_clientconn_free(conn: *mut hyper_clientconn); - pub fn hyper_clientconn_options_new() -> *mut hyper_clientconn_options; - pub fn hyper_clientconn_options_free(opts: *mut hyper_clientconn_options); - pub fn hyper_clientconn_options_exec( - opts: *mut hyper_clientconn_options, - exec: *const hyper_executor, - ); - pub fn hyper_error_free(err: *mut hyper_error); - pub fn hyper_error_print(err: *const hyper_error, dst: *mut uint8_t, dst_len: size_t) - -> size_t; - pub fn hyper_request_new() -> *mut hyper_request; - pub fn hyper_request_set_method( - req: *mut hyper_request, - method: *const uint8_t, - method_len: size_t, - ) -> hyper_code; - pub fn hyper_request_set_uri( - req: *mut hyper_request, - uri: *const uint8_t, - uri_len: size_t, - ) -> hyper_code; - pub fn hyper_request_set_version(req: *mut hyper_request, version: libc::c_int) -> hyper_code; - pub fn hyper_request_headers(req: *mut hyper_request) -> *mut hyper_headers; - pub fn hyper_io_new() -> *mut hyper_io; - pub fn hyper_io_free(io: *mut hyper_io); - pub fn hyper_io_set_userdata(io: *mut hyper_io, data: *mut libc::c_void); - pub fn hyper_io_set_read(io: *mut hyper_io, func: hyper_io_read_callback); - pub fn hyper_io_set_write(io: *mut hyper_io, func: hyper_io_write_callback); - pub fn hyper_executor_new() -> *const hyper_executor; - pub fn hyper_executor_free(exec: *const hyper_executor); - pub fn hyper_executor_push(exec: *const hyper_executor, task: *mut hyper_task) -> hyper_code; - pub fn hyper_executor_poll(exec: *const hyper_executor) -> *mut hyper_task; - pub fn hyper_task_free(task: *mut hyper_task); - pub fn hyper_task_value(task: *mut hyper_task) -> *mut libc::c_void; - pub fn hyper_task_type(task: *mut hyper_task) -> hyper_task_return_type; - pub fn hyper_waker_free(waker: *mut hyper_waker); - pub fn Curl_hyper_recv( - userp: *mut libc::c_void, - ctx: *mut hyper_context, - buf: *mut uint8_t, - buflen: size_t, - ) -> size_t; - pub fn Curl_hyper_send( - userp: *mut libc::c_void, - ctx: *mut hyper_context, - buf: *const uint8_t, - buflen: size_t, - ) -> size_t; - pub fn Curl_hyper_stream( - data: *mut Curl_easy, - conn: *mut connectdata, - didwhat: *mut libc::c_int, - done: *mut bool, - select_res: libc::c_int, - ) -> CURLcode; - pub fn Curl_hyper_header( - data: *mut Curl_easy, - headers: *mut hyper_headers, - line: *const libc::c_char, - ) -> CURLcode; - pub fn Curl_hyper_done(_: *mut Curl_easy); - - // in http.rs, remove in future - #[cfg(USE_HYPER)] - pub fn Curl_add_custom_headers( - data: *mut Curl_easy, - is_connect: bool, - headers: *mut libc::c_void, - ) -> CURLcode; - - // http.rs function without hyper - #[cfg(not(USE_HYPER))] - pub fn Curl_add_custom_headers( - data: *mut Curl_easy, - is_connect: bool, - req: *mut dynbuf, - ) -> CURLcode; - - // ftp - pub fn htons(__hostshort: uint16_t) -> uint16_t; - pub fn ntohs(__netshort: uint16_t) -> uint16_t; - - //debug - pub fn __assert_fail( - __assertion: *const libc::c_char, - __file: *const libc::c_char, - __line: libc::c_uint, - __function: *const libc::c_char, - ) -> !; - pub fn curl_dbg_free(ptr: *mut libc::c_void, line: libc::c_int, source: *const libc::c_char); - pub fn curl_dbg_strdup( - str: *const libc::c_char, - line: libc::c_int, - src: *const libc::c_char, - ) -> *mut libc::c_char; - pub fn curl_dbg_calloc( - elements: size_t, - size: size_t, - line: libc::c_int, - source: *const libc::c_char, - ) -> *mut libc::c_void; - pub fn curl_dbg_malloc( - size: size_t, - line: libc::c_int, - source: *const libc::c_char, - ) -> *mut libc::c_void; - pub fn curl_dbg_fopen( - file: *const libc::c_char, - mode: *const libc::c_char, - line: libc::c_int, - source: *const libc::c_char, - ) -> *mut FILE; - pub fn curl_dbg_fclose( - file: *mut FILE, - line: libc::c_int, - source: *const libc::c_char, - ) -> libc::c_int; - pub fn curl_dbg_recv( - sockfd: libc::c_int, - buf: *mut libc::c_void, - len: size_t, - flags: libc::c_int, - line: libc::c_int, - source: *const libc::c_char, - ) -> ssize_t; + pub fn nghttp2_is_fatal(lib_error_code: libc::c_int) -> libc::c_int; + pub fn nghttp2_version(least_version: libc::c_int) -> *mut nghttp2_info; + pub fn Curl_http(data: *mut Curl_easy, done: *mut bool) -> CURLcode; + pub fn Curl_http_done(data: *mut Curl_easy, _: CURLcode, premature: bool) -> CURLcode; + pub fn Curl_base64url_encode( + data: *mut Curl_easy, + inputbuff: *const libc::c_char, + insize: size_t, + outptr: *mut *mut libc::c_char, + outlen: *mut size_t, + ) -> CURLcode; + pub fn Curl_multi_add_perform( + multi: *mut Curl_multi, + data: *mut Curl_easy, + conn: *mut connectdata, + ) -> CURLMcode; + pub fn Curl_multi_max_concurrent_streams(multi: *mut Curl_multi) -> libc::c_uint; + pub fn Curl_close(datap: *mut *mut Curl_easy) -> CURLcode; + pub fn Curl_connalive(conn: *mut connectdata) -> bool; + pub fn Curl_saferealloc(ptr: *mut libc::c_void, size: size_t) -> *mut libc::c_void; + + // mbedtls ftp + + pub fn Curl_ssl_connect( + data: *mut Curl_easy, + conn: *mut connectdata, + sockindex: libc::c_int, + ) -> CURLcode; + pub fn Curl_ssl_close(data: *mut Curl_easy, conn: *mut connectdata, sockindex: libc::c_int); + pub fn Curl_ssl_shutdown( + data: *mut Curl_easy, + conn: *mut connectdata, + sockindex: libc::c_int, + ) -> CURLcode; + + // http_ntlm.rs + pub fn curl_free(p: *mut libc::c_void); + pub fn Curl_http_auth_cleanup_ntlm_wb(conn: *mut connectdata); + pub fn Curl_base64_decode( + src: *const libc::c_char, + outptr: *mut *mut libc::c_uchar, + outlen: *mut size_t, + ) -> CURLcode; + pub fn Curl_bufref_init(br: *mut bufref); + pub fn Curl_bufref_set( + br: *mut bufref, + ptr: *const libc::c_void, + len: size_t, + dtor: Option ()>, + ); + pub fn Curl_bufref_ptr(br: *const bufref) -> *const libc::c_uchar; + pub fn Curl_bufref_len(br: *const bufref) -> size_t; + pub fn Curl_bufref_free(br: *mut bufref); + #[cfg(USE_NTLM)] + pub fn Curl_auth_create_ntlm_type1_message( + data: *mut Curl_easy, + userp: *const libc::c_char, + passwdp: *const libc::c_char, + service: *const libc::c_char, + host: *const libc::c_char, + ntlm: *mut ntlmdata, + out: *mut bufref, + ) -> CURLcode; + #[cfg(USE_NTLM)] + pub fn Curl_auth_decode_ntlm_type2_message( + data: *mut Curl_easy, + type2: *const bufref, + ntlm: *mut ntlmdata, + ) -> CURLcode; + #[cfg(USE_NTLM)] + pub fn Curl_auth_create_ntlm_type3_message( + data: *mut Curl_easy, + userp: *const libc::c_char, + passwdp: *const libc::c_char, + ntlm: *mut ntlmdata, + out: *mut bufref, + ) -> CURLcode; + #[cfg(USE_NTLM)] + pub fn Curl_auth_cleanup_ntlm(ntlm: *mut ntlmdata); + + // new http_proxy.rs + pub fn Curl_ssl_connect_nonblocking( + data: *mut Curl_easy, + conn: *mut connectdata, + isproxy: bool, + sockindex: libc::c_int, + done: *mut bool, + ) -> CURLcode; + + // http.rs + pub fn Curl_auth_is_ntlm_supported() -> bool; + pub fn Curl_input_ntlm( + data: *mut Curl_easy, + proxy: bool, + header: *const libc::c_char, + ) -> CURLcode; + pub fn Curl_output_ntlm(data: *mut Curl_easy, proxy: bool) -> CURLcode; + pub fn Curl_input_ntlm_wb( + data: *mut Curl_easy, + conn: *mut connectdata, + proxy: bool, + header: *const libc::c_char, + ) -> CURLcode; + pub fn Curl_output_ntlm_wb( + data: *mut Curl_easy, + conn: *mut connectdata, + proxy: bool, + ) -> CURLcode; + pub fn Curl_hsts_parse( + h: *mut hsts, + hostname: *const libc::c_char, + sts: *const libc::c_char, + ) -> CURLcode; + pub fn Curl_auth_is_spnego_supported() -> bool; + pub fn Curl_input_negotiate( + data: *mut Curl_easy, + conn: *mut connectdata, + proxy: bool, + header: *const libc::c_char, + ) -> CURLcode; + pub fn Curl_output_negotiate( + data: *mut Curl_easy, + conn: *mut connectdata, + proxy: bool, + ) -> CURLcode; + + // mbedtls vtls.rs + pub fn fread( + _: *mut libc::c_void, + _: libc::c_ulong, + _: libc::c_ulong, + _: *mut FILE, + ) -> libc::c_ulong; + pub fn fseek(__stream: *mut FILE, __off: libc::c_long, __whence: libc::c_int) -> libc::c_int; + pub fn ftell(__stream: *mut FILE) -> libc::c_long; + + pub fn curl_slist_free_all(_: *mut curl_slist); + pub fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void; + + pub fn Curl_slist_append_nodup( + list: *mut curl_slist, + data: *mut libc::c_char, + ) -> *mut curl_slist; + pub fn Curl_recv_plain( + data: *mut Curl_easy, + num: libc::c_int, + buf: *mut libc::c_char, + len: size_t, + code: *mut CURLcode, + ) -> ssize_t; + pub fn Curl_send_plain( + data: *mut Curl_easy, + num: libc::c_int, + mem: *const libc::c_void, + len: size_t, + code: *mut CURLcode, + ) -> ssize_t; + + // mbedtls_threadlock.rs + pub fn pthread_mutex_init( + __mutex: *mut pthread_mutex_t, + __mutexattr: *const pthread_mutexattr_t, + ) -> libc::c_int; + pub fn pthread_mutex_destroy(__mutex: *mut pthread_mutex_t) -> libc::c_int; + pub fn pthread_mutex_lock(__mutex: *mut pthread_mutex_t) -> libc::c_int; + pub fn pthread_mutex_unlock(__mutex: *mut pthread_mutex_t) -> libc::c_int; + + // mbedtls.rs + pub fn mbedtls_version_get_number() -> libc::c_uint; + pub fn mbedtls_net_send( + ctx: *mut libc::c_void, + buf: *const libc::c_uchar, + len: size_t, + ) -> libc::c_int; + pub fn mbedtls_net_recv( + ctx: *mut libc::c_void, + buf: *mut libc::c_uchar, + len: size_t, + ) -> libc::c_int; + pub fn mbedtls_ssl_session_free(session: *mut mbedtls_ssl_session); + pub fn mbedtls_ssl_session_init(session: *mut mbedtls_ssl_session); + pub fn mbedtls_ssl_config_free(conf: *mut mbedtls_ssl_config); + pub fn mbedtls_ssl_config_defaults( + conf: *mut mbedtls_ssl_config, + endpoint: libc::c_int, + transport: libc::c_int, + preset: libc::c_int, + ) -> libc::c_int; + pub fn mbedtls_ssl_config_init(conf: *mut mbedtls_ssl_config); + pub fn mbedtls_ssl_free(ssl: *mut mbedtls_ssl_context); + pub fn mbedtls_ssl_write( + ssl: *mut mbedtls_ssl_context, + buf: *const libc::c_uchar, + len: size_t, + ) -> libc::c_int; + pub fn mbedtls_ssl_read( + ssl: *mut mbedtls_ssl_context, + buf: *mut libc::c_uchar, + len: size_t, + ) -> libc::c_int; + pub fn mbedtls_ssl_handshake(ssl: *mut mbedtls_ssl_context) -> libc::c_int; + pub fn mbedtls_ssl_get_session( + ssl: *const mbedtls_ssl_context, + session: *mut mbedtls_ssl_session, + ) -> libc::c_int; + pub fn mbedtls_ssl_get_peer_cert(ssl: *const mbedtls_ssl_context) -> *const mbedtls_x509_crt; + pub fn mbedtls_ssl_get_ciphersuite(ssl: *const mbedtls_ssl_context) -> *const libc::c_char; + pub fn mbedtls_ssl_get_verify_result(ssl: *const mbedtls_ssl_context) -> uint32_t; + pub fn mbedtls_ssl_get_bytes_avail(ssl: *const mbedtls_ssl_context) -> size_t; + pub fn mbedtls_ssl_conf_renegotiation( + conf: *mut mbedtls_ssl_config, + renegotiation: libc::c_int, + ); + pub fn mbedtls_ssl_conf_session_tickets( + conf: *mut mbedtls_ssl_config, + use_tickets: libc::c_int, + ); + pub fn mbedtls_ssl_conf_min_version( + conf: *mut mbedtls_ssl_config, + major: libc::c_int, + minor: libc::c_int, + ); + pub fn mbedtls_ssl_conf_max_version( + conf: *mut mbedtls_ssl_config, + major: libc::c_int, + minor: libc::c_int, + ); + pub fn mbedtls_ssl_get_alpn_protocol(ssl: *const mbedtls_ssl_context) -> *const libc::c_char; + pub fn mbedtls_ssl_conf_alpn_protocols( + conf: *mut mbedtls_ssl_config, + protos: *mut *const libc::c_char, + ) -> libc::c_int; + pub fn mbedtls_ssl_set_hostname( + ssl: *mut mbedtls_ssl_context, + hostname: *const libc::c_char, + ) -> libc::c_int; + pub fn mbedtls_ssl_conf_own_cert( + conf: *mut mbedtls_ssl_config, + own_cert: *mut mbedtls_x509_crt, + pk_key: *mut mbedtls_pk_context, + ) -> libc::c_int; + pub fn mbedtls_ssl_conf_ca_chain( + conf: *mut mbedtls_ssl_config, + ca_chain: *mut mbedtls_x509_crt, + ca_crl: *mut mbedtls_x509_crl, + ); + pub fn mbedtls_ssl_conf_cert_profile( + conf: *mut mbedtls_ssl_config, + profile: *const mbedtls_x509_crt_profile, + ); + pub fn mbedtls_ssl_conf_ciphersuites( + conf: *mut mbedtls_ssl_config, + ciphersuites: *const libc::c_int, + ); + pub fn mbedtls_ssl_set_session( + ssl: *mut mbedtls_ssl_context, + session: *const mbedtls_ssl_session, + ) -> libc::c_int; + pub fn mbedtls_ssl_set_bio( + ssl: *mut mbedtls_ssl_context, + p_bio: *mut libc::c_void, + f_send: Option, + f_recv: Option, + f_recv_timeout: Option, + ); + pub fn mbedtls_ssl_conf_rng( + conf: *mut mbedtls_ssl_config, + f_rng: Option< + unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_uchar, size_t) -> libc::c_int, + >, + p_rng: *mut libc::c_void, + ); + pub fn mbedtls_ssl_conf_authmode(conf: *mut mbedtls_ssl_config, authmode: libc::c_int); + pub fn mbedtls_ssl_setup( + ssl: *mut mbedtls_ssl_context, + conf: *const mbedtls_ssl_config, + ) -> libc::c_int; + pub fn mbedtls_ssl_init(ssl: *mut mbedtls_ssl_context); + pub fn mbedtls_pk_init(ctx: *mut mbedtls_pk_context); + pub fn mbedtls_pk_free(ctx: *mut mbedtls_pk_context); + pub fn mbedtls_pk_can_do( + ctx: *const mbedtls_pk_context, + type_0: mbedtls_pk_type_t, + ) -> libc::c_int; + pub fn mbedtls_pk_parse_key( + ctx: *mut mbedtls_pk_context, + key: *const libc::c_uchar, + keylen: size_t, + pwd: *const libc::c_uchar, + pwdlen: size_t, + ) -> libc::c_int; + pub fn mbedtls_pk_parse_keyfile( + ctx: *mut mbedtls_pk_context, + path: *const libc::c_char, + password: *const libc::c_char, + ) -> libc::c_int; + pub fn mbedtls_pk_write_pubkey_der( + ctx: *mut mbedtls_pk_context, + buf: *mut libc::c_uchar, + size: size_t, + ) -> libc::c_int; + pub fn mbedtls_ssl_list_ciphersuites() -> *const libc::c_int; + pub fn mbedtls_x509_crl_parse_file( + chain: *mut mbedtls_x509_crl, + path: *const libc::c_char, + ) -> libc::c_int; + pub fn mbedtls_x509_crl_init(crl: *mut mbedtls_x509_crl); + pub fn mbedtls_x509_crl_free(crl: *mut mbedtls_x509_crl); + pub fn mbedtls_x509_crt_parse_der( + chain: *mut mbedtls_x509_crt, + buf: *const libc::c_uchar, + buflen: size_t, + ) -> libc::c_int; + pub fn mbedtls_x509_crt_parse( + chain: *mut mbedtls_x509_crt, + buf: *const libc::c_uchar, + buflen: size_t, + ) -> libc::c_int; + pub fn mbedtls_x509_crt_parse_file( + chain: *mut mbedtls_x509_crt, + path: *const libc::c_char, + ) -> libc::c_int; + pub fn mbedtls_x509_crt_parse_path( + chain: *mut mbedtls_x509_crt, + path: *const libc::c_char, + ) -> libc::c_int; + pub fn mbedtls_x509_crt_info( + buf: *mut libc::c_char, + size: size_t, + prefix: *const libc::c_char, + crt: *const mbedtls_x509_crt, + ) -> libc::c_int; + pub fn mbedtls_x509_crt_init(crt: *mut mbedtls_x509_crt); + pub fn mbedtls_x509_crt_free(crt: *mut mbedtls_x509_crt); + pub fn mbedtls_strerror(errnum: libc::c_int, buffer: *mut libc::c_char, buflen: size_t); + pub fn mbedtls_entropy_init(ctx: *mut mbedtls_entropy_context); + pub fn mbedtls_entropy_free(ctx: *mut mbedtls_entropy_context); + pub fn mbedtls_entropy_func( + data: *mut libc::c_void, + output: *mut libc::c_uchar, + len: size_t, + ) -> libc::c_int; + pub fn mbedtls_ctr_drbg_init(ctx: *mut mbedtls_ctr_drbg_context); + pub fn mbedtls_ctr_drbg_seed( + ctx: *mut mbedtls_ctr_drbg_context, + f_entropy: Option< + unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_uchar, size_t) -> libc::c_int, + >, + p_entropy: *mut libc::c_void, + custom: *const libc::c_uchar, + len: size_t, + ) -> libc::c_int; + pub fn mbedtls_ctr_drbg_free(ctx: *mut mbedtls_ctr_drbg_context); + pub fn mbedtls_ctr_drbg_random( + p_rng: *mut libc::c_void, + output: *mut libc::c_uchar, + output_len: size_t, + ) -> libc::c_int; + pub fn mbedtls_sha256_ret( + input: *const libc::c_uchar, + ilen: size_t, + output: *mut libc::c_uchar, + is224: libc::c_int, + ) -> libc::c_int; + pub fn Curl_multiuse_state(data: *mut Curl_easy, bundlestate: libc::c_int); + pub fn Curl_mbedtlsthreadlock_thread_setup() -> libc::c_int; + pub fn Curl_mbedtlsthreadlock_thread_cleanup() -> libc::c_int; + pub fn Curl_mbedtlsthreadlock_lock_function(n: libc::c_int) -> libc::c_int; + pub fn Curl_mbedtlsthreadlock_unlock_function(n: libc::c_int) -> libc::c_int; + + // gnutls gnutls.rs + pub fn send( + __fd: libc::c_int, + __buf: *const libc::c_void, + __n: size_t, + __flags: libc::c_int, + ) -> ssize_t; + pub fn recv( + __fd: libc::c_int, + __buf: *mut libc::c_void, + __n: size_t, + __flags: libc::c_int, + ) -> ssize_t; + pub fn gnutls_pk_algorithm_get_name(algorithm: gnutls_pk_algorithm_t) -> *const libc::c_char; + pub fn gnutls_init(session: *mut gnutls_session_t, flags: libc::c_uint) -> libc::c_int; + pub fn gnutls_deinit(session: gnutls_session_t); + pub fn gnutls_bye(session: gnutls_session_t, how: gnutls_close_request_t) -> libc::c_int; + pub fn gnutls_handshake(session: gnutls_session_t) -> libc::c_int; + pub fn gnutls_alert_get(session: gnutls_session_t) -> gnutls_alert_description_t; + pub fn gnutls_alert_get_name(alert: gnutls_alert_description_t) -> *const libc::c_char; + pub fn gnutls_cipher_get(session: gnutls_session_t) -> gnutls_cipher_algorithm_t; + pub fn gnutls_kx_get(session: gnutls_session_t) -> gnutls_kx_algorithm_t; + pub fn gnutls_mac_get(session: gnutls_session_t) -> gnutls_mac_algorithm_t; + pub fn gnutls_error_is_fatal(error: libc::c_int) -> libc::c_int; + pub fn gnutls_strerror(error: libc::c_int) -> *const libc::c_char; + pub fn gnutls_record_send( + session: gnutls_session_t, + data: *const libc::c_void, + data_size: size_t, + ) -> ssize_t; + pub fn gnutls_record_recv( + session: gnutls_session_t, + data: *mut libc::c_void, + data_size: size_t, + ) -> ssize_t; + pub fn gnutls_record_get_direction(session: gnutls_session_t) -> libc::c_int; + pub fn gnutls_record_check_pending(session: gnutls_session_t) -> size_t; + pub fn gnutls_server_name_set( + session: gnutls_session_t, + type_0: gnutls_server_name_type_t, + name: *const libc::c_void, + name_length: size_t, + ) -> libc::c_int; + pub fn gnutls_alpn_get_selected_protocol( + session: gnutls_session_t, + protocol: *mut gnutls_datum_t, + ) -> libc::c_int; + pub fn gnutls_alpn_set_protocols( + session: gnutls_session_t, + protocols: *const gnutls_datum_t, + protocols_size: libc::c_uint, + flags: libc::c_uint, + ) -> libc::c_int; + pub fn gnutls_priority_set_direct( + session: gnutls_session_t, + priorities: *const libc::c_char, + err_pos: *mut *const libc::c_char, + ) -> libc::c_int; + pub fn gnutls_set_default_priority(session: gnutls_session_t) -> libc::c_int; + pub fn gnutls_cipher_suite_get_name( + kx_algorithm: gnutls_kx_algorithm_t, + cipher_algorithm: gnutls_cipher_algorithm_t, + mac_algorithm: gnutls_mac_algorithm_t, + ) -> *const libc::c_char; + pub fn gnutls_protocol_get_version(session: gnutls_session_t) -> gnutls_protocol_t; + pub fn gnutls_protocol_get_name(version: gnutls_protocol_t) -> *const libc::c_char; + pub fn gnutls_session_set_data( + session: gnutls_session_t, + session_data: *const libc::c_void, + session_data_size: size_t, + ) -> libc::c_int; + pub fn gnutls_session_get_data( + session: gnutls_session_t, + session_data: *mut libc::c_void, + session_data_size: *mut size_t, + ) -> libc::c_int; + pub fn gnutls_check_version(req_version: *const libc::c_char) -> *const libc::c_char; + pub fn gnutls_credentials_set( + session: gnutls_session_t, + type_0: gnutls_credentials_type_t, + cred: *mut libc::c_void, + ) -> libc::c_int; + pub fn gnutls_certificate_free_credentials(sc: gnutls_certificate_credentials_t); + pub fn gnutls_certificate_allocate_credentials( + res: *mut gnutls_certificate_credentials_t, + ) -> libc::c_int; + pub fn gnutls_certificate_set_verify_flags( + res: gnutls_certificate_credentials_t, + flags: libc::c_uint, + ); + pub fn gnutls_certificate_set_x509_trust_file( + cred: gnutls_certificate_credentials_t, + cafile: *const libc::c_char, + type_0: gnutls_x509_crt_fmt_t, + ) -> libc::c_int; + pub fn gnutls_certificate_set_x509_trust_dir( + cred: gnutls_certificate_credentials_t, + ca_dir: *const libc::c_char, + type_0: gnutls_x509_crt_fmt_t, + ) -> libc::c_int; + pub fn gnutls_certificate_set_x509_crl_file( + res: gnutls_certificate_credentials_t, + crlfile: *const libc::c_char, + type_0: gnutls_x509_crt_fmt_t, + ) -> libc::c_int; + pub fn gnutls_certificate_set_x509_key_file( + res: gnutls_certificate_credentials_t, + certfile: *const libc::c_char, + keyfile: *const libc::c_char, + type_0: gnutls_x509_crt_fmt_t, + ) -> libc::c_int; + pub fn gnutls_certificate_set_x509_key_file2( + res: gnutls_certificate_credentials_t, + certfile: *const libc::c_char, + keyfile: *const libc::c_char, + type_0: gnutls_x509_crt_fmt_t, + pass: *const libc::c_char, + flags: libc::c_uint, + ) -> libc::c_int; + pub fn gnutls_ocsp_status_request_enable_client( + session: gnutls_session_t, + responder_id: *mut gnutls_datum_t, + responder_id_size: size_t, + request_extensions: *mut gnutls_datum_t, + ) -> libc::c_int; + pub fn gnutls_ocsp_status_request_get( + session: gnutls_session_t, + response: *mut gnutls_datum_t, + ) -> libc::c_int; + pub fn gnutls_ocsp_status_request_is_checked( + session: gnutls_session_t, + flags: libc::c_uint, + ) -> libc::c_uint; + pub fn gnutls_global_init() -> libc::c_int; + pub fn gnutls_global_deinit(); + static mut gnutls_free: gnutls_free_function; + pub fn gnutls_transport_set_ptr(session: gnutls_session_t, ptr: gnutls_transport_ptr_t); + pub fn gnutls_transport_set_push_function( + session: gnutls_session_t, + push_func: gnutls_push_func, + ); + pub fn gnutls_transport_set_pull_function( + session: gnutls_session_t, + pull_func: gnutls_pull_func, + ); + pub fn gnutls_srp_free_client_credentials(sc: gnutls_srp_client_credentials_t); + pub fn gnutls_srp_allocate_client_credentials( + sc: *mut gnutls_srp_client_credentials_t, + ) -> libc::c_int; + pub fn gnutls_srp_set_client_credentials( + res: gnutls_srp_client_credentials_t, + username: *const libc::c_char, + password: *const libc::c_char, + ) -> libc::c_int; + pub fn gnutls_certificate_get_peers( + session: gnutls_session_t, + list_size: *mut libc::c_uint, + ) -> *const gnutls_datum_t; + pub fn gnutls_certificate_verify_peers2( + session: gnutls_session_t, + status: *mut libc::c_uint, + ) -> libc::c_int; + pub fn gnutls_pubkey_export( + key: gnutls_pubkey_t, + format: gnutls_x509_crt_fmt_t, + output_data: *mut libc::c_void, + output_data_size: *mut size_t, + ) -> libc::c_int; + pub fn gnutls_x509_crt_init(cert: *mut gnutls_x509_crt_t) -> libc::c_int; + pub fn gnutls_x509_crt_deinit(cert: gnutls_x509_crt_t); + pub fn gnutls_x509_crt_import( + cert: gnutls_x509_crt_t, + data: *const gnutls_datum_t, + format: gnutls_x509_crt_fmt_t, + ) -> libc::c_int; + pub fn gnutls_x509_crt_get_issuer_dn2( + cert: gnutls_x509_crt_t, + dn: *mut gnutls_datum_t, + ) -> libc::c_int; + pub fn gnutls_x509_crt_get_dn2(cert: gnutls_x509_crt_t, dn: *mut gnutls_datum_t) + -> libc::c_int; + pub fn gnutls_x509_crt_get_dn_by_oid( + cert: gnutls_x509_crt_t, + oid: *const libc::c_char, + indx: libc::c_uint, + raw_flag: libc::c_uint, + buf: *mut libc::c_void, + buf_size: *mut size_t, + ) -> libc::c_int; + pub fn gnutls_x509_crt_check_hostname( + cert: gnutls_x509_crt_t, + hostname: *const libc::c_char, + ) -> libc::c_uint; + pub fn gnutls_x509_crt_get_version(cert: gnutls_x509_crt_t) -> libc::c_int; + pub fn gnutls_x509_crt_get_activation_time(cert: gnutls_x509_crt_t) -> time_t; + pub fn gnutls_x509_crt_get_expiration_time(cert: gnutls_x509_crt_t) -> time_t; + pub fn gnutls_x509_crt_get_pk_algorithm( + cert: gnutls_x509_crt_t, + bits: *mut libc::c_uint, + ) -> libc::c_int; + pub fn gnutls_x509_crt_check_issuer( + cert: gnutls_x509_crt_t, + issuer: gnutls_x509_crt_t, + ) -> libc::c_uint; + pub fn gnutls_pubkey_import_x509( + key: gnutls_pubkey_t, + crt: gnutls_x509_crt_t, + flags: libc::c_uint, + ) -> libc::c_int; + pub fn gnutls_pubkey_deinit(key: gnutls_pubkey_t); + pub fn gnutls_pubkey_init(key: *mut gnutls_pubkey_t) -> libc::c_int; + pub fn gnutls_rnd( + level: gnutls_rnd_level_t, + data: *mut libc::c_void, + len: size_t, + ) -> libc::c_int; + pub fn nettle_sha256_digest(ctx: *mut sha256_ctx, length: size_t, digest: *mut uint8_t); + pub fn nettle_sha256_update(ctx: *mut sha256_ctx, length: size_t, data: *const uint8_t); + pub fn nettle_sha256_init(ctx: *mut sha256_ctx); + pub fn Curl_extract_certinfo( + data: *mut Curl_easy, + certnum: libc::c_int, + beg: *const libc::c_char, + end: *const libc::c_char, + ) -> CURLcode; + + pub fn gnutls_ocsp_resp_init(resp: *mut gnutls_ocsp_resp_t) -> libc::c_int; + pub fn gnutls_ocsp_resp_deinit(resp: gnutls_ocsp_resp_t); + pub fn gnutls_ocsp_resp_import( + resp: gnutls_ocsp_resp_t, + data: *const gnutls_datum_t, + ) -> libc::c_int; + pub fn gnutls_ocsp_resp_get_single( + resp: gnutls_ocsp_resp_const_t, + indx: libc::c_uint, + digest: *mut gnutls_digest_algorithm_t, + issuer_name_hash: *mut gnutls_datum_t, + issuer_key_hash: *mut gnutls_datum_t, + serial_number: *mut gnutls_datum_t, + cert_status: *mut libc::c_uint, + this_update: *mut time_t, + next_update: *mut time_t, + revocation_time: *mut time_t, + revocation_reason: *mut libc::c_uint, + ) -> libc::c_int; + + // wolfssl.rs + + // pub fn Curl_none_check_cxn(conn: *mut connectdata) -> libc::c_int; + // pub fn Curl_none_close_all(data: *mut Curl_easy); + // pub fn Curl_none_set_engine( + // data: *mut Curl_easy, + // engine: *const libc::c_char, + // ) -> CURLcode; + // pub fn Curl_none_set_engine_default(data: *mut Curl_easy) -> CURLcode; + // pub fn Curl_none_engines_list(data: *mut Curl_easy) -> *mut curl_slist; + // pub fn Curl_none_false_start() -> bool; + // pub fn Curl_ssl_getsock( + // conn: *mut connectdata, + // socks: *mut curl_socket_t, + // ) -> libc::c_int; + // pub fn Curl_ssl_sessionid_lock(data: *mut Curl_easy); + // pub fn Curl_ssl_sessionid_unlock(data: *mut Curl_easy); + // pub fn Curl_ssl_getsessionid( + // data: *mut Curl_easy, + // conn: *mut connectdata, + // isProxy: bool, + // ssl_sessionid: *mut *mut libc::c_void, + // idsize: *mut size_t, + // sockindex: libc::c_int, + // ) -> bool; + // pub fn Curl_ssl_addsessionid( + // data: *mut Curl_easy, + // conn: *mut connectdata, + // isProxy: bool, + // ssl_sessionid: *mut libc::c_void, + // idsize: size_t, + // sockindex: libc::c_int, + // ) -> CURLcode; + // pub fn Curl_ssl_delsessionid(data: *mut Curl_easy, ssl_sessionid: *mut libc::c_void); + // pub fn Curl_pin_peer_pubkey( + // data: *mut Curl_easy, + // pinnedpubkey: *const libc::c_char, + // pubkey: *const libc::c_uchar, + // pubkeylen: size_t, + // ) -> CURLcode; + // pub fn Curl_tls_keylog_open(); + // pub fn Curl_tls_keylog_close(); + // pub fn Curl_tls_keylog_enabled() -> bool; + // pub fn Curl_tls_keylog_write( + // label: *const libc::c_char, + // client_random: *const libc::c_uchar, + // secret: *const libc::c_uchar, + // secretlen: size_t, + // ) -> bool; + pub fn Curl_parseX509( + cert: *mut Curl_X509certificate, + beg: *const libc::c_char, + end: *const libc::c_char, + ) -> libc::c_int; + pub fn wolfSSL_CTX_set_verify( + _: *mut WOLFSSL_CTX, + _: libc::c_int, + verify_callback: VerifyCallback, + ); + pub fn wolfSSL_CTX_use_PrivateKey_file( + _: *mut WOLFSSL_CTX, + _: *const libc::c_char, + _: libc::c_int, + ) -> libc::c_int; + pub fn wolfSSL_CTX_use_certificate_file( + _: *mut WOLFSSL_CTX, + _: *const libc::c_char, + _: libc::c_int, + ) -> libc::c_int; + pub fn wolfSSL_CTX_load_verify_locations( + _: *mut WOLFSSL_CTX, + _: *const libc::c_char, + _: *const libc::c_char, + ) -> libc::c_int; + pub fn wolfSSL_CTX_set_cipher_list(_: *mut WOLFSSL_CTX, _: *const libc::c_char) -> libc::c_int; + pub fn wolfSSL_CTX_SetMinVersion(ctx: *mut WOLFSSL_CTX, version: libc::c_int) -> libc::c_int; + pub fn wolfSSL_CTX_new(_: *mut WOLFSSL_METHOD) -> *mut WOLFSSL_CTX; + pub fn wolfTLSv1_2_client_method() -> *mut WOLFSSL_METHOD; + pub fn wolfTLSv1_1_client_method() -> *mut WOLFSSL_METHOD; + pub fn wolfSSLv23_client_method() -> *mut WOLFSSL_METHOD; + pub fn wc_FreeRng(_: *mut WC_RNG) -> libc::c_int; + pub fn wc_RNG_GenerateBlock(_: *mut WC_RNG, _: *mut byte, sz: word32) -> libc::c_int; + pub fn wc_InitRng(_: *mut WC_RNG) -> libc::c_int; + pub fn wolfSSL_pending(_: *mut WOLFSSL) -> libc::c_int; + pub fn wolfSSL_lib_version() -> *const libc::c_char; + pub fn wolfSSL_Cleanup() -> libc::c_int; + pub fn wolfSSL_Init() -> libc::c_int; + pub fn wolfSSL_check_domain_name(ssl: *mut WOLFSSL, dn: *const libc::c_char) -> libc::c_int; + pub fn wolfSSL_new(_: *mut WOLFSSL_CTX) -> *mut WOLFSSL; + pub fn wolfSSL_KeepArrays(_: *mut WOLFSSL); + pub fn wolfSSL_set_session(ssl: *mut WOLFSSL, session: *mut WOLFSSL_SESSION) -> libc::c_int; + pub fn wolfSSL_set_fd(_: *mut WOLFSSL, _: libc::c_int) -> libc::c_int; + pub fn wolfSSL_connect(_: *mut WOLFSSL) -> libc::c_int; + pub fn wolfSSL_want_read(_: *mut WOLFSSL) -> libc::c_int; + pub fn wolfSSL_want_write(_: *mut WOLFSSL) -> libc::c_int; + pub fn wolfSSL_GetVersion(ssl: *mut WOLFSSL) -> libc::c_int; + pub fn wolfSSL_get_keys( + _: *mut WOLFSSL, + ms: *mut *mut libc::c_uchar, + msLen: *mut libc::c_uint, + sr: *mut *mut libc::c_uchar, + srLen: *mut libc::c_uint, + cr: *mut *mut libc::c_uchar, + crLen: *mut libc::c_uint, + ) -> libc::c_int; + pub fn wolfSSL_FreeArrays(_: *mut WOLFSSL); + pub fn wolfSSL_get_peer_certificate(ssl: *mut WOLFSSL) -> *mut WOLFSSL_X509; + pub fn wolfSSL_X509_get_der(_: *mut WOLFSSL_X509, _: *mut libc::c_int) -> *const libc::c_uchar; + pub fn wolfSSL_get_version(_: *mut WOLFSSL) -> *const libc::c_char; + pub fn wolfSSL_get_cipher_name(ssl: *mut WOLFSSL) -> *const libc::c_char; + pub fn wolfSSL_get_session(ssl: *mut WOLFSSL) -> *mut WOLFSSL_SESSION; + pub fn wolfSSL_ERR_clear_error(); + pub fn wolfSSL_write(_: *mut WOLFSSL, _: *const libc::c_void, _: libc::c_int) -> libc::c_int; + pub fn wolfSSL_ERR_error_string(_: libc::c_ulong, _: *mut libc::c_char) -> *mut libc::c_char; + pub fn wolfSSL_get_error(_: *mut WOLFSSL, _: libc::c_int) -> libc::c_int; + pub fn wolfSSL_read(_: *mut WOLFSSL, _: *mut libc::c_void, _: libc::c_int) -> libc::c_int; + pub fn wolfSSL_shutdown(_: *mut WOLFSSL) -> libc::c_int; + pub fn wolfSSL_free(_: *mut WOLFSSL); + pub fn wolfSSL_CTX_free(_: *mut WOLFSSL_CTX); + pub fn wc_InitSha256(_: *mut wc_Sha256) -> libc::c_int; + pub fn wc_Sha256Update(_: *mut wc_Sha256, _: *const byte, _: word32) -> libc::c_int; + pub fn wc_Sha256Final(_: *mut wc_Sha256, _: *mut byte) -> libc::c_int; + + // nss.rs + pub fn __xstat( + __ver: libc::c_int, + __filename: *const libc::c_char, + __stat_buf: *mut stat, + ) -> libc::c_int; + pub fn getenv(__name: *const libc::c_char) -> *mut libc::c_char; + pub fn Curl_llist_destroy(_: *mut Curl_llist, _: *mut libc::c_void); + // pub fn Curl_ssl_init_certinfo(data: *mut Curl_easy, num: libc::c_int) -> CURLcode; + // pub fn Curl_pin_peer_pubkey( + // data: *mut Curl_easy, + // pinnedpubkey: *const libc::c_char, + // pubkey: *const libc::c_uchar, + // pubkeylen: size_t, + // ) -> CURLcode; + pub fn PR_ErrorToName(code: PRErrorCode) -> *const libc::c_char; + pub fn PR_GetError() -> PRErrorCode; + pub fn PR_Lock(lock: *mut PRLock); + pub fn PR_ErrorToString(code: PRErrorCode, language: PRLanguageCode) -> *const libc::c_char; + pub fn PR_Now() -> PRTime; + pub fn PR_Free(ptr: *mut libc::c_void); + pub fn PR_FormatTime( + buf: *mut libc::c_char, + buflen: libc::c_int, + fmt: *const libc::c_char, + time: *const PRExplodedTime, + ) -> PRUint32; + pub fn PR_GMTParameters(gmt: *const PRExplodedTime) -> PRTimeParameters; + pub fn PR_ExplodeTime(usecs: PRTime, params: PRTimeParamFn, exploded: *mut PRExplodedTime); + pub fn PR_Unlock(lock: *mut PRLock) -> PRStatus; + pub fn PR_MillisecondsToInterval(milli: PRUint32) -> PRIntervalTime; + pub fn PR_Init(type_0: PRThreadType, priority: PRThreadPriority, maxPTDs: PRUintn); + pub fn PR_SetError(errorCode: PRErrorCode, oserr: PRInt32); + pub fn PR_NewLock() -> *mut PRLock; + pub fn PR_DestroyLock(lock: *mut PRLock); + pub fn PR_SecondsToInterval(seconds: PRUint32) -> PRIntervalTime; + pub fn PR_GetOpenFileInfo(fd: *mut PRFileDesc, info: *mut PRFileInfo) -> PRStatus; + pub fn PR_OpenDir(name: *const libc::c_char) -> *mut PRDir; + pub fn PR_CloseDir(dir: *mut PRDir) -> PRStatus; + pub fn PR_Read(fd: *mut PRFileDesc, buf: *mut libc::c_void, amount: PRInt32) -> PRInt32; + pub fn PR_ReadDir(dir: *mut PRDir, flags: PRDirFlags) -> *mut PRDirEntry; + pub fn PR_GetDefaultIOMethods() -> *const PRIOMethods; + pub fn PR_Close(fd: *mut PRFileDesc) -> PRStatus; + pub fn PR_PushIOLayer( + fd_stack: *mut PRFileDesc, + id: PRDescIdentity, + layer: *mut PRFileDesc, + ) -> PRStatus; + pub fn PR_CreateIOLayerStub( + ident: PRDescIdentity, + methods: *const PRIOMethods, + ) -> *mut PRFileDesc; + pub fn PR_GetUniqueIdentity(layer_name: *const libc::c_char) -> PRDescIdentity; + pub fn PR_Open(name: *const libc::c_char, flags: PRIntn, mode: PRIntn) -> *mut PRFileDesc; + pub fn PR_NewTCPSocket() -> *mut PRFileDesc; + pub fn PR_Recv( + fd: *mut PRFileDesc, + buf: *mut libc::c_void, + amount: PRInt32, + flags: PRIntn, + timeout: PRIntervalTime, + ) -> PRInt32; + pub fn PR_Send( + fd: *mut PRFileDesc, + buf: *const libc::c_void, + amount: PRInt32, + flags: PRIntn, + timeout: PRIntervalTime, + ) -> PRInt32; + pub fn PR_SetSocketOption(fd: *mut PRFileDesc, data: *const PRSocketOptionData) -> PRStatus; + pub fn NSS_ShutdownContext(_: *mut NSSInitContext) -> SECStatus; + pub fn NSS_GetVersion() -> *const libc::c_char; + pub fn PORT_Strdup(s: *const libc::c_char) -> *mut libc::c_char; + pub fn NSS_InitContext( + configdir: *const libc::c_char, + certPrefix: *const libc::c_char, + keyPrefix: *const libc::c_char, + secmodName: *const libc::c_char, + initParams: *mut NSSInitParameters, + flags: PRUint32, + ) -> *mut NSSInitContext; + pub fn SSL_VersionRangeGetDefault( + protocolVariant: SSLProtocolVariant, + vrange: *mut SSLVersionRange, + ) -> SECStatus; + pub fn SSL_VersionRangeGetSupported( + protocolVariant: SSLProtocolVariant, + vrange: *mut SSLVersionRange, + ) -> SECStatus; + pub fn SSL_VersionRangeSet(fd: *mut PRFileDesc, vrange: *const SSLVersionRange) -> SECStatus; + pub fn SSL_GetNumImplementedCiphers() -> PRUint16; + pub fn SSL_GetImplementedCiphers() -> *const PRUint16; + pub fn SSL_CipherPrefSet(fd: *mut PRFileDesc, cipher: PRInt32, enabled: PRBool) -> SECStatus; + pub fn SSL_AuthCertificateHook( + fd: *mut PRFileDesc, + f: SSLAuthCertificate, + arg: *mut libc::c_void, + ) -> SECStatus; + pub fn SSL_PeerStapledOCSPResponses(fd: *mut PRFileDesc) -> *const SECItemArray; + pub fn SSL_AuthCertificate( + arg: *mut libc::c_void, + fd: *mut PRFileDesc, + checkSig: PRBool, + isServer: PRBool, + ) -> SECStatus; + pub fn SSL_BadCertHook( + fd: *mut PRFileDesc, + f: SSLBadCertHandler, + arg: *mut libc::c_void, + ) -> SECStatus; + pub fn SSL_GetNextProto( + fd: *mut PRFileDesc, + state: *mut SSLNextProtoState, + buf: *mut libc::c_uchar, + bufLen: *mut libc::c_uint, + bufLenMax: libc::c_uint, + ) -> SECStatus; + pub fn SECITEM_AllocItem( + arena: *mut PLArenaPool, + item: *mut SECItem, + len: libc::c_uint, + ) -> *mut SECItem; + pub fn CERT_CacheCRL(dbhandle: *mut CERTCertDBHandle, newcrl: *mut SECItem) -> SECStatus; + pub fn CERT_UncacheCRL(dbhandle: *mut CERTCertDBHandle, oldcrl: *mut SECItem) -> SECStatus; + pub fn CERT_GetDefaultCertDB() -> *mut CERTCertDBHandle; + pub fn SSL_ClearSessionCache(); + pub fn SSL_GetClientAuthDataHook( + fd: *mut PRFileDesc, + f: SSLGetClientAuthData, + a: *mut libc::c_void, + ) -> SECStatus; + pub fn SSL_SetSockPeerID(fd: *mut PRFileDesc, peerID: *const libc::c_char) -> SECStatus; + pub fn NSS_GetClientAuthData( + arg: *mut libc::c_void, + socket: *mut PRFileDesc, + caNames: *mut CERTDistNamesStr, + pRetCert: *mut *mut CERTCertificateStr, + pRetKey: *mut *mut SECKEYPrivateKeyStr, + ) -> SECStatus; + pub fn SSL_ImportFD(model: *mut PRFileDesc, fd: *mut PRFileDesc) -> *mut PRFileDesc; + pub fn SSL_SetPKCS11PinArg(fd: *mut PRFileDesc, a: *mut libc::c_void) -> SECStatus; + pub fn SSL_OptionSet(fd: *mut PRFileDesc, option: PRInt32, val: PRIntn) -> SECStatus; + pub fn SSL_SetCanFalseStartCallback( + fd: *mut PRFileDesc, + callback: SSLCanFalseStartCallback, + arg: *mut libc::c_void, + ) -> SECStatus; + pub fn SSL_HandshakeNegotiatedExtension( + socket: *mut PRFileDesc, + extId: SSLExtensionType, + yes: *mut PRBool, + ) -> SECStatus; + pub fn SSL_SetNextProtoNego( + fd: *mut PRFileDesc, + data: *const libc::c_uchar, + length: libc::c_uint, + ) -> SECStatus; + pub fn SSL_ResetHandshake(fd: *mut PRFileDesc, asServer: PRBool) -> SECStatus; + pub fn SSL_SetURL(fd: *mut PRFileDesc, url: *const libc::c_char) -> SECStatus; + pub fn SSL_ForceHandshakeWithTimeout(fd: *mut PRFileDesc, timeout: PRIntervalTime) + -> SECStatus; + pub fn SSL_GetChannelInfo( + fd: *mut PRFileDesc, + info: *mut SSLChannelInfo, + len: PRUintn, + ) -> SECStatus; + pub fn SSL_GetCipherSuiteInfo( + cipherSuite: PRUint16, + info: *mut SSLCipherSuiteInfo, + len: PRUintn, + ) -> SECStatus; + pub fn CERT_NameToAscii(name: *mut CERTName) -> *mut libc::c_char; + pub fn CERT_GetCommonName(name: *const CERTName) -> *mut libc::c_char; + pub fn CERT_GetCertTimes( + c: *const CERTCertificate, + notBefore: *mut PRTime, + notAfter: *mut PRTime, + ) -> SECStatus; + pub fn CERT_FindCertIssuer( + cert: *mut CERTCertificate, + validTime: PRTime, + usage: SECCertUsage, + ) -> *mut CERTCertificate; + pub fn SSL_RevealPinArg(socket: *mut PRFileDesc) -> *mut libc::c_void; + pub fn SECITEM_CompareItem(a: *const SECItem, b: *const SECItem) -> SECComparison; + pub fn SSL_PeerCertificate(fd: *mut PRFileDesc) -> *mut CERTCertificate; + pub fn SECKEY_DestroyPublicKey(key: *mut SECKEYPublicKey); + pub fn CERT_ExtractPublicKey(cert: *mut CERTCertificate) -> *mut SECKEYPublicKey; + pub fn CERT_DestroyCertificate(cert: *mut CERTCertificate); + pub fn SSL_InvalidateSession(fd: *mut PRFileDesc) -> SECStatus; + pub fn SECITEM_FreeItem(zap: *mut SECItem, freeit: PRBool); + pub fn SSL_CipherPolicyGet(cipher: PRInt32, policy: *mut PRInt32) -> SECStatus; + pub fn NSS_SetDomesticPolicy() -> SECStatus; + pub fn SSL_HandshakeCallback( + fd: *mut PRFileDesc, + cb: SSLHandshakeCallback, + client_data: *mut libc::c_void, + ) -> SECStatus; + pub fn SECMOD_LoadUserModule( + moduleSpec: *mut libc::c_char, + parent: *mut SECMODModule, + recurse: PRBool, + ) -> *mut SECMODModule; + pub fn SECMOD_UnloadUserModule(mod_0: *mut SECMODModule) -> SECStatus; + pub fn SECMOD_DestroyModule(module: *mut SECMODModule); + pub fn SECMOD_WaitForAnyTokenEvent( + mod_0: *mut SECMODModule, + flags: libc::c_ulong, + latency: PRIntervalTime, + ) -> *mut PK11SlotInfo; + pub fn PK11_FreeSlot(slot: *mut PK11SlotInfo); + pub fn PK11_SetPasswordFunc(func: PK11PasswordFunc); + pub fn PK11_Authenticate( + slot: *mut PK11SlotInfo, + loadCerts: PRBool, + wincx: *mut libc::c_void, + ) -> SECStatus; + pub fn PK11_FindSlotByName(name: *const libc::c_char) -> *mut PK11SlotInfo; + pub fn PK11_IsPresent(slot: *mut PK11SlotInfo) -> PRBool; + pub fn PK11_GenerateRandom(data: *mut libc::c_uchar, len: libc::c_int) -> SECStatus; + pub fn PK11_FindPrivateKeyFromCert( + slot: *mut PK11SlotInfo, + cert: *mut CERTCertificate, + wincx: *mut libc::c_void, + ) -> *mut SECKEYPrivateKey; + pub fn PK11_DEREncodePublicKey(pubk: *const SECKEYPublicKey) -> *mut SECItem; + pub fn PK11_FindCertFromNickname( + nickname: *const libc::c_char, + wincx: *mut libc::c_void, + ) -> *mut CERTCertificate; + pub fn PK11_FindCertFromDERCertItem( + slot: *mut PK11SlotInfo, + derCert: *const SECItem, + wincx: *mut libc::c_void, + ) -> *mut CERTCertificate; + pub fn PK11_DestroyContext(context: *mut PK11Context, freeit: PRBool); + pub fn PK11_CreateDigestContext(hashAlg: SECOidTag) -> *mut PK11Context; + pub fn PK11_DigestOp( + context: *mut PK11Context, + in_0: *const libc::c_uchar, + len: libc::c_uint, + ) -> SECStatus; + pub fn PK11_DigestFinal( + context: *mut PK11Context, + data: *mut libc::c_uchar, + outLen: *mut libc::c_uint, + length: libc::c_uint, + ) -> SECStatus; + pub fn PK11_ReadRawAttribute( + type_0: PK11ObjectType, + object: *mut libc::c_void, + attr: CK_ATTRIBUTE_TYPE, + item: *mut SECItem, + ) -> SECStatus; + pub fn PK11_DestroyGenericObject(object: *mut PK11GenericObject) -> SECStatus; + pub fn PK11_CreateManagedGenericObject( + slot: *mut PK11SlotInfo, + pTemplate: *const CK_ATTRIBUTE, + count: libc::c_int, + token: PRBool, + ) -> *mut PK11GenericObject; + pub fn SEC_FindCrlByDERCert( + handle: *mut CERTCertDBHandle, + derCrl: *mut SECItem, + type_0: libc::c_int, + ) -> *mut CERTSignedCrl; + pub fn SEC_DestroyCrl(crl: *mut CERTSignedCrl) -> SECStatus; + pub fn ATOB_ConvertAsciiToItem( + binary_item: *mut SECItem, + ascii: *const libc::c_char, + ) -> SECStatus; + pub fn PR_ImportTCPSocket(osfd: PROsfd) -> *mut PRFileDesc; + pub fn CERT_CacheOCSPResponseFromSideChannel( + handle: *mut CERTCertDBHandle, + cert: *mut CERTCertificate, + time: PRTime, + encodedResponse: *const SECItem, + pwArg: *mut libc::c_void, + ) -> SECStatus; + pub fn curlx_uztosi(uznum: size_t) -> libc::c_int; + pub fn curlx_uztoui(uznum: size_t) -> libc::c_uint; + pub fn strpbrk(_: *const libc::c_char, _: *const libc::c_char) -> *mut libc::c_char; + pub fn Curl_llist_init(_: *mut Curl_llist, _: Curl_llist_dtor); + // rustls.rs + pub fn rustls_client_config_builder_dangerous_set_certificate_verifier( + config: *mut rustls_client_config_builder, + callback: rustls_verify_server_cert_callback, + ); + pub fn rustls_client_config_builder_load_roots_from_file( + config: *mut rustls_client_config_builder, + filename: *const libc::c_char, + ) -> rustls_result; + pub fn rustls_client_config_builder_set_protocols( + builder: *mut rustls_client_config_builder, + protocols: *const rustls_slice_bytes, + len: size_t, + ) -> rustls_result; + pub fn rustls_client_config_builder_set_enable_sni( + config: *mut rustls_client_config_builder, + enable: bool, + ); + pub fn rustls_client_config_free(config: *const rustls_client_config); + pub fn rustls_client_connection_new( + config: *const rustls_client_config, + hostname: *const libc::c_char, + conn_out: *mut *mut rustls_connection, + ) -> rustls_result; + pub fn rustls_connection_set_userdata( + conn: *mut rustls_connection, + userdata: *mut libc::c_void, + ); + pub fn rustls_connection_read_tls( + conn: *mut rustls_connection, + callback: rustls_read_callback, + userdata: *mut libc::c_void, + out_n: *mut size_t, + ) -> rustls_io_result; + pub fn rustls_connection_write_tls( + conn: *mut rustls_connection, + callback: rustls_write_callback, + userdata: *mut libc::c_void, + out_n: *mut size_t, + ) -> rustls_io_result; + pub fn rustls_connection_process_new_packets(conn: *mut rustls_connection) -> rustls_result; + pub fn rustls_connection_wants_read(conn: *const rustls_connection) -> bool; + pub fn rustls_connection_wants_write(conn: *const rustls_connection) -> bool; + pub fn rustls_connection_is_handshaking(conn: *const rustls_connection) -> bool; + pub fn rustls_version(buf: *mut libc::c_char, len: size_t) -> size_t; + pub fn rustls_connection_send_close_notify(conn: *mut rustls_connection); + pub fn rustls_connection_get_alpn_protocol( + conn: *const rustls_connection, + protocol_out: *mut *const uint8_t, + protocol_out_len: *mut size_t, + ); + pub fn rustls_connection_write( + conn: *mut rustls_connection, + buf: *const uint8_t, + count: size_t, + out_n: *mut size_t, + ) -> rustls_result; + pub fn rustls_connection_read( + conn: *mut rustls_connection, + buf: *mut uint8_t, + count: size_t, + out_n: *mut size_t, + ) -> rustls_result; + pub fn rustls_connection_free(conn: *mut rustls_connection); + pub fn rustls_error( + result: rustls_result, + buf: *mut libc::c_char, + len: size_t, + out_n: *mut size_t, + ); + pub fn rustls_result_is_cert_error(result: rustls_result) -> bool; + pub fn rustls_client_config_builder_build( + builder: *mut rustls_client_config_builder, + ) -> *const rustls_client_config; + pub fn rustls_client_config_builder_new() -> *mut rustls_client_config_builder; + // pub fn Curl_none_init() -> libc::c_int; + // pub fn Curl_none_cleanup(); + // pub fn Curl_none_check_cxn(conn: *mut connectdata) -> libc::c_int; + // pub fn Curl_none_random( + // data: *mut Curl_easy, + // entropy: *mut libc::c_uchar, + // length: size_t, + // ) -> CURLcode; + // pub fn Curl_none_close_all(data: *mut Curl_easy); + // pub fn Curl_none_session_free(ptr: *mut libc::c_void); + // pub fn Curl_none_cert_status_request() -> bool; + // pub fn Curl_none_set_engine( + // data: *mut Curl_easy, + // engine: *const libc::c_char, + // ) -> CURLcode; + // pub fn Curl_none_set_engine_default(data: *mut Curl_easy) -> CURLcode; + // pub fn Curl_none_engines_list(data: *mut Curl_easy) -> *mut curl_slist; + // pub fn Curl_none_false_start() -> bool; + + // mesalink.rs + pub fn mesalink_SSL_CTX_use_PrivateKey_file( + _: *mut MESALINK_CTX, + _: *const libc::c_char, + _: libc::c_int, + ) -> libc::c_int; + pub fn mesalink_library_init() -> libc::c_int; + pub fn mesalink_TLSv1_2_client_method() -> *mut MESALINK_METHOD; + pub fn mesalink_TLSv1_3_client_method() -> *mut MESALINK_METHOD; + pub fn mesalink_SSL_CTX_new(_: *mut MESALINK_METHOD) -> *mut MESALINK_CTX; + pub fn mesalink_SSL_CTX_load_verify_locations( + _: *mut MESALINK_CTX, + _: *const libc::c_char, + _: *const libc::c_char, + ) -> libc::c_int; + pub fn mesalink_SSL_CTX_use_certificate_chain_file( + _: *mut MESALINK_CTX, + _: *const libc::c_char, + _: libc::c_int, + ) -> libc::c_int; + pub fn mesalink_SSL_CTX_set_verify( + _: *mut MESALINK_CTX, + _: libc::c_int, + cb: Option libc::c_int>, + ) -> libc::c_int; + pub fn mesalink_SSL_new(_: *mut MESALINK_CTX) -> *mut MESALINK_SSL; + pub fn mesalink_SSL_set_tlsext_host_name( + _: *mut MESALINK_SSL, + _: *const libc::c_char, + ) -> libc::c_int; + pub fn mesalink_SSL_set_fd(_: *mut MESALINK_SSL, _: libc::c_int) -> libc::c_int; + pub fn mesalink_SSL_CTX_free(_: *mut MESALINK_CTX); + pub fn mesalink_SSL_connect(_: *mut MESALINK_SSL) -> libc::c_int; + pub fn mesalink_SSL_write( + _: *mut MESALINK_SSL, + _: *const libc::c_void, + _: libc::c_int, + ) -> libc::c_int; + pub fn mesalink_SSL_get_cipher_name(_: *mut MESALINK_SSL) -> *const libc::c_char; + pub fn mesalink_SSL_read( + _: *mut MESALINK_SSL, + _: *mut libc::c_void, + _: libc::c_int, + ) -> libc::c_int; + pub fn mesalink_SSL_shutdown(_: *mut MESALINK_SSL) -> libc::c_int; + pub fn mesalink_SSL_get_version(_: *const MESALINK_SSL) -> *const libc::c_char; + pub fn mesalink_SSL_free(_: *mut MESALINK_SSL); + pub fn mesalink_SSL_get_error(_: *const MESALINK_SSL, _: libc::c_int) -> libc::c_int; + pub fn mesalink_ERR_error_string_n( + e: libc::c_ulong, + buf: *mut libc::c_char, + len: size_t, + ) -> *const libc::c_char; + pub fn mesalink_ERR_print_errors_fp(_: *const FILE); + // openssl.rs + pub fn Curl_wait_ms(timeout_ms: timediff_t) -> libc::c_int; + // pub fn Curl_none_false_start() -> bool; + pub fn curl_slist_append(_: *mut curl_slist, _: *const libc::c_char) -> *mut curl_slist; + // pub fn Curl_ssl_push_certinfo_len( + // data: *mut Curl_easy, + // certnum: libc::c_int, + // label: *const libc::c_char, + // value: *const libc::c_char, + // valuelen: size_t, + // ) -> CURLcode; + // pub fn Curl_ssl_sessionid_lock(data: *mut Curl_easy); + // pub fn Curl_ssl_sessionid_unlock(data: *mut Curl_easy); + // pub fn Curl_ssl_getsessionid( + // data: *mut Curl_easy, + // conn: *mut connectdata, + // isProxy: bool, + // ssl_sessionid: *mut *mut libc::c_void, + // idsize: *mut size_t, + // sockindex: libc::c_int, + // ) -> bool; + // pub fn Curl_ssl_addsessionid( + // data: *mut Curl_easy, + // conn: *mut connectdata, + // isProxy: bool, + // ssl_sessionid: *mut libc::c_void, + // idsize: size_t, + // sockindex: libc::c_int, + // ) -> CURLcode; + // pub fn Curl_ssl_delsessionid(data: *mut Curl_easy, ssl_sessionid: *mut libc::c_void); + pub fn Curl_cert_hostcheck( + match_pattern: *const libc::c_char, + hostname: *const libc::c_char, + ) -> libc::c_int; + pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX; + pub fn EVP_MD_CTX_free(ctx: *mut EVP_MD_CTX); + pub fn EVP_DigestUpdate( + ctx: *mut EVP_MD_CTX, + d: *const libc::c_void, + cnt: size_t, + ) -> libc::c_int; + pub fn EVP_DigestFinal_ex( + ctx: *mut EVP_MD_CTX, + md: *mut libc::c_uchar, + s: *mut libc::c_uint, + ) -> libc::c_int; + pub fn EVP_DigestInit(ctx: *mut EVP_MD_CTX, type_0: *const EVP_MD) -> libc::c_int; + pub fn EVP_sha1() -> *const EVP_MD; + pub fn EVP_sha256() -> *const EVP_MD; + pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> libc::c_int; + pub fn EVP_PKEY_get0_RSA(pkey: *mut EVP_PKEY) -> *mut rsa_st; + pub fn EVP_PKEY_get1_RSA(pkey: *mut EVP_PKEY) -> *mut rsa_st; + pub fn EVP_PKEY_get0_DSA(pkey: *mut EVP_PKEY) -> *mut dsa_st; + pub fn EVP_PKEY_get0_DH(pkey: *mut EVP_PKEY) -> *mut dh_st; + pub fn EVP_PKEY_free(pkey: *mut EVP_PKEY); + pub fn EVP_PKEY_copy_parameters(to: *mut EVP_PKEY, from: *const EVP_PKEY) -> libc::c_int; + pub fn OPENSSL_init_ssl(opts: uint64_t, settings: *const OPENSSL_INIT_SETTINGS) -> libc::c_int; + pub fn SSL_get_shutdown(ssl: *const SSL) -> libc::c_int; + pub fn SSL_pending(s: *const SSL) -> libc::c_int; + pub fn TLS_client_method() -> *const SSL_METHOD; + pub fn SSL_CTX_new(meth: *const SSL_METHOD) -> *mut SSL_CTX; + pub fn SSL_CTX_set_msg_callback( + ctx: *mut SSL_CTX, + cb: Option< + unsafe extern "C" fn( + libc::c_int, + libc::c_int, + libc::c_int, + *const libc::c_void, + size_t, + *mut SSL, + *mut libc::c_void, + ) -> (), + >, + ); + pub fn SSL_alert_desc_string_long(value: libc::c_int) -> *const libc::c_char; + pub fn SSL_CTX_set_options(ctx: *mut SSL_CTX, op: libc::c_ulong) -> libc::c_ulong; + pub fn SSL_CTX_set_next_proto_select_cb( + s: *mut SSL_CTX, + cb: SSL_CTX_npn_select_cb_func, + arg: *mut libc::c_void, + ); + pub fn SSL_CTX_set_alpn_protos( + ctx: *mut SSL_CTX, + protos: *const libc::c_uchar, + protos_len: libc::c_uint, + ) -> libc::c_int; + pub fn SSL_CTX_set_default_passwd_cb_userdata(ctx: *mut SSL_CTX, u: *mut libc::c_void); + pub fn SSL_CTX_set_default_passwd_cb(ctx: *mut SSL_CTX, cb: Option); + pub fn PEM_read_bio_X509_AUX( + bp: *mut BIO, + x: *mut *mut X509, + cb: Option, + u: *mut libc::c_void, + ) -> *mut X509; + pub fn SSL_CTX_use_certificate_chain_file( + ctx: *mut SSL_CTX, + file: *const libc::c_char, + ) -> libc::c_int; + pub fn d2i_X509_bio(bp: *mut BIO, x509: *mut *mut X509) -> *mut X509; + pub fn SSL_CTX_use_certificate_file( + ctx: *mut SSL_CTX, + file: *const libc::c_char, + type_0: libc::c_int, + ) -> libc::c_int; + pub fn SSL_CTX_use_certificate(ctx: *mut SSL_CTX, x: *mut X509) -> libc::c_int; + pub fn SSL_CTX_add_client_CA(ctx: *mut SSL_CTX, x: *mut X509) -> libc::c_int; + pub fn OPENSSL_sk_pop(st: *mut OPENSSL_STACK) -> *mut libc::c_void; + pub fn PEM_read_bio_PrivateKey( + bp: *mut BIO, + x: *mut *mut EVP_PKEY, + cb: Option, + u: *mut libc::c_void, + ) -> *mut EVP_PKEY; + pub fn d2i_PrivateKey_bio(bp: *mut BIO, a: *mut *mut EVP_PKEY) -> *mut EVP_PKEY; + pub fn SSL_CTX_use_PrivateKey_file( + ctx: *mut SSL_CTX, + file: *const libc::c_char, + type_0: libc::c_int, + ) -> libc::c_int; + pub fn SSL_CTX_use_PrivateKey(ctx: *mut SSL_CTX, pkey: *mut EVP_PKEY) -> libc::c_int; + pub fn SSL_get_certificate(ssl: *const SSL) -> *mut X509; + pub fn RSA_flags(r: *const RSA) -> libc::c_int; + pub fn RSA_free(r: *mut RSA); + pub fn SSL_get_privatekey(ssl: *const SSL) -> *mut evp_pkey_st; + pub fn SSL_CTX_check_private_key(ctx: *const SSL_CTX) -> libc::c_int; + pub fn SSL_CTX_set_ciphersuites(ctx: *mut SSL_CTX, str: *const libc::c_char) -> libc::c_int; + pub fn SSL_CTX_set_post_handshake_auth(ctx: *mut SSL_CTX, val: libc::c_int); + pub fn SSL_CTX_set_srp_username(ctx: *mut SSL_CTX, name: *mut libc::c_char) -> libc::c_int; + pub fn SSL_CTX_set_srp_password(ctx: *mut SSL_CTX, password: *mut libc::c_char) -> libc::c_int; + pub fn SSL_CTX_set_cipher_list(_: *mut SSL_CTX, str: *const libc::c_char) -> libc::c_int; + pub fn PEM_X509_INFO_read_bio( + bp: *mut BIO, + sk: *mut stack_st_X509_INFO, + cb: Option, + u: *mut libc::c_void, + ) -> *mut stack_st_X509_INFO; + pub fn X509_STORE_add_cert(ctx: *mut X509_STORE, x: *mut X509) -> libc::c_int; + pub fn X509_STORE_add_crl(ctx: *mut X509_STORE, x: *mut X509_CRL) -> libc::c_int; + pub fn OPENSSL_sk_pop_free( + st: *mut OPENSSL_STACK, + func: Option ()>, + ); + pub fn X509_INFO_free(a: *mut X509_INFO); + pub fn SSL_CTX_load_verify_locations( + ctx: *mut SSL_CTX, + CAfile: *const libc::c_char, + CApath: *const libc::c_char, + ) -> libc::c_int; + pub fn X509_STORE_add_lookup( + v: *mut X509_STORE, + m: *mut X509_LOOKUP_METHOD, + ) -> *mut X509_LOOKUP; + pub fn X509_LOOKUP_file() -> *mut X509_LOOKUP_METHOD; + pub fn X509_load_crl_file( + ctx: *mut X509_LOOKUP, + file: *const libc::c_char, + type_0: libc::c_int, + ) -> libc::c_int; + pub fn X509_STORE_set_flags(ctx: *mut X509_STORE, flags: libc::c_ulong) -> libc::c_int; + pub fn SSL_CTX_set_verify(ctx: *mut SSL_CTX, mode: libc::c_int, callback: SSL_verify_cb); + pub fn SSL_CTX_set_keylog_callback(ctx: *mut SSL_CTX, cb: SSL_CTX_keylog_cb_func); + pub fn SSL_CTX_ctrl( + ctx: *mut SSL_CTX, + cmd: libc::c_int, + larg: libc::c_long, + parg: *mut libc::c_void, + ) -> libc::c_long; + pub fn SSL_CTX_sess_set_new_cb( + ctx: *mut SSL_CTX, + new_session_cb: Option libc::c_int>, + ); + pub fn SSL_get_ex_data(ssl: *const SSL, idx: libc::c_int) -> *mut libc::c_void; + pub fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL; + pub fn SSL_set_session(to: *mut SSL, session: *mut SSL_SESSION) -> libc::c_int; + pub fn SSL_set_bio(s: *mut SSL, rbio: *mut BIO, wbio: *mut BIO); + pub fn BIO_f_ssl() -> *const BIO_METHOD; + pub fn SSL_set_fd(s: *mut SSL, fd: libc::c_int) -> libc::c_int; + pub fn SSL_connect(ssl: *mut SSL) -> libc::c_int; + pub fn X509_get0_extensions(x: *const X509) -> *const stack_st_X509_EXTENSION; + pub fn SSL_get_version(s: *const SSL) -> *const libc::c_char; + pub fn SSL_CIPHER_get_name(c: *const SSL_CIPHER) -> *const libc::c_char; + pub fn SSL_get_current_cipher(s: *const SSL) -> *const SSL_CIPHER; + pub fn SSL_get0_alpn_selected( + ssl: *const SSL, + data: *mut *const libc::c_uchar, + len: *mut libc::c_uint, + ); + pub fn X509_get_version(x: *const X509) -> libc::c_long; + pub fn X509_get_serialNumber(x: *mut X509) -> *mut ASN1_INTEGER; + pub fn BIO_puts(bp: *mut BIO, buf: *const libc::c_char) -> libc::c_int; + pub fn X509_get0_signature( + psig: *mut *const ASN1_BIT_STRING, + palg: *mut *const X509_ALGOR, + x: *const X509, + ); + pub fn X509_PUBKEY_get0_param( + ppkalg: *mut *mut ASN1_OBJECT, + pk: *mut *const libc::c_uchar, + ppklen: *mut libc::c_int, + pa: *mut *mut X509_ALGOR, + pub_0: *mut X509_PUBKEY, + ) -> libc::c_int; + pub fn i2a_ASN1_OBJECT(bp: *mut BIO, a: *const ASN1_OBJECT) -> libc::c_int; + pub fn X509_EXTENSION_get_object(ex: *mut X509_EXTENSION) -> *mut ASN1_OBJECT; + pub fn i2t_ASN1_OBJECT( + buf: *mut libc::c_char, + buf_len: libc::c_int, + a: *const ASN1_OBJECT, + ) -> libc::c_int; + pub fn ASN1_STRING_print(bp: *mut BIO, v: *const ASN1_STRING) -> libc::c_int; + pub fn X509_EXTENSION_get_data(ne: *mut X509_EXTENSION) -> *mut ASN1_OCTET_STRING; + pub fn X509_get_pubkey(x: *mut X509) -> *mut EVP_PKEY; + pub fn RSA_get0_key( + r: *const RSA, + n: *mut *const BIGNUM, + e: *mut *const BIGNUM, + d: *mut *const BIGNUM, + ); + pub fn BN_num_bits(a: *const BIGNUM) -> libc::c_int; + pub fn DSA_get0_pqg( + d: *const DSA, + p: *mut *const BIGNUM, + q: *mut *const BIGNUM, + g: *mut *const BIGNUM, + ); + pub fn DSA_get0_key(d: *const DSA, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM); + pub fn DH_get0_pqg( + dh: *const DH, + p: *mut *const BIGNUM, + q: *mut *const BIGNUM, + g: *mut *const BIGNUM, + ); + pub fn DH_get0_key(dh: *const DH, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM); + pub fn BN_print(bio: *mut BIO, a: *const BIGNUM) -> libc::c_int; + pub fn BIO_printf(bio: *mut BIO, format: *const libc::c_char, _: ...) -> libc::c_int; + pub fn PEM_write_bio_X509(bp: *mut BIO, x: *mut X509) -> libc::c_int; + pub fn X509_get0_notBefore(x: *const X509) -> *const ASN1_TIME; + pub fn ASN1_TIME_print(fp: *mut BIO, a: *const ASN1_TIME) -> libc::c_int; + pub fn X509_get0_notAfter(x: *const X509) -> *const ASN1_TIME; + pub fn X509_get_ext_d2i( + x: *const X509, + nid: libc::c_int, + crit: *mut libc::c_int, + idx: *mut libc::c_int, + ) -> *mut libc::c_void; + pub fn X509_NAME_get_index_by_NID( + name: *mut X509_NAME, + nid: libc::c_int, + lastpos: libc::c_int, + ) -> libc::c_int; + pub fn ASN1_STRING_type(x: *const ASN1_STRING) -> libc::c_int; + pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> libc::c_int; + pub fn CRYPTO_malloc( + num: size_t, + file: *const libc::c_char, + line: libc::c_int, + ) -> *mut libc::c_void; + pub fn ASN1_STRING_get0_data(x: *const ASN1_STRING) -> *const libc::c_uchar; + pub fn ASN1_STRING_to_UTF8( + out: *mut *mut libc::c_uchar, + in_0: *const ASN1_STRING, + ) -> libc::c_int; + pub fn X509_NAME_ENTRY_get_data(ne: *const X509_NAME_ENTRY) -> *mut ASN1_STRING; + pub fn X509_NAME_get_entry(name: *const X509_NAME, loc: libc::c_int) -> *mut X509_NAME_ENTRY; + pub fn X509_get_subject_name(a: *const X509) -> *mut X509_NAME; + pub fn CRYPTO_free(ptr: *mut libc::c_void, file: *const libc::c_char, line: libc::c_int); + pub fn X509_NAME_print_ex( + out: *mut BIO, + nm: *const X509_NAME, + indent: libc::c_int, + flags: libc::c_ulong, + ) -> libc::c_int; + pub fn BIO_s_mem() -> *const BIO_METHOD; + pub fn X509_get_issuer_name(a: *const X509) -> *mut X509_NAME; + pub fn BIO_new_mem_buf(buf: *const libc::c_void, len: libc::c_int) -> *mut BIO; + pub fn BIO_new(type_0: *const BIO_METHOD) -> *mut BIO; + pub fn BIO_s_file() -> *const BIO_METHOD; + pub fn BIO_ctrl( + bp: *mut BIO, + cmd: libc::c_int, + larg: libc::c_long, + parg: *mut libc::c_void, + ) -> libc::c_long; + pub fn PEM_read_bio_X509( + bp: *mut BIO, + x: *mut *mut X509, + cb: Option, + u: *mut libc::c_void, + ) -> *mut X509; + pub fn BIO_free(a: *mut BIO) -> libc::c_int; + pub fn SSL_get_verify_result(ssl: *const SSL) -> libc::c_long; + pub fn X509_verify_cert_error_string(n: libc::c_long) -> *const libc::c_char; + pub fn SSL_ctrl( + ssl: *mut SSL, + cmd: libc::c_int, + larg: libc::c_long, + parg: *mut libc::c_void, + ) -> libc::c_long; + pub fn SSL_get_peer_cert_chain(s: *const SSL) -> *mut stack_st_X509; + pub fn SSL_CTX_get_cert_store(_: *const SSL_CTX) -> *mut X509_STORE; + pub fn SSL_get_peer_certificate(s: *const SSL) -> *mut X509; + pub fn OPENSSL_sk_num(_: *const OPENSSL_STACK) -> libc::c_int; + pub fn OPENSSL_sk_value(_: *const OPENSSL_STACK, _: libc::c_int) -> *mut libc::c_void; + pub fn i2d_X509_PUBKEY(a: *mut X509_PUBKEY, out: *mut *mut libc::c_uchar) -> libc::c_int; + pub fn X509_get_X509_PUBKEY(x: *const X509) -> *mut X509_PUBKEY; + pub fn X509_free(a: *mut X509); + pub fn SSL_write(ssl: *mut SSL, buf: *const libc::c_void, num: libc::c_int) -> libc::c_int; + pub fn SSL_get_error(s: *const SSL, ret_code: libc::c_int) -> libc::c_int; + pub fn OpenSSL_version_num() -> libc::c_ulong; + pub fn SSL_read(ssl: *mut SSL, buf: *mut libc::c_void, num: libc::c_int) -> libc::c_int; + pub fn SSL_shutdown(s: *mut SSL) -> libc::c_int; + pub fn SSL_set_connect_state(s: *mut SSL); + pub fn SSL_free(ssl: *mut SSL); + pub fn SSL_CTX_free(_: *mut SSL_CTX); + pub fn SSL_SESSION_free(ses: *mut SSL_SESSION); + pub fn SSL_set_ex_data(ssl: *mut SSL, idx: libc::c_int, data: *mut libc::c_void) + -> libc::c_int; + pub fn CRYPTO_get_ex_new_index( + class_index: libc::c_int, + argl: libc::c_long, + argp: *mut libc::c_void, + new_func: Option, + dup_func: Option, + free_func: Option, + ) -> libc::c_int; + pub fn RAND_bytes(buf: *mut libc::c_uchar, num: libc::c_int) -> libc::c_int; + pub fn RAND_add(buf: *const libc::c_void, num: libc::c_int, randomness: libc::c_double); + pub fn RAND_load_file(file: *const libc::c_char, max_bytes: libc::c_long) -> libc::c_int; + pub fn RAND_file_name(file: *mut libc::c_char, num: size_t) -> *const libc::c_char; + pub fn RAND_status() -> libc::c_int; + pub fn GENERAL_NAMES_free(a: *mut GENERAL_NAMES); + pub fn X509V3_EXT_print( + out: *mut BIO, + ext: *mut X509_EXTENSION, + flag: libc::c_ulong, + indent: libc::c_int, + ) -> libc::c_int; + pub fn X509_check_issued(issuer: *mut X509, subject: *mut X509) -> libc::c_int; + pub fn ERR_get_error() -> libc::c_ulong; + pub fn ERR_peek_error() -> libc::c_ulong; + pub fn ERR_peek_last_error() -> libc::c_ulong; + pub fn ERR_clear_error(); + pub fn ERR_error_string_n(e: libc::c_ulong, buf: *mut libc::c_char, len: size_t); + pub fn PKCS12_free(a: *mut PKCS12); + pub fn PKCS12_PBE_add(); + pub fn PKCS12_parse( + p12: *mut PKCS12, + pass: *const libc::c_char, + pkey: *mut *mut EVP_PKEY, + cert: *mut *mut X509, + ca: *mut *mut stack_st_X509, + ) -> libc::c_int; + pub fn d2i_PKCS12_bio(bp: *mut BIO, p12: *mut *mut PKCS12) -> *mut PKCS12; + pub fn OCSP_cert_to_id( + dgst: *const EVP_MD, + subject: *const X509, + issuer: *const X509, + ) -> *mut OCSP_CERTID; + pub fn OCSP_response_status(resp: *mut OCSP_RESPONSE) -> libc::c_int; + pub fn OCSP_response_get1_basic(resp: *mut OCSP_RESPONSE) -> *mut OCSP_BASICRESP; + pub fn OCSP_resp_find_status( + bs: *mut OCSP_BASICRESP, + id: *mut OCSP_CERTID, + status: *mut libc::c_int, + reason: *mut libc::c_int, + revtime: *mut *mut ASN1_GENERALIZEDTIME, + thisupd: *mut *mut ASN1_GENERALIZEDTIME, + nextupd: *mut *mut ASN1_GENERALIZEDTIME, + ) -> libc::c_int; + pub fn OCSP_check_validity( + thisupd: *mut ASN1_GENERALIZEDTIME, + nextupd: *mut ASN1_GENERALIZEDTIME, + sec: libc::c_long, + maxsec: libc::c_long, + ) -> libc::c_int; + pub fn OCSP_BASICRESP_free(a: *mut OCSP_BASICRESP); + pub fn OCSP_RESPONSE_free(a: *mut OCSP_RESPONSE); + pub fn d2i_OCSP_RESPONSE( + a: *mut *mut OCSP_RESPONSE, + in_0: *mut *const libc::c_uchar, + len: libc::c_long, + ) -> *mut OCSP_RESPONSE; + pub fn OCSP_CERTID_free(a: *mut OCSP_CERTID); + pub fn OCSP_response_status_str(s: libc::c_long) -> *const libc::c_char; + pub fn OCSP_basic_verify( + bs: *mut OCSP_BASICRESP, + certs: *mut stack_st_X509, + st: *mut X509_STORE, + flags: libc::c_ulong, + ) -> libc::c_int; + pub fn OCSP_cert_status_str(s: libc::c_long) -> *const libc::c_char; + pub fn OCSP_crl_reason_str(s: libc::c_long) -> *const libc::c_char; + pub fn ENGINE_get_first() -> *mut ENGINE; + pub fn ENGINE_get_next(e: *mut ENGINE) -> *mut ENGINE; + pub fn ENGINE_by_id(id: *const libc::c_char) -> *mut ENGINE; + pub fn ENGINE_ctrl( + e: *mut ENGINE, + cmd: libc::c_int, + i: libc::c_long, + p: *mut libc::c_void, + f: Option ()>, + ) -> libc::c_int; + pub fn ENGINE_ctrl_cmd( + e: *mut ENGINE, + cmd_name: *const libc::c_char, + i: libc::c_long, + p: *mut libc::c_void, + f: Option ()>, + cmd_optional: libc::c_int, + ) -> libc::c_int; + pub fn ENGINE_free(e: *mut ENGINE) -> libc::c_int; + pub fn ENGINE_get_id(e: *const ENGINE) -> *const libc::c_char; + pub fn UI_OpenSSL() -> *mut UI_METHOD; + pub fn ENGINE_load_private_key( + e: *mut ENGINE, + key_id: *const libc::c_char, + ui_method: *mut UI_METHOD, + callback_data: *mut libc::c_void, + ) -> *mut EVP_PKEY; + pub fn ENGINE_set_default(e: *mut ENGINE, flags: libc::c_uint) -> libc::c_int; + pub fn ENGINE_init(e: *mut ENGINE) -> libc::c_int; + pub fn ENGINE_finish(e: *mut ENGINE) -> libc::c_int; + pub fn UI_get0_user_data(ui: *mut UI) -> *mut libc::c_void; + pub fn UI_method_set_opener( + method: *mut UI_METHOD, + opener: Option libc::c_int>, + ) -> libc::c_int; + pub fn UI_method_get_opener( + method: *const UI_METHOD, + ) -> Option libc::c_int>; + pub fn UI_method_set_closer( + method: *mut UI_METHOD, + closer: Option libc::c_int>, + ) -> libc::c_int; + pub fn UI_method_get_closer( + method: *const UI_METHOD, + ) -> Option libc::c_int>; + pub fn UI_create_method(name: *const libc::c_char) -> *mut UI_METHOD; + pub fn UI_destroy_method(ui_method: *mut UI_METHOD); + pub fn UI_method_get_writer( + method: *const UI_METHOD, + ) -> Option libc::c_int>; + pub fn UI_method_set_writer( + method: *mut UI_METHOD, + writer: Option libc::c_int>, + ) -> libc::c_int; + pub fn UI_method_get_reader( + method: *const UI_METHOD, + ) -> Option libc::c_int>; + pub fn UI_method_set_reader( + method: *mut UI_METHOD, + reader: Option libc::c_int>, + ) -> libc::c_int; + pub fn UI_set_result( + ui: *mut UI, + uis: *mut UI_STRING, + result: *const libc::c_char, + ) -> libc::c_int; + pub fn UI_get_string_type(uis: *mut UI_STRING) -> UI_string_types; + pub fn UI_get_input_flags(uis: *mut UI_STRING) -> libc::c_int; + + // http_negotiate.rs + pub fn Curl_auth_decode_spnego_message( + data: *mut Curl_easy, + user: *const libc::c_char, + passwood: *const libc::c_char, + service: *const libc::c_char, + host: *const libc::c_char, + chlg64: *const libc::c_char, + nego: *mut negotiatedata, + ) -> CURLcode; + pub fn Curl_auth_create_spnego_message( + data: *mut Curl_easy, + nego: *mut negotiatedata, + outptr: *mut *mut libc::c_char, + outlen: *mut size_t, + ) -> CURLcode; + pub fn Curl_auth_cleanup_spnego(nego: *mut negotiatedata); + // bearssl.rs + pub fn br_ssl_engine_sendapp_ack(cc: *mut br_ssl_engine_context, len: size_t); + pub fn br_ssl_engine_sendapp_buf( + cc: *const br_ssl_engine_context, + len: *mut size_t, + ) -> *mut libc::c_uchar; + pub fn br_ssl_engine_current_state(cc: *const br_ssl_engine_context) -> libc::c_uint; + pub fn br_ssl_engine_set_buffer( + cc: *mut br_ssl_engine_context, + iobuf: *mut libc::c_void, + iobuf_len: size_t, + bidi: libc::c_int, + ); + pub fn br_pem_decoder_event(ctx: *mut br_pem_decoder_context) -> libc::c_int; + pub fn br_pem_decoder_push( + ctx: *mut br_pem_decoder_context, + data: *const libc::c_void, + len: size_t, + ) -> size_t; + pub fn br_pem_decoder_init(ctx: *mut br_pem_decoder_context); + pub fn br_ssl_client_reset( + cc: *mut br_ssl_client_context, + server_name: *const libc::c_char, + resume_session: libc::c_int, + ) -> libc::c_int; + pub fn br_ssl_client_init_full( + cc: *mut br_ssl_client_context, + xc: *mut br_x509_minimal_context, + trust_anchors: *const br_x509_trust_anchor, + trust_anchors_num: size_t, + ); + pub fn br_ssl_engine_close(cc: *mut br_ssl_engine_context); + pub fn br_ssl_engine_flush(cc: *mut br_ssl_engine_context, force: libc::c_int); + pub fn br_ssl_engine_recvrec_ack(cc: *mut br_ssl_engine_context, len: size_t); + pub fn br_ssl_engine_recvrec_buf( + cc: *const br_ssl_engine_context, + len: *mut size_t, + ) -> *mut libc::c_uchar; + pub fn br_ssl_engine_sendrec_ack(cc: *mut br_ssl_engine_context, len: size_t); + pub fn br_ssl_engine_sendrec_buf( + cc: *const br_ssl_engine_context, + len: *mut size_t, + ) -> *mut libc::c_uchar; + pub fn br_ssl_engine_recvapp_ack(cc: *mut br_ssl_engine_context, len: size_t); + pub fn br_sha224_update(ctx: *mut br_sha224_context, data: *const libc::c_void, len: size_t); + pub fn br_sha256_init(ctx: *mut br_sha256_context); + pub fn br_sha256_out(ctx: *const br_sha256_context, out: *mut libc::c_void); + pub fn br_ssl_engine_recvapp_buf( + cc: *const br_ssl_engine_context, + len: *mut size_t, + ) -> *mut libc::c_uchar; + pub fn br_x509_decoder_push( + ctx: *mut br_x509_decoder_context, + data: *const libc::c_void, + len: size_t, + ); + pub fn br_x509_decoder_init( + ctx: *mut br_x509_decoder_context, + append_dn_0: Option< + unsafe extern "C" fn(*mut libc::c_void, *const libc::c_void, size_t) -> (), + >, + append_dn_ctx: *mut libc::c_void, + ); + pub fn br_hmac_drbg_init( + ctx: *mut br_hmac_drbg_context, + digest_class: *const br_hash_class, + seed: *const libc::c_void, + seed_len: size_t, + ); + pub fn br_hmac_drbg_generate( + ctx: *mut br_hmac_drbg_context, + out: *mut libc::c_void, + len: size_t, + ); + pub fn br_prng_seeder_system(name: *mut *const libc::c_char) -> br_prng_seeder; + pub fn ferror(__stream: *mut FILE) -> libc::c_int; + + // option hyper + pub fn hyper_clientconn_handshake( + io: *mut hyper_io, + options: *mut hyper_clientconn_options, + ) -> *mut hyper_task; + pub fn hyper_clientconn_send( + conn: *mut hyper_clientconn, + req: *mut hyper_request, + ) -> *mut hyper_task; + pub fn hyper_clientconn_free(conn: *mut hyper_clientconn); + pub fn hyper_clientconn_options_new() -> *mut hyper_clientconn_options; + pub fn hyper_clientconn_options_free(opts: *mut hyper_clientconn_options); + pub fn hyper_clientconn_options_exec( + opts: *mut hyper_clientconn_options, + exec: *const hyper_executor, + ); + pub fn hyper_error_free(err: *mut hyper_error); + pub fn hyper_error_print(err: *const hyper_error, dst: *mut uint8_t, dst_len: size_t) + -> size_t; + pub fn hyper_request_new() -> *mut hyper_request; + pub fn hyper_request_set_method( + req: *mut hyper_request, + method: *const uint8_t, + method_len: size_t, + ) -> hyper_code; + pub fn hyper_request_set_uri( + req: *mut hyper_request, + uri: *const uint8_t, + uri_len: size_t, + ) -> hyper_code; + pub fn hyper_request_set_version(req: *mut hyper_request, version: libc::c_int) -> hyper_code; + pub fn hyper_request_headers(req: *mut hyper_request) -> *mut hyper_headers; + pub fn hyper_io_new() -> *mut hyper_io; + pub fn hyper_io_free(io: *mut hyper_io); + pub fn hyper_io_set_userdata(io: *mut hyper_io, data: *mut libc::c_void); + pub fn hyper_io_set_read(io: *mut hyper_io, func: hyper_io_read_callback); + pub fn hyper_io_set_write(io: *mut hyper_io, func: hyper_io_write_callback); + pub fn hyper_executor_new() -> *const hyper_executor; + pub fn hyper_executor_free(exec: *const hyper_executor); + pub fn hyper_executor_push(exec: *const hyper_executor, task: *mut hyper_task) -> hyper_code; + pub fn hyper_executor_poll(exec: *const hyper_executor) -> *mut hyper_task; + pub fn hyper_task_free(task: *mut hyper_task); + pub fn hyper_task_value(task: *mut hyper_task) -> *mut libc::c_void; + pub fn hyper_task_type(task: *mut hyper_task) -> hyper_task_return_type; + pub fn hyper_waker_free(waker: *mut hyper_waker); + pub fn Curl_hyper_recv( + userp: *mut libc::c_void, + ctx: *mut hyper_context, + buf: *mut uint8_t, + buflen: size_t, + ) -> size_t; + pub fn Curl_hyper_send( + userp: *mut libc::c_void, + ctx: *mut hyper_context, + buf: *const uint8_t, + buflen: size_t, + ) -> size_t; + pub fn Curl_hyper_stream( + data: *mut Curl_easy, + conn: *mut connectdata, + didwhat: *mut libc::c_int, + done: *mut bool, + select_res: libc::c_int, + ) -> CURLcode; + pub fn Curl_hyper_header( + data: *mut Curl_easy, + headers: *mut hyper_headers, + line: *const libc::c_char, + ) -> CURLcode; + pub fn Curl_hyper_done(_: *mut Curl_easy); + + // in http.rs, remove in future + #[cfg(USE_HYPER)] + pub fn Curl_add_custom_headers( + data: *mut Curl_easy, + is_connect: bool, + headers: *mut libc::c_void, + ) -> CURLcode; + + // http.rs function without hyper + #[cfg(not(USE_HYPER))] + pub fn Curl_add_custom_headers( + data: *mut Curl_easy, + is_connect: bool, + req: *mut dynbuf, + ) -> CURLcode; + + // ftp + pub fn htons(__hostshort: uint16_t) -> uint16_t; + pub fn ntohs(__netshort: uint16_t) -> uint16_t; + + //debug + pub fn __assert_fail( + __assertion: *const libc::c_char, + __file: *const libc::c_char, + __line: libc::c_uint, + __function: *const libc::c_char, + ) -> !; + pub fn curl_dbg_free(ptr: *mut libc::c_void, line: libc::c_int, source: *const libc::c_char); + pub fn curl_dbg_strdup( + str: *const libc::c_char, + line: libc::c_int, + src: *const libc::c_char, + ) -> *mut libc::c_char; + pub fn curl_dbg_calloc( + elements: size_t, + size: size_t, + line: libc::c_int, + source: *const libc::c_char, + ) -> *mut libc::c_void; + pub fn curl_dbg_malloc( + size: size_t, + line: libc::c_int, + source: *const libc::c_char, + ) -> *mut libc::c_void; + pub fn curl_dbg_fopen( + file: *const libc::c_char, + mode: *const libc::c_char, + line: libc::c_int, + source: *const libc::c_char, + ) -> *mut FILE; + pub fn curl_dbg_fclose( + file: *mut FILE, + line: libc::c_int, + source: *const libc::c_char, + ) -> libc::c_int; + pub fn curl_dbg_recv( + sockfd: libc::c_int, + buf: *mut libc::c_void, + len: size_t, + flags: libc::c_int, + line: libc::c_int, + source: *const libc::c_char, + ) -> ssize_t; pub fn curl_dbg_send( sockfd: libc::c_int, buf: *const libc::c_void, @@ -2565,12 +2565,12 @@ source: *const libc::c_char, ) -> ssize_t; pub fn curl_dbg_accept( - s: curl_socket_t, - a: *mut libc::c_void, - alen: *mut libc::c_void, - line: libc::c_int, - source: *const libc::c_char, - ) -> curl_socket_t; + s: curl_socket_t, + a: *mut libc::c_void, + alen: *mut libc::c_void, + line: libc::c_int, + source: *const libc::c_char, + ) -> curl_socket_t; pub fn curl_dbg_realloc( ptr: *mut libc::c_void, size: size_t, @@ -2586,5 +2586,4 @@ pub fn free(__ptr: *mut libc::c_void); pub fn malloc(_: libc::c_ulong) -> *mut libc::c_void; pub fn realloc(_: *mut libc::c_void, _: libc::c_ulong) -> *mut libc::c_void; - } - \ No newline at end of file +} diff --git a/rust/rust_macro/src/get_macros.rs b/rust/rust_macro/src/get_macros.rs index 0729da8..84c05fc 100644 --- a/rust/rust_macro/src/get_macros.rs +++ b/rust/rust_macro/src/get_macros.rs @@ -176,6 +176,8 @@ extern "C" { fn get_HAVE_ASSERT_H() -> i32; fn get_THREADING_SUPPORT() -> i32; + + fn get_USE_QUICHE() -> i32; } pub fn get_all_cfg() { // http2 @@ -341,6 +343,8 @@ pub fn get_all_cfg() { get_HAVE_ASSERT_H_add_cfg(); get_THREADING_SUPPORT_add_cfg(); + + get_USE_QUICHE_add_cfg(); } // http2 @@ -1028,9 +1032,14 @@ fn get_HAVE_ASSERT_H_add_cfg() { } } - fn get_THREADING_SUPPORT_add_cfg() { if unsafe { get_THREADING_SUPPORT() } == 1 { println!("cargo:rustc-cfg=THREADING_SUPPORT"); } -} \ No newline at end of file +} + +fn get_USE_QUICHE_add_cfg() { + if unsafe { get_USE_QUICHE() } == 1 { + println!("cargo:rustc-cfg=USE_QUICHE"); + } +} diff --git a/rust/rust_project/src/ftp.rs b/rust/rust_project/src/ftp.rs index c856632..00eb693 100644 --- a/rust/rust_project/src/ftp.rs +++ b/rust/rust_project/src/ftp.rs @@ -164,12 +164,15 @@ pub static mut Curl_handler_ftps: Curl_handler = unsafe { } }; extern "C" fn close_secondarysocket(mut data: *mut Curl_easy, mut conn: *mut connectdata) { - unsafe { - if -(1 as i32) != (*conn).sock[1 as usize] { + + if unsafe{-(1 as i32) != (*conn).sock[1 as usize] }{ + unsafe{ Curl_closesocket(data, conn, (*conn).sock[1 as usize]); (*conn).sock[1 as usize] = -(1 as i32); + } } - (*conn).bits.tcpconnect[1 as usize] = 0 as i32 != 0; + unsafe{(*conn).bits.tcpconnect[1 as usize] = 0 as i32 != 0;} + unsafe{ match () { #[cfg(not(CURL_DISABLE_PROXY))] _ => { @@ -179,6 +182,7 @@ extern "C" fn close_secondarysocket(mut data: *mut Curl_easy, mut conn: *mut con _ => {} } } + } /* @@ -192,10 +196,11 @@ extern "C" fn close_secondarysocket(mut data: *mut Curl_easy, mut conn: *mut con * following define named CURL_FTP_HTTPSTYLE_HEAD. */ extern "C" fn freedirs(mut ftpc: *mut ftp_conn) { - unsafe { - if !((*ftpc).dirs).is_null() { + + if unsafe{!((*ftpc).dirs).is_null()} { let mut i: i32 = 0; i = 0 as i32; + unsafe{ while i < (*ftpc).dirdepth { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( @@ -210,37 +215,38 @@ extern "C" fn freedirs(mut ftpc: *mut ftp_conn) { *((*ftpc).dirs).offset(i as isize) = 0 as *mut libc::c_char; i += 1; } + } #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")((*ftpc).dirs as *mut libc::c_void); + unsafe{Curl_cfree.expect("non-null function pointer")((*ftpc).dirs as *mut libc::c_void);} #[cfg(CURLDEBUG)] - curl_dbg_free( + unsafe{curl_dbg_free( (*ftpc).dirs as *mut libc::c_void, 251 as i32, b"ftp.c\0" as *const u8 as *const libc::c_char, - ); - (*ftpc).dirs = 0 as *mut *mut libc::c_char; - (*ftpc).dirdepth = 0 as i32; + );} + unsafe{(*ftpc).dirs = 0 as *mut *mut libc::c_char; + (*ftpc).dirdepth = 0 as i32;} } #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")((*ftpc).file as *mut libc::c_void); + unsafe{Curl_cfree.expect("non-null function pointer")((*ftpc).file as *mut libc::c_void);} #[cfg(CURLDEBUG)] - curl_dbg_free( + unsafe{curl_dbg_free( (*ftpc).file as *mut libc::c_void, 255 as i32, b"ftp.c\0" as *const u8 as *const libc::c_char, - ); - (*ftpc).file = 0 as *mut libc::c_char; + );} + unsafe{(*ftpc).file = 0 as *mut libc::c_char;} #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")((*ftpc).newhost as *mut libc::c_void); + unsafe{Curl_cfree.expect("non-null function pointer")((*ftpc).newhost as *mut libc::c_void);} #[cfg(CURLDEBUG)] - curl_dbg_free( + unsafe{curl_dbg_free( (*ftpc).newhost as *mut libc::c_void, 258 as i32, b"ftp.c\0" as *const u8 as *const libc::c_char, - ); + );} /* no longer of any use */ - (*ftpc).newhost = 0 as *mut libc::c_char; - } + unsafe{(*ftpc).newhost = 0 as *mut libc::c_char;} + } /*********************************************************************** @@ -252,26 +258,25 @@ extern "C" fn freedirs(mut ftpc: *mut ftp_conn) { * */ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut sock: curl_socket_t = (*conn).sock[1 as usize]; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut sock: curl_socket_t =unsafe{ (*conn).sock[1 as usize]}; let mut s: curl_socket_t = -(1 as i32); #[cfg(ENABLE_IPV6)] - let mut add: Curl_sockaddr_storage = Curl_sockaddr_storage { + let mut add: Curl_sockaddr_storage =unsafe{ Curl_sockaddr_storage { buffer: C2RustUnnamed_9 { sa: sockaddr { sa_family: 0, sa_data: [0; 14], }, }, - }; + }}; #[cfg(not(ENABLE_IPV6))] - let mut add: sockaddr_in = sockaddr_in { + let mut add: sockaddr_in = unsafe{ sockaddr_in { sin_family: 0, sin_port: 0, sin_addr: in_addr { s_addr: 0 }, sin_zero: [0; 8], - }; + }}; #[cfg(ENABLE_IPV6)] let mut size: curl_socklen_t = ::std::mem::size_of::() as curl_socklen_t; @@ -279,7 +284,7 @@ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { let mut size: curl_socklen_t = ::std::mem::size_of::() as u64 as curl_socklen_t; #[cfg(ENABLE_IPV6)] - if 0 as i32 + unsafe{ if 0 as i32 == getsockname( sock, &mut add as *mut Curl_sockaddr_storage as *mut sockaddr, @@ -308,9 +313,9 @@ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { ); } } - } + }} #[cfg(not(ENABLE_IPV6))] - if 0 as i32 + unsafe{ if 0 as i32 == getsockname( sock, &mut add as *mut sockaddr_in as *mut sockaddr, @@ -324,7 +329,8 @@ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { &mut size, ); } - Curl_closesocket(data, conn, sock); /* close the first socket */ + } + unsafe{ Curl_closesocket(data, conn, sock); /* close the first socket */ if -(1 as i32) == s { Curl_failf( data, @@ -355,8 +361,9 @@ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { return CURLE_ABORTED_BY_CALLBACK; } } - return CURLE_OK; } + return CURLE_OK; + } /* @@ -369,33 +376,33 @@ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { * */ extern "C" fn ftp_timeleft_accept(mut data: *mut Curl_easy) -> timediff_t { - unsafe { let mut timeout_ms: timediff_t = 60000 as timediff_t; let mut other: timediff_t = 0; let mut now: curltime = curltime { tv_sec: 0, tv_usec: 0, }; - if (*data).set.accepttimeout > 0 as i64 { - timeout_ms = (*data).set.accepttimeout; + if unsafe{(*data).set.accepttimeout > 0 as i64} { + unsafe{ + timeout_ms = (*data).set.accepttimeout;} } - now = Curl_now(); + now = unsafe{Curl_now()}; /* check if the generic timeout possibly is set shorter */ - other = Curl_timeleft(data, &mut now, 0 as i32 != 0); + other = unsafe{Curl_timeleft(data, &mut now, 0 as i32 != 0)}; if other != 0 && other < timeout_ms { /* note that this also works fine for when other happens to be negative due to it already having elapsed */ timeout_ms = other; } else { /* subtract elapsed time */ - timeout_ms -= Curl_timediff(now, (*data).progress.t_acceptdata); + timeout_ms -= unsafe{Curl_timediff(now, (*data).progress.t_acceptdata)}; if timeout_ms == 0 { /* avoid returning 0 as that means no timeout! */ return -(1 as i32) as timediff_t; } } return timeout_ms; - } + } /*********************************************************************** * @@ -407,48 +414,48 @@ extern "C" fn ftp_timeleft_accept(mut data: *mut Curl_easy) -> timediff_t { * */ extern "C" fn ReceivedServerConnect(mut data: *mut Curl_easy, mut received: *mut bool) -> CURLcode { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut ctrl_sock: curl_socket_t = (*conn).sock[0 as usize]; - let mut data_sock: curl_socket_t = (*conn).sock[1 as usize]; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut pp: *mut pingpong = &mut (*ftpc).pp; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ctrl_sock: curl_socket_t =unsafe{ (*conn).sock[0 as usize]}; + let mut data_sock: curl_socket_t = unsafe{(*conn).sock[1 as usize]}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; let mut result: i32 = 0; let mut timeout_ms: timediff_t = 0; let mut nread: ssize_t = 0; let mut ftpcode: i32 = 0; - *received = 0 as i32 != 0; + unsafe{*received = 0 as i32 != 0;} timeout_ms = ftp_timeleft_accept(data); - Curl_infof( + unsafe{Curl_infof( data, b"Checking for server connect\0" as *const u8 as *const libc::c_char, - ); + );} if timeout_ms < 0 as i64 { /* if a timeout was already reached, bail out */ - Curl_failf( + unsafe{Curl_failf( data, b"Accept timeout occurred while waiting server connect\0" as *const u8 as *const libc::c_char, - ); + );} return CURLE_FTP_ACCEPT_TIMEOUT; } /* First check whether there is a cached response from server */ - if (*pp).cache_size != 0 + if unsafe{(*pp).cache_size != 0 && !((*pp).cache).is_null() - && *((*pp).cache).offset(0 as isize) as i32 > '3' as i32 + && *((*pp).cache).offset(0 as isize) as i32 > '3' as i32} { /* Data connection could not be established, let's return */ - Curl_infof( + unsafe{Curl_infof( data, b"There is negative response in cache while serv connect\0" as *const u8 as *const libc::c_char, - ); + );} Curl_GetFTPResponse(data, &mut nread, &mut ftpcode); return CURLE_FTP_ACCEPT_FAILED; } - result = Curl_socket_check(ctrl_sock, data_sock, -(1 as i32), 0 as i32 as timediff_t); - /* see if the connection request is already here */ + result = unsafe{Curl_socket_check(ctrl_sock, data_sock, -(1 as i32), 0 as i32 as timediff_t)}; + /* see if the connecion request is already here */ + unsafe{ match result { -1 => { /* error *//* let's die here */ @@ -481,9 +488,9 @@ extern "C" fn ReceivedServerConnect(mut data: *mut Curl_easy, mut received: *mut return CURLE_WEIRD_SERVER_REPLY; } } /* switch() */ - } + }} return CURLE_OK; - } + } /*********************************************************************** @@ -495,17 +502,16 @@ extern "C" fn ReceivedServerConnect(mut data: *mut Curl_easy, mut received: *mut * */ extern "C" fn InitiateTransfer(mut data: *mut Curl_easy) -> CURLcode { - unsafe { let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = (*data).conn; - if ((*conn).bits).ftp_use_data_ssl() != 0 { + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + if unsafe{ ((*conn).bits).ftp_use_data_ssl() != 0} { /* since we only have a plaintext TCP connection here, we must now * do the TLS stuff */ - Curl_infof( + unsafe{Curl_infof( data, b"Doing the SSL/TLS handshake on the data stream\0" as *const u8 as *const libc::c_char, - ); + );} // match () { // #[cfg(USE_SSL)] // _ => { @@ -516,14 +522,15 @@ extern "C" fn InitiateTransfer(mut data: *mut Curl_easy) -> CURLcode { // result = CURLE_NOT_BUILT_IN; // } // } - result = Curl_ssl_connect(data, conn, 1 as i32); + result = unsafe{Curl_ssl_connect(data, conn, 1 as i32)}; if result as u64 != 0 { return result; } } /* When we know we're uploading a specified file, we can get the file size prior to the actual upload. */ - if (*conn).proto.ftpc.state_saved as u32 == FTP_STOR as u32 { + if unsafe{(*conn).proto.ftpc.state_saved as u32 == FTP_STOR as u32} { + unsafe{ Curl_pgrsSetUploadSize(data, (*data).state.infilesize); /* set the SO_SNDBUF for the secondary socket for those who need it */ Curl_setup_transfer( @@ -532,25 +539,26 @@ extern "C" fn InitiateTransfer(mut data: *mut Curl_easy) -> CURLcode { -(1 as i32) as curl_off_t, 0 as i32 != 0, 1 as i32, - ); + );} } else { /* FTP download: */ + unsafe{ Curl_setup_transfer( data, 1 as i32, (*conn).proto.ftpc.retr_size_saved, 0 as i32 != 0, -(1 as i32), - ); + );} } - (*conn).proto.ftpc.pp.pending_resp = 1 as i32 != 0; /* expect server response */ + unsafe{(*conn).proto.ftpc.pp.pending_resp = 1 as i32 != 0;} /* expect server response */ #[cfg(not(DEBUGBUILD))] _state(data, FTP_STOP); #[cfg(DEBUGBUILD)] _state(data, FTP_STOP, 470 as i32); return CURLE_OK; - } + } /*********************************************************************** * @@ -562,24 +570,23 @@ extern "C" fn InitiateTransfer(mut data: *mut Curl_easy) -> CURLcode { * */ extern "C" fn AllowServerConnect(mut data: *mut Curl_easy, mut connected: *mut bool) -> CURLcode { - unsafe { let mut timeout_ms: timediff_t = 0; let mut result: CURLcode = CURLE_OK; - *connected = 0 as i32 != 0; - Curl_infof( + unsafe{*connected = 0 as i32 != 0}; + unsafe{Curl_infof( data, b"Preparing for accepting server on data port\0" as *const u8 as *const libc::c_char, ); /* Save the time we start accepting server connect */ - Curl_pgrsTime(data, TIMER_STARTACCEPT); + Curl_pgrsTime(data, TIMER_STARTACCEPT);} timeout_ms = ftp_timeleft_accept(data); if timeout_ms < 0 as i64 { /* if a timeout was already reached, bail out */ - Curl_failf( + unsafe{Curl_failf( data, b"Accept timeout occurred while waiting server connect\0" as *const u8 as *const libc::c_char, - ); + );} return CURLE_FTP_ACCEPT_TIMEOUT; } /* see if the connection request is already here */ @@ -589,7 +596,7 @@ extern "C" fn AllowServerConnect(mut data: *mut Curl_easy, mut connected: *mut b } /* Add timeout to multi handle and break out of the loop */ - if *connected { + if unsafe{*connected} { result = AcceptServerConnect(data); if result as u64 != 0 { return result; @@ -598,8 +605,8 @@ extern "C" fn AllowServerConnect(mut data: *mut Curl_easy, mut connected: *mut b if result as u64 != 0 { return result; } - } else if *connected as i32 == 0 as i32 { - Curl_expire( + } else if unsafe{*connected as i32 == 0 as i32} { + unsafe{Curl_expire( data, if (*data).set.accepttimeout > 0 as i64 { (*data).set.accepttimeout @@ -607,10 +614,10 @@ extern "C" fn AllowServerConnect(mut data: *mut Curl_easy, mut connected: *mut b 60000 as i64 }, EXPIRE_100_TIMEOUT, - ); + );} } return result; - } + } extern "C" fn ftp_endofresp( mut data: *mut Curl_easy, @@ -639,13 +646,14 @@ extern "C" fn ftp_readresp( mut ftpcode: *mut i32, /* return the ftp-code if done */ mut size: *mut size_t, /* size of the response */ ) -> CURLcode { - unsafe { + let mut code: i32 = 0; - let mut result: CURLcode = Curl_pp_readresp(data, sockfd, pp, &mut code, size); + let mut result: CURLcode = unsafe{Curl_pp_readresp(data, sockfd, pp, &mut code, size)}; if cfg!(HAVE_GSSAPI) { - let mut conn: *mut connectdata = (*data).conn; - let buf: *mut libc::c_char = (*data).state.buffer; + let mut conn: *mut connectdata = unsafe{(*data).conn}; + let buf: *mut libc::c_char =unsafe{ (*data).state.buffer}; /* handle the security-oriented responses 6xx ***/ + unsafe{ match code { 631 => { code = Curl_sec_read_msg(data, conn, buf, PROT_SAFE); @@ -658,11 +666,12 @@ extern "C" fn ftp_readresp( } _ => {} /* normal ftp stuff we pass through! */ } - } + } + } /* store the latest code for later retrieval */ - (*data).info.httpcode = code; + unsafe{(*data).info.httpcode = code;} if !ftpcode.is_null() { - *ftpcode = code; + unsafe{*ftpcode = code;} } if 421 as i32 == code { /* 421 means "Service not available, closing control connection." and FTP @@ -672,10 +681,10 @@ extern "C" fn ftp_readresp( * This response code can come at any point so having it treated * generically is a good idea. */ - Curl_infof( + unsafe{Curl_infof( data, b"We got a 421 - timeout!\0" as *const u8 as *const libc::c_char, - ); + );} #[cfg(not(DEBUGBUILD))] _state(data, FTP_STOP); @@ -684,22 +693,21 @@ extern "C" fn ftp_readresp( return CURLE_OPERATION_TIMEDOUT; } return result; - } + } /* --- parse FTP server responses --- */ /* -* Curl_GetFTPResponse() is a BLOCKING function to read the full response -* from a server after a command. -* -*/ + * Curl_GetFTPResponse() is a BLOCKING function to read the full response + * from a server after a command. + * + */ #[no_mangle] pub extern "C" fn Curl_GetFTPResponse( mut data: *mut Curl_easy, mut nreadp: *mut ssize_t, /* return number of bytes read */ mut ftpcode: *mut i32, /* return the ftp-code */ ) -> CURLcode { - unsafe { /* * We cannot read just one byte per read() and then go back to select() as * the OpenSSL read() doesn't grok that properly. @@ -707,31 +715,31 @@ pub extern "C" fn Curl_GetFTPResponse( * Alas, read as much as possible, split up into lines, use the ending * line in a response or continue reading. */ - let mut conn: *mut connectdata = (*data).conn; - let mut sockfd: curl_socket_t = (*conn).sock[0 as usize]; + let mut conn: *mut connectdata = unsafe{(*data).conn}; + let mut sockfd: curl_socket_t = unsafe{(*conn).sock[0 as usize]}; let mut result: CURLcode = CURLE_OK; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut pp: *mut pingpong = &mut (*ftpc).pp; + let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; + let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; let mut nread: size_t = 0; let mut cache_skip: i32 = 0 as i32; let mut value_to_be_ignored: i32 = 0 as i32; if !ftpcode.is_null() { - *ftpcode = 0 as i32; /* 0 for errors */ + unsafe{*ftpcode = 0 as i32;} /* 0 for errors */ } else { /* make the pointer point to something for the rest of this function */ ftpcode = &mut value_to_be_ignored; } - *nreadp = 0 as ssize_t; + unsafe{*nreadp = 0 as ssize_t;} let mut current_block_20: u64; - while *ftpcode == 0 && result as u64 == 0 { + while unsafe{*ftpcode == 0 && result as u64 == 0} { /* check and reset timeout value every lap */ - let mut timeout: timediff_t = Curl_pp_state_timeout(data, pp, 0 as i32 != 0); + let mut timeout: timediff_t = unsafe{Curl_pp_state_timeout(data, pp, 0 as i32 != 0)}; let mut interval_ms: timediff_t = 0; if timeout <= 0 as i64 { - Curl_failf( + unsafe{Curl_failf( data, b"FTP response timeout\0" as *const u8 as *const libc::c_char, - ); + );} return CURLE_OPERATION_TIMEDOUT; /* already too little time */ } interval_ms = 1000 as timediff_t; /* use 1 second timeout intervals */ @@ -751,14 +759,15 @@ pub extern "C" fn Curl_GetFTPResponse( * around this function. * */ - if !(!((*pp).cache).is_null() && cache_skip < 2 as i32) { + if unsafe{!(!((*pp).cache).is_null() && cache_skip < 2 as i32)} { /* * There's a cache left since before. We then skipping the wait for * socket action, unless this is the same cache like the previous round * as then the cache was deemed not enough to act on and we then need to * wait for more data anyway. */ - if !Curl_conn_data_pending(conn, 0 as i32) { + if unsafe{!Curl_conn_data_pending(conn, 0 as i32)} { + unsafe{ match Curl_socket_check(sockfd, -(1 as i32), -(1 as i32), interval_ms) { -1 => { /* select() error, stop reading */ @@ -808,22 +817,23 @@ pub extern "C" fn Curl_GetFTPResponse( } } } + } result = ftp_readresp(data, sockfd, pp, ftpcode, &mut nread); if result as u64 != 0 { break; } - if nread == 0 && !((*pp).cache).is_null() { + if unsafe{nread == 0 && !((*pp).cache).is_null()} { cache_skip += 1; /* bump cache skip counter as on repeated skips we must wait for more data */ } else { cache_skip = 0 as i32; } - *nreadp = (*nreadp as u64).wrapping_add(nread) as ssize_t; + unsafe{*nreadp = (*nreadp as u64).wrapping_add(nread) as ssize_t;} } - (*pp).pending_resp = 0 as i32 != 0; /* when we got data or there is no cache left, we reset the cache skip + unsafe{(*pp).pending_resp = 0 as i32 != 0;} /* when we got data or there is no cache left, we reset the cache skip counter */ return result; - } + } /* for debug purposes */ static mut ftp_state_names: [*const libc::c_char; 35] = [ @@ -893,8 +903,7 @@ extern "C" fn _state(mut data: *mut Curl_easy, mut newstate: ftpstate, mut linen } /* For the FTP "protocol connect" and "doing" phases only */ extern "C" fn ftp_state_user(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - unsafe { - let mut result: CURLcode = Curl_pp_sendf( + let mut result: CURLcode =unsafe{ Curl_pp_sendf( data, &mut (*conn).proto.ftpc.pp as *mut pingpong, b"USER %s\0" as *const u8 as *const libc::c_char, @@ -903,7 +912,7 @@ extern "C" fn ftp_state_user(mut data: *mut Curl_easy, mut conn: *mut connectdat } else { b"\0" as *const u8 as *const libc::c_char }, - ); + )}; if result as u64 == 0 { #[cfg(not(DEBUGBUILD))] _state(data, FTP_USER); @@ -911,20 +920,19 @@ extern "C" fn ftp_state_user(mut data: *mut Curl_easy, mut conn: *mut connectdat #[cfg(DEBUGBUILD)] _state(data, FTP_USER, 787 as i32); // let ref mut fresh6 = (*data).state; - ((*data).state).set_ftp_trying_alternative(0 as bit); + unsafe{((*data).state).set_ftp_trying_alternative(0 as bit);} } return result; - } + } /* For the FTP "DO_MORE" phase only */ extern "C" fn ftp_state_pwd(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - unsafe { - let mut result: CURLcode = Curl_pp_sendf( + let mut result: CURLcode =unsafe{ Curl_pp_sendf( data, &mut (*conn).proto.ftpc.pp as *mut pingpong, b"%s\0" as *const u8 as *const libc::c_char, b"PWD\0" as *const u8 as *const libc::c_char, - ); + )}; if result as u64 == 0 { #[cfg(not(DEBUGBUILD))] _state(data, FTP_PWD); @@ -933,7 +941,7 @@ extern "C" fn ftp_state_pwd(mut data: *mut Curl_easy, mut conn: *mut connectdata _state(data, FTP_PWD, 798 as i32); } return result; - } + } /* For the FTP "protocol connect" and "doing" phases only */ extern "C" fn ftp_getsock( @@ -951,28 +959,28 @@ extern "C" fn ftp_domore_getsock( mut conn: *mut connectdata, mut socks: *mut curl_socket_t, ) -> i32 { - unsafe { + /* When in DO_MORE state, we could be either waiting for us to connect to a * remote site, or we could wait for that site to connect to us. Or just * handle ordinary commands. */ - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - if (*conn).cnnct.state as u32 >= CONNECT_SOCKS_INIT as u32 - && ((*conn).cnnct.state as u32) < CONNECT_DONE as u32 + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + if unsafe{(*conn).cnnct.state as u32 >= CONNECT_SOCKS_INIT as u32 + && ((*conn).cnnct.state as u32) < CONNECT_DONE as u32} { /* if stopped and still in this state, then we're also waiting for a connect on the secondary connection */ #[cfg(not(CURL_DISABLE_PROXY))] - return Curl_SOCKS_getsock(conn, socks, 1 as i32); + unsafe{return Curl_SOCKS_getsock(conn, socks, 1 as i32);} #[cfg(CURL_DISABLE_PROXY)] return 0 as i32; } - if FTP_STOP as u32 == (*ftpc).state as u32 { + if unsafe{FTP_STOP as u32 == (*ftpc).state as u32} { let mut bits: i32 = (1 as i32) << 0 as i32; let mut any: bool = 0 as i32 != 0; /* PORT is used to tell the server to connect to us, and during that we don't do happy eyeballs, but we do if we connect to the server */ - *socks.offset(0 as i32 as isize) = (*conn).sock[0 as usize]; + unsafe{*socks.offset(0 as i32 as isize) = (*conn).sock[0 as usize]; if ((*data).set).ftp_use_port() == 0 { let mut s: i32 = 0; let mut i: i32 = 0; @@ -993,10 +1001,10 @@ extern "C" fn ftp_domore_getsock( *socks.offset(1 as isize) = (*conn).sock[1 as usize]; bits |= (1 as i32) << 16 as i32 + 1 as i32 | (1 as i32) << 1 as i32; } - return bits; + return bits;} } - return Curl_pp_getsock(data, &mut (*conn).proto.ftpc.pp, socks); - } + return unsafe{Curl_pp_getsock(data, &mut (*conn).proto.ftpc.pp, socks)}; + } /* This is called after the FTP_QUOTE state is passed. @@ -1006,9 +1014,10 @@ extern "C" fn ftp_domore_getsock( missing ones, if that option is enabled. */ extern "C" fn ftp_state_cwd(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + unsafe{ if (*ftpc).cwddone { /* already done and fine */ result = ftp_state_mdtm(data); @@ -1022,16 +1031,16 @@ extern "C" fn ftp_state_cwd(mut data: *mut Curl_easy, mut conn: *mut connectdata { } else { __assert_fail( - b"(data->set.ftp_filemethod != FTPFILE_NOCWD) || !(ftpc->dirdepth && ftpc->dirs[0][0] == '/')\0" - as *const u8 as *const libc::c_char, - b"ftp.c\0" as *const u8 as *const libc::c_char, - 875 as u32, - (*::std::mem::transmute::< - &[u8; 65], - &[libc::c_char; 65], - >(b"CURLcode ftp_state_cwd(struct Curl_easy *, struct connectdata *)\0")) - .as_ptr(), - ); + b"(data->set.ftp_filemethod != FTPFILE_NOCWD) || !(ftpc->dirdepth && ftpc->dirs[0][0] == '/')\0" + as *const u8 as *const libc::c_char, + b"ftp.c\0" as *const u8 as *const libc::c_char, + 875 as u32, + (*::std::mem::transmute::< + &[u8; 65], + &[libc::c_char; 65], + >(b"CURLcode ftp_state_cwd(struct Curl_easy *, struct connectdata *)\0")) + .as_ptr(), + ); } (*ftpc).count2 = 0 as i32; /* count2 counts failed CWDs */ /* count3 is set to allow a MKD to fail once. In the case when first CWD @@ -1101,11 +1110,11 @@ extern "C" fn ftp_state_use_port(mut data: *mut Curl_easy, mut fcmd: ftpport) -> let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; let mut portsock: curl_socket_t = -(1 as i32); let mut myhost: [libc::c_char; 47] = *::std::mem::transmute::< - &[u8; 47], - &mut [libc::c_char; 47], - >( - b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - ); + &[u8; 47], + &mut [libc::c_char; 47], + >( + b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + ); let mut ss: Curl_sockaddr_storage = Curl_sockaddr_storage { buffer: C2RustUnnamed_9 { sa: sockaddr { @@ -1851,10 +1860,10 @@ extern "C" fn ftp_state_prepare_transfer(mut data: *mut Curl_easy) -> CURLcode { } } extern "C" fn ftp_state_rest(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - unsafe { let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + unsafe{ if (*ftp).transfer as u32 != PPTRANSFER_BODY as u32 && !((*ftpc).file).is_null() { /* if a "head"-like request is being made (on a file) */ @@ -1880,10 +1889,11 @@ extern "C" fn ftp_state_rest(mut data: *mut Curl_easy, mut conn: *mut connectdat } } extern "C" fn ftp_state_size(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; + let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; + unsafe{ if (*ftp).transfer as u32 == PPTRANSFER_INFO as u32 && !((*ftpc).file).is_null() { /* if a "head"-like request is being made (on a file) */ @@ -1908,10 +1918,10 @@ extern "C" fn ftp_state_size(mut data: *mut Curl_easy, mut conn: *mut connectdat } } extern "C" fn ftp_state_list(mut data: *mut Curl_easy) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut conn: *mut connectdata = (*data).conn; + let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; /* If this output is to be machine-parsed, the NLST command might be better to use, since the LIST command output is not specified or standard in any way. It has turned out that the NLST list output is not the same on all @@ -1927,6 +1937,7 @@ extern "C" fn ftp_state_list(mut data: *mut Curl_easy) -> CURLcode { */ let mut lstArg: *mut libc::c_char = 0 as *mut libc::c_char; let mut cmd: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe{ if (*data).set.ftp_filemethod as u32 == FTPFILE_NOCWD as u32 && !((*ftp).path).is_null() { let mut slashPos: *const libc::c_char = 0 as *const libc::c_char; let mut rawPath: *mut libc::c_char = 0 as *mut libc::c_char; @@ -2033,14 +2044,15 @@ extern "C" fn ftp_state_stor_prequote(mut data: *mut Curl_easy) -> CURLcode { } } extern "C" fn ftp_state_type(mut data: *mut Curl_easy) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; /* If we have selected NOBODY and HEADER, it means that we only want file information. Which in FTP can't be much more than the file size and date. */ + unsafe{ if ((*data).set).opt_no_body() as i32 != 0 && !((*ftpc).file).is_null() && ftp_need_type(conn, ((*data).state).prefer_ascii() != 0) != 0 @@ -2066,11 +2078,12 @@ extern "C" fn ftp_state_type(mut data: *mut Curl_easy) -> CURLcode { /* This is called after the CWD commands have been done in the beginning of the DO phase */ extern "C" fn ftp_state_mdtm(mut data: *mut Curl_easy) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; /* Requested time of file or time-depended transfer? */ + unsafe{ if (((*data).set).get_filetime() as i32 != 0 || (*data).set.timecondition as u32 != 0) && !((*ftpc).file).is_null() { @@ -2097,12 +2110,13 @@ extern "C" fn ftp_state_mdtm(mut data: *mut Curl_easy) -> CURLcode { } /* This is called after the TYPE and possible quote commands have been sent */ extern "C" fn ftp_state_ul_setup(mut data: *mut Curl_easy, mut sizechecked: bool) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = (*data).conn; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut append: bool = ((*data).set).remote_append() != 0; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + let mut append: bool =unsafe{ ((*data).set).remote_append() != 0}; + unsafe{ if (*data).state.resume_from != 0 && !sizechecked || (*data).state.resume_from > 0 as i64 && sizechecked as i32 != 0 { @@ -2241,13 +2255,14 @@ extern "C" fn ftp_state_quote( mut init: bool, mut instate: ftpstate, ) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; let mut quote: bool = 0 as i32 != 0; let mut item: *mut curl_slist = 0 as *mut curl_slist; + unsafe{ match instate as u32 { 13 | 14 => { item = (*data).set.prequote; @@ -2434,15 +2449,16 @@ extern "C" fn control_address(mut conn: *mut connectdata) -> *mut libc::c_char { } } extern "C" fn ftp_state_pasv_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> CURLcode { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; let mut result: CURLcode = CURLE_OK; let mut addr: *mut Curl_dns_entry = 0 as *mut Curl_dns_entry; let mut rc: resolve_t = CURLRESOLV_RESOLVED; let mut connectport: u16 = 0; /* the local port connect() should use! */ - let mut str: *mut libc::c_char = - &mut *((*data).state.buffer).offset(4 as isize) as *mut libc::c_char; /* start on the first letter */ + let mut str: *mut libc::c_char =unsafe{ + &mut *((*data).state.buffer).offset(4 as isize) as *mut libc::c_char}; /* start on the first letter */ + unsafe{ #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")((*ftpc).newhost as *mut libc::c_void); /* if we come here again, make sure the former name is cleared */ @@ -2862,11 +2878,12 @@ extern "C" fn ftp_state_pasv_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> } } extern "C" fn ftp_state_port_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> CURLcode { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut fcmd: ftpport = (*ftpc).count1 as ftpport; + + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; + let mut fcmd: ftpport = unsafe{(*ftpc).count1 as ftpport}; let mut result: CURLcode = CURLE_OK; + unsafe{ /* The FTP spec tells a positive response should have code 200. Be more permissive here to tolerate deviant servers. */ if ftpcode / 100 as i32 != 2 as i32 { @@ -2906,11 +2923,12 @@ extern "C" fn ftp_state_port_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> } } extern "C" fn ftp_state_mdtm_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut ftp: *mut FTP =unsafe{(*data).req.p.ftp}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + unsafe{ match ftpcode { 213 => { /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the @@ -3080,9 +3098,10 @@ extern "C" fn ftp_state_type_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = (*data).conn; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + unsafe{ if ftpcode / 100 as i32 != 2 as i32 { /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a successful 'TYPE I'. While that is not as RFC959 says, it is still a @@ -3114,11 +3133,12 @@ extern "C" fn ftp_state_type_resp( } } extern "C" fn ftp_state_retr(mut data: *mut Curl_easy, mut filesize: curl_off_t) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + unsafe{ if (*data).set.max_filesize != 0 && filesize > (*data).set.max_filesize { Curl_failf( data, @@ -3230,10 +3250,11 @@ extern "C" fn ftp_state_size_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; let mut filesize: curl_off_t = -(1 as i32) as curl_off_t; - let mut buf: *mut libc::c_char = (*data).state.buffer; + let mut buf: *mut libc::c_char =unsafe{ (*data).state.buffer}; + unsafe{ /* get the size from the ascii string: */ if ftpcode == 213 as i32 { /* To allow servers to prepend "rubbish" in the response string, we scan @@ -3306,9 +3327,10 @@ extern "C" fn ftp_state_rest_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + unsafe{ match instate as u32 { 27 => { if ftpcode != 350 as i32 { @@ -3361,9 +3383,10 @@ extern "C" fn ftp_state_stor_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = (*data).conn; + let mut conn: *mut connectdata = unsafe{(*data).conn}; + unsafe{ if ftpcode >= 400 as i32 { Curl_failf( data, @@ -3411,10 +3434,11 @@ extern "C" fn ftp_state_get_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut conn: *mut connectdata = (*data).conn; + let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + unsafe{ if ftpcode == 150 as i32 || ftpcode == 125 as i32 { /* A; @@ -3556,9 +3580,10 @@ extern "C" fn ftp_state_get_resp( } /* after USER, PASS and ACCT */ extern "C" fn ftp_state_loggedin(mut data: *mut Curl_easy) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = (*data).conn; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + unsafe{ if ((*conn).bits).ftp_use_control_ssl() != 0 { /* PBSZ = PROTECTION BUFFER SIZE. @@ -3599,11 +3624,12 @@ extern "C" fn ftp_state_user_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; /* no use for this yet */ + let mut conn: *mut connectdata = unsafe{(*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; /* no use for this yet */ /* some need password anyway, and others just return 2xx ignored */ + unsafe{ if ftpcode == 331 as i32 && (*ftpc).state as u32 == FTP_USER as u32 { /* 331 Password required for ... (the server requires to send the user's password too) */ @@ -4366,14 +4392,15 @@ unsafe extern "C" fn ftp_statemachine( /* called repeatedly until done from multi.c */ extern "C" fn ftp_multi_statemach(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut result: CURLcode = - Curl_pp_statemach(data, &mut (*ftpc).pp, 0 as i32 != 0, 0 as i32 != 0); + + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; + let mut result: CURLcode =unsafe{ + Curl_pp_statemach(data, &mut (*ftpc).pp, 0 as i32 != 0, 0 as i32 != 0)}; /* Check for the state outside of the Curl_socket_check() return code checks since at times we are in fact already in this state when this function gets called. */ + unsafe{ *done = if (*ftpc).state as u32 == FTP_STOP as u32 { 1 as i32 } else { @@ -4387,10 +4414,10 @@ extern "C" fn ftp_block_statemach( mut data: *mut Curl_easy, mut conn: *mut connectdata, ) -> CURLcode { - unsafe { - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut pp: *mut pingpong = &mut (*ftpc).pp; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; let mut result: CURLcode = CURLE_OK; + unsafe{ // 解决clippy错误 loop { if (*ftpc).state as u32 == FTP_STOP as u32 { @@ -4416,11 +4443,12 @@ extern "C" fn ftp_block_statemach( */ extern "C" fn ftp_connect(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { /* see description above */ - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut pp: *mut pingpong = &mut (*ftpc).pp; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; + unsafe{ *done = 0 as i32 != 0; /* default to not done yet */ #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 0 as i32); @@ -4493,16 +4521,17 @@ extern "C" fn ftp_done( mut status: CURLcode, mut premature: bool, ) -> CURLcode { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut pp: *mut pingpong = &mut (*ftpc).pp; + + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; + let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; + let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; let mut nread: ssize_t = 0; let mut ftpcode: i32 = 0; let mut result: CURLcode = CURLE_OK; let mut rawPath: *mut libc::c_char = 0 as *mut libc::c_char; let mut pathLen: size_t = 0 as size_t; + unsafe{ if ftp.is_null() { return CURLE_OK; } @@ -4875,11 +4904,12 @@ extern "C" fn ftp_sendquote( mut conn: *mut connectdata, mut quote: *mut curl_slist, ) -> CURLcode { - unsafe { + let mut item: *mut curl_slist = 0 as *mut curl_slist; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut pp: *mut pingpong = &mut (*ftpc).pp; + let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; + let mut pp: *mut pingpong = unsafe{&mut (*ftpc).pp}; item = quote; + unsafe{ while !item.is_null() { if !((*item).data).is_null() { let mut nread: ssize_t = 0; @@ -4953,14 +4983,15 @@ extern "C" fn ftp_nb_type( mut ascii: bool, mut newstate: ftpstate, ) -> CURLcode { - unsafe { - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; let mut result: CURLcode = CURLE_OK; let mut want: libc::c_char = (if ascii as i32 != 0 { 'A' as i32 } else { 'I' as i32 }) as libc::c_char; + unsafe{ if (*ftpc).transfertype as i32 == want as i32 { #[cfg(not(DEBUGBUILD))] _state(data, newstate); @@ -5003,8 +5034,9 @@ extern "C" fn ftp_pasv_verbose( mut newhost: *mut libc::c_char, /* ascii version */ mut port: i32, ) { - unsafe { + let mut buf: [libc::c_char; 256] = [0; 256]; + unsafe{ Curl_printable_address( ai, buf.as_mut_ptr(), @@ -5031,13 +5063,14 @@ extern "C" fn ftp_pasv_verbose( * EPSV). */ extern "C" fn ftp_do_more(mut data: *mut Curl_easy, mut completep: *mut i32) -> CURLcode { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; let mut result: CURLcode = CURLE_OK; let mut connected: bool = 0 as i32 != 0; let mut complete: bool = 0 as i32 != 0; - let mut ftp: *mut FTP = (*data).req.p.ftp; + let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; + unsafe{ /* the ftp struct is inited in ftp_connect() */ /* if the second connection isn't done yet, wait for it */ if !(*conn).bits.tcpconnect[1 as i32 as usize] { @@ -5205,12 +5238,12 @@ extern "C" fn ftp_do_more(mut data: *mut Curl_easy, mut completep: *mut i32) -> } /*********************************************************************** -* -* ftp_perform() -* -* This is the actual DO function for FTP. Get a file/directory according to -* the options previously setup. -*/ + * + * ftp_perform() + * + * This is the actual DO function for FTP. Get a file/directory according to + * the options previously setup. + */ extern "C" fn ftp_perform( mut data: *mut Curl_easy, mut connected: *mut bool, /* connect status after PASV / PORT */ @@ -5274,13 +5307,14 @@ extern "C" fn wc_data_dtor(mut ptr: *mut libc::c_void) { } extern "C" fn init_wc_data(mut data: *mut Curl_easy) -> CURLcode { - unsafe { + let mut last_slash: *mut libc::c_char = 0 as *mut libc::c_char; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut path: *mut libc::c_char = (*ftp).path; - let mut wildcard: *mut WildcardData = &mut (*data).wildcard; + let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; + let mut path: *mut libc::c_char =unsafe{ (*ftp).path}; + let mut wildcard: *mut WildcardData =unsafe{ &mut (*data).wildcard}; let mut result: CURLcode = CURLE_OK; let mut ftpwc: *mut ftp_wc = 0 as *mut ftp_wc; + unsafe{ last_slash = strrchr((*ftp).path, '/' as i32); if !last_slash.is_null() { last_slash = last_slash.offset(1); @@ -5459,11 +5493,12 @@ extern "C" fn init_wc_data(mut data: *mut Curl_easy) -> CURLcode { } extern "C" fn wc_statemach(mut data: *mut Curl_easy) -> CURLcode { - unsafe { - let wildcard: *mut WildcardData = &mut (*data).wildcard; - let mut conn: *mut connectdata = (*data).conn; + + let wildcard: *mut WildcardData =unsafe{ &mut (*data).wildcard}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; let mut result: CURLcode = CURLE_OK; let mut current_block_53: u64; + unsafe{ loop { match (*wildcard).state as u32 { 1 => { @@ -5658,10 +5693,11 @@ extern "C" fn wc_statemach(mut data: *mut Curl_easy) -> CURLcode { * The input argument is already checked for validity. */ extern "C" fn ftp_do(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + unsafe{ *done = 0 as i32 != 0; /* default to false */ (*ftpc).wait_data_conn = 0 as i32 != 0; /* default to no such wait */ if ((*data).state).wildcardmatch() != 0 { @@ -6293,9 +6329,9 @@ extern "C" fn ftp_disconnect( mut conn: *mut connectdata, mut dead_connection: bool, ) -> CURLcode { - unsafe { - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; - let mut pp: *mut pingpong = &mut (*ftpc).pp; + + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; /* We cannot send quit unconditionally. If this connection is stale or bad in any way, sending quit and waiting around here will make the disconnect wait in vain and cause more problems than we need to. @@ -6303,6 +6339,7 @@ extern "C" fn ftp_disconnect( ftp_quit() will check the state of ftp->ctl_valid. If it's ok it will try to send the QUIT command, otherwise it will just return. */ + unsafe{ if dead_connection { (*ftpc).ctl_valid = 0 as i32 != 0; } @@ -6363,16 +6400,17 @@ extern "C" fn ftp_disconnect( * */ extern "C" fn ftp_parse_url_path(mut data: *mut Curl_easy) -> CURLcode { - unsafe { + /* the ftp struct is already inited in ftp_connect() */ - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; let mut slashPos: *const libc::c_char = 0 as *const libc::c_char; let mut fileName: *const libc::c_char = 0 as *const libc::c_char; let mut result: CURLcode = CURLE_OK; let mut rawPath: *mut libc::c_char = 0 as *mut libc::c_char; /* url-decoded "raw" path */ let mut pathLen: size_t = 0 as size_t; + unsafe{ (*ftpc).ctl_valid = 0 as i32 != 0; (*ftpc).cwdfail = 0 as i32 != 0; /* url-decode ftp path before further evaluation */ @@ -6685,10 +6723,11 @@ extern "C" fn ftp_parse_url_path(mut data: *mut Curl_easy) -> CURLcode { } /* call this when the DO phase has completed */ extern "C" fn ftp_dophase_done(mut data: *mut Curl_easy, mut connected: bool) -> CURLcode { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut ftp: *mut FTP = (*data).req.p.ftp; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + unsafe{ if connected { let mut completed: i32 = 0; let mut result: CURLcode = ftp_do_more(data, &mut completed); @@ -6752,11 +6791,12 @@ extern "C" fn ftp_regular_transfer( mut data: *mut Curl_easy, mut dophase_done: *mut bool, ) -> CURLcode { - unsafe { + let mut result: CURLcode = CURLE_OK; let mut connected: bool = 0 as i32 != 0; - let mut conn: *mut connectdata = (*data).conn; - let mut ftpc: *mut ftp_conn = &mut (*conn).proto.ftpc; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; + unsafe{ (*data).req.size = -(1 as i32) as curl_off_t; /* make sure this is unknown at this point */ Curl_pgrsSetUploadCounter(data, 0 as curl_off_t); Curl_pgrsSetDownloadCounter(data, 0 as curl_off_t); diff --git a/rust/rust_project/src/ftplistparser.rs b/rust/rust_project/src/ftplistparser.rs index da12308..bdd48c6 100644 --- a/rust/rust_project/src/ftplistparser.rs +++ b/rust/rust_project/src/ftplistparser.rs @@ -8,7 +8,7 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: pnext, + * Author: pnext, * Create: 2022-10-31 * Description: ftplistparser ******************************************************************************/ @@ -38,154 +38,160 @@ use rust_ffi::src::ffi_struct::struct_define::*; #[no_mangle] pub extern "C" fn Curl_ftp_parselist_data_alloc() -> *mut ftp_parselist_data { #[cfg(not(CURLDEBUG))] - return unsafe{Curl_ccalloc.expect("non-null function pointer")( - 1 as size_t, - ::std::mem::size_of::() as u64, - ) as *mut ftp_parselist_data}; + return unsafe { + Curl_ccalloc.expect("non-null function pointer")( + 1 as size_t, + ::std::mem::size_of::() as u64, + ) as *mut ftp_parselist_data + }; #[cfg(CURLDEBUG)] - return unsafe{curl_dbg_calloc( - 1 as size_t, - ::std::mem::size_of::() as u64, - 184 as i32, - b"ftplistparser.c\0" as *const u8 as *const libc::c_char, - ) as *mut ftp_parselist_data}; - + return unsafe { + curl_dbg_calloc( + 1 as size_t, + ::std::mem::size_of::() as u64, + 184 as i32, + b"ftplistparser.c\0" as *const u8 as *const libc::c_char, + ) as *mut ftp_parselist_data + }; } #[no_mangle] pub extern "C" fn Curl_ftp_parselist_data_free(mut parserp: *mut *mut ftp_parselist_data) { - let mut parser: *mut ftp_parselist_data = unsafe{*parserp}; + let mut parser: *mut ftp_parselist_data = unsafe { *parserp }; if !parser.is_null() { - unsafe{Curl_fileinfo_cleanup((*parser).file_data);} + unsafe { + Curl_fileinfo_cleanup((*parser).file_data); + } } #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(parser as *mut libc::c_void);} + unsafe { + Curl_cfree.expect("non-null function pointer")(parser as *mut libc::c_void); + } #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - parser as *mut libc::c_void, - 193 as i32, - b"ftplistparser.c\0" as *const u8 as *const libc::c_char, - ); - *parserp = 0 as *mut ftp_parselist_data;} + unsafe { + curl_dbg_free( + parser as *mut libc::c_void, + 193 as i32, + b"ftplistparser.c\0" as *const u8 as *const libc::c_char, + ); + *parserp = 0 as *mut ftp_parselist_data; + } } #[no_mangle] -pub extern "C" fn Curl_ftp_parselist_geterror( - mut pl_data: *mut ftp_parselist_data, -) -> CURLcode { - unsafe{ - return (*pl_data).error; - } +pub extern "C" fn Curl_ftp_parselist_geterror(mut pl_data: *mut ftp_parselist_data) -> CURLcode { + unsafe { + return (*pl_data).error; + } } extern "C" fn ftp_pl_get_permission(mut str: *const libc::c_char) -> i32 { let mut permissions: i32 = 0 as i32; /* USER */ - if unsafe{ *str.offset(0 as isize) as i32} == 'r' as i32 { + if unsafe { *str.offset(0 as isize) as i32 } == 'r' as i32 { permissions |= (1 as i32) << 8 as i32; - } else if unsafe{*str.offset(0 as isize) as i32} != '-' as i32 { + } else if unsafe { *str.offset(0 as isize) as i32 } != '-' as i32 { permissions |= 0x1000000 as i32; } - if unsafe{*str.offset(1 as isize) as i32} == 'w' as i32 { + if unsafe { *str.offset(1 as isize) as i32 } == 'w' as i32 { permissions |= (1 as i32) << 7 as i32; - } else if unsafe{*str.offset(1 as isize) as i32} != '-' as i32 { + } else if unsafe { *str.offset(1 as isize) as i32 } != '-' as i32 { permissions |= 0x1000000 as i32; } - if unsafe{*str.offset(2 as isize) as i32} == 'x' as i32 { + if unsafe { *str.offset(2 as isize) as i32 } == 'x' as i32 { permissions |= (1 as i32) << 6 as i32; - } else if unsafe{*str.offset(2 as i32 as isize) as i32} == 's' as i32 { + } else if unsafe { *str.offset(2 as i32 as isize) as i32 } == 's' as i32 { permissions |= (1 as i32) << 6 as i32; permissions |= (1 as i32) << 11 as i32; - } else if unsafe{*str.offset(2 as isize) as i32} == 'S' as i32 { + } else if unsafe { *str.offset(2 as isize) as i32 } == 'S' as i32 { permissions |= (1 as i32) << 11 as i32; - } else if unsafe{*str.offset(2 as isize) as i32} != '-' as i32 { + } else if unsafe { *str.offset(2 as isize) as i32 } != '-' as i32 { permissions |= 0x1000000 as i32; } /* GROUP */ - if unsafe{*str.offset(3 as isize) as i32} == 'r' as i32 { + if unsafe { *str.offset(3 as isize) as i32 } == 'r' as i32 { permissions |= (1 as i32) << 5 as i32; - } else if unsafe{*str.offset(3 as isize) as i32} != '-' as i32 { + } else if unsafe { *str.offset(3 as isize) as i32 } != '-' as i32 { permissions |= 0x1000000 as i32; } - if unsafe{*str.offset(4 as isize) as i32} == 'w' as i32 { + if unsafe { *str.offset(4 as isize) as i32 } == 'w' as i32 { permissions |= (1 as i32) << 4 as i32; - } else if unsafe{*str.offset(4 as isize) as i32} != '-' as i32 { + } else if unsafe { *str.offset(4 as isize) as i32 } != '-' as i32 { permissions |= 0x1000000 as i32; } - if unsafe{*str.offset(5 as isize) as i32} == 'x' as i32 { + if unsafe { *str.offset(5 as isize) as i32 } == 'x' as i32 { permissions |= (1 as i32) << 3 as i32; - } else if unsafe{*str.offset(5 as isize) as i32} == 's' as i32 { + } else if unsafe { *str.offset(5 as isize) as i32 } == 's' as i32 { permissions |= (1 as i32) << 3 as i32; permissions |= (1 as i32) << 10 as i32; - } else if unsafe{*str.offset(5 as isize) as i32} == 'S' as i32 { + } else if unsafe { *str.offset(5 as isize) as i32 } == 'S' as i32 { permissions |= (1 as i32) << 10 as i32; - } else if unsafe{*str.offset(5 as isize) as i32} != '-' as i32 { + } else if unsafe { *str.offset(5 as isize) as i32 } != '-' as i32 { permissions |= 0x1000000 as i32; } /* others */ - if unsafe{*str.offset(6 as isize) as i32} == 'r' as i32 { + if unsafe { *str.offset(6 as isize) as i32 } == 'r' as i32 { permissions |= (1 as i32) << 2 as i32; - } else if unsafe{*str.offset(6 as isize) as i32} != '-' as i32 { + } else if unsafe { *str.offset(6 as isize) as i32 } != '-' as i32 { permissions |= 0x1000000 as i32; } - if unsafe{*str.offset(7 as isize) as i32} == 'w' as i32 { + if unsafe { *str.offset(7 as isize) as i32 } == 'w' as i32 { permissions |= (1 as i32) << 1 as i32; - } else if unsafe{*str.offset(7 as isize) as i32} != '-' as i32 { + } else if unsafe { *str.offset(7 as isize) as i32 } != '-' as i32 { permissions |= 0x1000000 as i32; } - if unsafe{*str.offset(8 as isize) as i32} == 'x' as i32 { + if unsafe { *str.offset(8 as isize) as i32 } == 'x' as i32 { permissions |= 1 as i32; - } else if unsafe{*str.offset(8 as isize) as i32} == 't' as i32 { + } else if unsafe { *str.offset(8 as isize) as i32 } == 't' as i32 { permissions |= 1 as i32; permissions |= (1 as i32) << 9 as i32; - } else if unsafe{*str.offset(8 as isize) as i32} == 'T' as i32 { + } else if unsafe { *str.offset(8 as isize) as i32 } == 'T' as i32 { permissions |= (1 as i32) << 9 as i32; - } else if unsafe{*str.offset(8 as isize) as i32} != '-' as i32 { + } else if unsafe { *str.offset(8 as isize) as i32 } != '-' as i32 { permissions |= 0x1000000 as i32; } return permissions; } -extern "C" fn ftp_pl_insert_finfo( - mut data: *mut Curl_easy, - mut infop: *mut fileinfo, -) -> CURLcode { +extern "C" fn ftp_pl_insert_finfo(mut data: *mut Curl_easy, mut infop: *mut fileinfo) -> CURLcode { let mut compare: curl_fnmatch_callback = None; - let mut wc: *mut WildcardData = unsafe{&mut (*data).wildcard}; - let mut ftpwc: *mut ftp_wc = unsafe{(*wc).protdata as *mut ftp_wc}; - let mut llist: *mut Curl_llist = unsafe{&mut (*wc).filelist}; - let mut parser: *mut ftp_parselist_data = unsafe{(*ftpwc).parser}; + let mut wc: *mut WildcardData = unsafe { &mut (*data).wildcard }; + let mut ftpwc: *mut ftp_wc = unsafe { (*wc).protdata as *mut ftp_wc }; + let mut llist: *mut Curl_llist = unsafe { &mut (*wc).filelist }; + let mut parser: *mut ftp_parselist_data = unsafe { (*ftpwc).parser }; let mut add: bool = 1 as i32 != 0; - let mut finfo: *mut curl_fileinfo = unsafe{&mut (*infop).info}; + let mut finfo: *mut curl_fileinfo = unsafe { &mut (*infop).info }; /* move finfo pointers to b_data */ - let mut str: *mut libc::c_char = unsafe{(*finfo).b_data}; + let mut str: *mut libc::c_char = unsafe { (*finfo).b_data }; // let ref mut fresh0 = (*finfo).filename; - unsafe{(*finfo).filename = str.offset((*parser).offsets.filename as isize); - // let ref mut fresh1 = (*finfo).strings.group; - (*finfo).strings.group = if (*parser).offsets.group != 0 { - str.offset((*parser).offsets.group as isize) - } else { - 0 as *mut libc::c_char - }; - // let ref mut fresh2 = (*finfo).strings.perm; - (*finfo).strings.perm = if (*parser).offsets.perm != 0 { - str.offset((*parser).offsets.perm as isize) - } else { - 0 as *mut libc::c_char - }; - // let ref mut fresh3 = (*finfo).strings.target; - (*finfo).strings.target = if (*parser).offsets.symlink_target != 0 { - str.offset((*parser).offsets.symlink_target as isize) - } else { - 0 as *mut libc::c_char - }; - // let ref mut fresh4 = (*finfo).strings.time; - (*finfo).strings.time = str.offset((*parser).offsets.time as isize); - // let ref mut fresh5 = (*finfo).strings.user; - (*finfo).strings.user = if (*parser).offsets.user != 0 { - str.offset((*parser).offsets.user as isize) - } else { - 0 as *mut libc::c_char - };} - /* get correct fnmatch callback */ - compare = unsafe{(*data).set.fnmatch}; + unsafe { + (*finfo).filename = str.offset((*parser).offsets.filename as isize); + // let ref mut fresh1 = (*finfo).strings.group; + (*finfo).strings.group = if (*parser).offsets.group != 0 { + str.offset((*parser).offsets.group as isize) + } else { + 0 as *mut libc::c_char + }; + // let ref mut fresh2 = (*finfo).strings.perm; + (*finfo).strings.perm = if (*parser).offsets.perm != 0 { + str.offset((*parser).offsets.perm as isize) + } else { + 0 as *mut libc::c_char + }; + // let ref mut fresh3 = (*finfo).strings.target; + (*finfo).strings.target = if (*parser).offsets.symlink_target != 0 { + str.offset((*parser).offsets.symlink_target as isize) + } else { + 0 as *mut libc::c_char + }; + // let ref mut fresh4 = (*finfo).strings.time; + (*finfo).strings.time = str.offset((*parser).offsets.time as isize); + // let ref mut fresh5 = (*finfo).strings.user; + (*finfo).strings.user = if (*parser).offsets.user != 0 { + str.offset((*parser).offsets.user as isize) + } else { + 0 as *mut libc::c_char + }; + } + /* get correct fnmatch callback */ + compare = unsafe { (*data).set.fnmatch }; if compare.is_none() { compare = Some( Curl_fnmatch @@ -197,1065 +203,1049 @@ extern "C" fn ftp_pl_insert_finfo( ); } /* filter pattern-corresponding filenames */ - unsafe{Curl_set_in_callback(data, 1 as i32 != 0);} - if unsafe{compare.expect("non-null function pointer")( - (*data).set.fnmatch_data, - (*wc).pattern, - (*finfo).filename, - )} == 0 as i32 - {/* discard symlink which is containing multiple " -> " */ - if unsafe{(*finfo).filetype} as u32 == CURLFILETYPE_SYMLINK as u32 - && unsafe{!((*finfo).strings.target).is_null()} - && unsafe{!(strstr( - (*finfo).strings.target, - b" -> \0" as *const u8 as *const libc::c_char, - )) - .is_null()} + unsafe { + Curl_set_in_callback(data, 1 as i32 != 0); + } + if unsafe { + compare.expect("non-null function pointer")( + (*data).set.fnmatch_data, + (*wc).pattern, + (*finfo).filename, + ) + } == 0 as i32 + { + /* discard symlink which is containing multiple " -> " */ + if unsafe { (*finfo).filetype } as u32 == CURLFILETYPE_SYMLINK as u32 + && unsafe { !((*finfo).strings.target).is_null() } + && unsafe { + !(strstr( + (*finfo).strings.target, + b" -> \0" as *const u8 as *const libc::c_char, + )) + .is_null() + } { add = 0 as i32 != 0; } } else { add = 0 as i32 != 0; } - unsafe{Curl_set_in_callback(data, 0 as i32 != 0);} + unsafe { + Curl_set_in_callback(data, 0 as i32 != 0); + } if add { - unsafe{Curl_llist_insert_next( - llist, - (*llist).tail, - finfo as *const libc::c_void, - &mut (*infop).list, - );} + unsafe { + Curl_llist_insert_next( + llist, + (*llist).tail, + finfo as *const libc::c_void, + &mut (*infop).list, + ); + } } else { - unsafe{Curl_fileinfo_cleanup(infop);} + unsafe { + Curl_fileinfo_cleanup(infop); + } } // let ref mut fresh6 = (*(*ftpwc).parser).file_data; - unsafe{(*(*ftpwc).parser).file_data = 0 as *mut fileinfo;} + unsafe { + (*(*ftpwc).parser).file_data = 0 as *mut fileinfo; + } return CURLE_OK; } #[no_mangle] pub extern "C" fn Curl_ftp_parselist( - mut buffer: *mut libc::c_char, - mut size: size_t, - mut nmemb: size_t, - mut connptr: *mut libc::c_void, + mut buffer: *mut libc::c_char, + mut size: size_t, + mut nmemb: size_t, + mut connptr: *mut libc::c_void, ) -> size_t { - let mut bufflen: size_t = size.wrapping_mul(nmemb); - let mut data: *mut Curl_easy = connptr as *mut Curl_easy; - let mut ftpwc: *mut ftp_wc = unsafe{(*data).wildcard.protdata as *mut ftp_wc}; - let mut parser: *mut ftp_parselist_data = unsafe{(*ftpwc).parser}; - let mut infop: *mut fileinfo = 0 as *mut fileinfo; - let mut finfo: *mut curl_fileinfo = 0 as *mut curl_fileinfo; - let mut i: u64 = 0 as i32 as u64; - let mut result: CURLcode = CURLE_OK; - let mut retsize: size_t = bufflen; + let mut bufflen: size_t = size.wrapping_mul(nmemb); + let mut data: *mut Curl_easy = connptr as *mut Curl_easy; + let mut ftpwc: *mut ftp_wc = unsafe { (*data).wildcard.protdata as *mut ftp_wc }; + let mut parser: *mut ftp_parselist_data = unsafe { (*ftpwc).parser }; + let mut infop: *mut fileinfo = 0 as *mut fileinfo; + let mut finfo: *mut curl_fileinfo = 0 as *mut curl_fileinfo; + let mut i: u64 = 0 as i32 as u64; + let mut result: CURLcode = CURLE_OK; + let mut retsize: size_t = bufflen; - 'fail: loop { - if unsafe{(*parser).error as u64} != 0 { - /* error in previous call */ - /* scenario: - * 1. call => OK.. - * 2. call => OUT_OF_MEMORY (or other error) - * 3. (last) call => is skipped RIGHT HERE and the error is hadled later - * in wc_statemach() - */ - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - if unsafe{(*parser).os_type as u32} - == OS_TYPE_UNKNOWN as u32 - && bufflen > 0 as u64 - {/* considering info about FILE response format */ - unsafe{(*parser) - .os_type = (if *buffer.offset(0 as isize) as i32 - >= '0' as i32 - && *buffer.offset(0 as isize) as i32 <= '9' as i32 - { - OS_TYPE_WIN_NT as i32 - } else { - OS_TYPE_UNIX as i32 - }) as C2RustUnnamed_22;} - } - while i < bufflen {/* FSM */ - let mut c: libc::c_char = unsafe{*buffer.offset(i as isize)}; - if unsafe{((*parser).file_data).is_null()} {/* tmp file data is not allocated yet */ - // let ref mut fresh7 = (*parser).file_data; - unsafe{(*parser).file_data = Curl_fileinfo_alloc();} - if unsafe{((*parser).file_data).is_null()} { - unsafe{(*parser).error = CURLE_OUT_OF_MEMORY;} - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - unsafe{ - match () { - #[cfg(not(CURLDEBUG))] - _ => { - (*(*parser).file_data).info.b_data = Curl_cmalloc - .expect("non-null function pointer")(160 as size_t) - as *mut libc::c_char; - } - #[cfg(CURLDEBUG)] - _ => { - (*(*parser).file_data).info.b_data = curl_dbg_malloc( - 160 as size_t, - 364 as i32, - b"ftplistparser.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char; - } - } + 'fail: loop { + if unsafe { (*parser).error as u64 } != 0 { + /* error in previous call */ + /* scenario: + * 1. call => OK.. + * 2. call => OUT_OF_MEMORY (or other error) + * 3. (last) call => is skipped RIGHT HERE and the error is hadled later + * in wc_statemach() + */ + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + if unsafe { (*parser).os_type as u32 } == OS_TYPE_UNKNOWN as u32 && bufflen > 0 as u64 { + /* considering info about FILE response format */ + unsafe { + (*parser).os_type = (if *buffer.offset(0 as isize) as i32 >= '0' as i32 + && *buffer.offset(0 as isize) as i32 <= '9' as i32 + { + OS_TYPE_WIN_NT as i32 + } else { + OS_TYPE_UNIX as i32 + }) as C2RustUnnamed_22; } - if unsafe{((*(*parser).file_data).info.b_data).is_null() }{ - unsafe{(*parser).error = CURLE_OUT_OF_MEMORY;} - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - unsafe{ - (*(*parser).file_data).info.b_size = 160 as size_t; - (*parser).item_offset = 0 as size_t; - (*parser).item_length = 0 as u32;} - } - infop = unsafe{(*parser).file_data}; - finfo = unsafe{&mut (*infop).info}; - // let ref mut fresh9 = (*finfo).b_used; - let fresh10 = unsafe{(*finfo).b_used}; - unsafe{(*finfo).b_used = ( (*finfo).b_used).wrapping_add(1); - *((*finfo).b_data).offset(fresh10 as isize) = c;} - if unsafe{(*finfo).b_used} - >= unsafe{((*finfo).b_size).wrapping_sub(1 as u64)} - { /* if it is important, extend buffer space for file data */ - #[cfg(not(CURLDEBUG))] - let mut tmp: *mut libc::c_char = unsafe{Curl_crealloc - .expect( - "non-null function pointer", - )( - (*finfo).b_data as *mut libc::c_void, - ((*finfo).b_size).wrapping_add(160 as u64), - ) as *mut libc::c_char}; - #[cfg(CURLDEBUG)] - let mut tmp: *mut libc::c_char = unsafe{curl_dbg_realloc( - (*finfo).b_data as *mut libc::c_void, - ((*finfo).b_size).wrapping_add(160 as u64), - 381 as i32, - b"ftplistparser.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char}; - if !tmp.is_null() { - // let ref mut fresh11 = (*finfo).b_size; - unsafe{(*finfo).b_size = ((*finfo).b_size as u64) - .wrapping_add(160 as u64) as size_t - as size_t; - // let ref mut fresh12 = (*finfo).b_data; - (*finfo).b_data = tmp;} - } else { - unsafe{Curl_fileinfo_cleanup((*parser).file_data); - // let ref mut fresh13 = (*parser).file_data; - (*parser).file_data = 0 as *mut fileinfo; - (*parser).error = CURLE_OUT_OF_MEMORY;} - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - unsafe{ - match (*parser).os_type as u32{ - 1 => { - match (*parser).state.UNIX.main as u32 { - 0 => { - match (*parser).state.UNIX.sub.total_dirsize as u32 { - 0 => { - if c as i32 == 't' as i32 { - (*parser) - .state - .UNIX - .sub - .total_dirsize = PL_UNIX_TOTALSIZE_READING; - // let ref mut fresh14 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - } else { - (*parser).state.UNIX.main = PL_UNIX_FILETYPE; - /* start FSM again not considering size of directory */ - (*finfo).b_used = 0 as size_t; - continue; - } - } - 1 => { - // let ref mut fresh15 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == '\r' as i32 { - // let ref mut fresh16 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_sub(1); - // let ref mut fresh17 = (*finfo).b_used; - (*finfo).b_used = ((*finfo).b_used).wrapping_sub(1); - } else if c as i32 == '\n' as i32 { - *((*finfo).b_data) - .offset( - ((*parser).item_length) - .wrapping_sub(1 as u32) as isize, - ) = 0 as libc::c_char; - if strncmp( - b"total \0" as *const u8 as *const libc::c_char, - (*finfo).b_data, - 6 as u64, - ) == 0 as i32 - { - let mut endptr: *mut libc::c_char = ((*finfo).b_data) - .offset(6 as isize); - /* here we can deal with directory size, pass the leading - whitespace and then the digits */ - while Curl_isspace(*endptr as u8 as i32) - != 0 - { - endptr = endptr.offset(1); - } - while Curl_isdigit(*endptr as u8 as i32) - != 0 - { - endptr = endptr.offset(1); - } - if *endptr != 0 { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - (*parser).state.UNIX.main = PL_UNIX_FILETYPE; - (*finfo).b_used = 0 as size_t;/* terminate permissions */ - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - } - _ => {} - } - } - 1 => { - match c as i32 { - 45 => { - (*finfo).filetype = CURLFILETYPE_FILE; - } - 100 => { - (*finfo).filetype = CURLFILETYPE_DIRECTORY; - } - 108 => { - (*finfo).filetype = CURLFILETYPE_SYMLINK; - } - 112 => { - (*finfo).filetype = CURLFILETYPE_NAMEDPIPE; - } - 115 => { - (*finfo).filetype = CURLFILETYPE_SOCKET; - } - 99 => { - (*finfo).filetype = CURLFILETYPE_DEVICE_CHAR; - } - 98 => { - (*finfo).filetype = CURLFILETYPE_DEVICE_BLOCK; - } - 68 => { - (*finfo).filetype = CURLFILETYPE_DOOR; - } - _ => { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - (*parser).state.UNIX.main = PL_UNIX_PERMISSION; - (*parser).item_length = 0 as u32; - (*parser).item_offset = 1 as size_t; - } - 2 => { - // let ref mut fresh18 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if (*parser).item_length <= 9 as u32 { - if (strchr( - b"rwx-tTsS\0" as *const u8 as *const libc::c_char, - c as i32, - )) - .is_null() - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } else if (*parser).item_length - == 10 as u32 - { - let mut perm: u32 = 0; - if c as i32 != ' ' as i32 { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - *((*finfo).b_data) - .offset( - 10 as isize, - ) = 0 as libc::c_char; - perm = ftp_pl_get_permission( - ((*finfo).b_data).offset((*parser).item_offset as isize), - ) as u32; - if perm & 0x1000000 as u32 != 0 { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - (*(*parser).file_data).info.flags - |= ((1 as i32) << 3 as i32) as u32; - (*(*parser).file_data).info.perm = perm; - (*parser).offsets.perm = (*parser).item_offset; - (*parser).item_length = 0 as u32; - (*parser).state.UNIX.main = PL_UNIX_HLINKS; - (*parser).state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE; - } - } - 3 => { - match (*parser).state.UNIX.sub.hlinks as u32 { - 0 => { - if c as i32 != ' ' as i32 { - if c as i32 >= '0' as i32 - && c as i32 <= '9' as i32 - { - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - (*parser).state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER; - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - } - 1 => { - // let ref mut fresh19 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - let mut p: *mut libc::c_char = 0 as *mut libc::c_char; - let mut hlinks: i64 = 0; - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - hlinks = strtol( - ((*finfo).b_data).offset((*parser).item_offset as isize), - &mut p, - 10 as i32, - ); - if *p.offset(0 as isize) as i32 - == '\u{0}' as i32 - && hlinks != 9223372036854775807 as i64 - && hlinks - != -(9223372036854775807 as i64) - - 1 as i64 - { - (*(*parser).file_data).info.flags - |= ((1 as i32) << 7 as i32) as u32; - (*(*parser).file_data).info.hardlinks = hlinks; - } - (*parser).item_length = 0 as u32; - (*parser).item_offset = 0 as size_t; - (*parser).state.UNIX.main = PL_UNIX_USER; - (*parser).state.UNIX.sub.user = PL_UNIX_USER_PRESPACE; - } else if (c as i32) < '0' as i32 - || c as i32 > '9' as i32 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - _ => {} - } - } - 4 => { - match (*parser).state.UNIX.sub.user as u32 { - 0 => { - if c as i32 != ' ' as i32 { - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - (*parser).state.UNIX.sub.user = PL_UNIX_USER_PARSING; - } - } - 1 => { - // let ref mut fresh20 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - (*parser).offsets.user = (*parser).item_offset; - (*parser).state.UNIX.main = PL_UNIX_GROUP; - (*parser).state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE; - (*parser).item_offset = 0 as size_t; - (*parser).item_length = 0 as u32; - } - } - _ => {} - } - } - 5 => { - match (*parser).state.UNIX.sub.group as u32 { - 0 => { - if c as i32 != ' ' as i32 { - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - (*parser).state.UNIX.sub.group = PL_UNIX_GROUP_NAME; - } - } - 1 => { - // let ref mut fresh21 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - (*parser).offsets.group = (*parser).item_offset; - (*parser).state.UNIX.main = PL_UNIX_SIZE; - (*parser).state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE; - (*parser).item_offset = 0 as size_t; - (*parser).item_length = 0 as u32; - } - } - _ => {} - } - } - 6 => { - match (*parser).state.UNIX.sub.size as u32 { - 0 => { - if c as i32 != ' ' as i32 { - if c as i32 >= '0' as i32 - && c as i32 <= '9' as i32 - { - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - (*parser).state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER; - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - } - 1 => { - // let ref mut fresh22 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - let mut p_0: *mut libc::c_char = 0 as *mut libc::c_char; - let mut fsize: curl_off_t = 0; - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - if curlx_strtoofft( - ((*finfo).b_data).offset((*parser).item_offset as isize), - &mut p_0, - 10 as i32, - &mut fsize, - ) as u64 == 0 - { - if *p_0.offset(0 as isize) as i32 - == '\u{0}' as i32 - && fsize != 0x7fffffffffffffff as i64 - && fsize - != -(0x7fffffffffffffff as i64) - 1 as i64 - { - (*(*parser).file_data).info.flags - |= ((1 as i32) << 6 as i32) as u32; - (*(*parser).file_data).info.size = fsize; - } - (*parser).item_length = 0 as u32; - (*parser).item_offset = 0 as size_t; - (*parser).state.UNIX.main = PL_UNIX_TIME; - (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PREPART1; - } - } else if Curl_isdigit(c as i32) - == 0 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - _ => {} - } - } - 7 => { - match (*parser).state.UNIX.sub.time as u32 { - 0 => { - if c as i32 != ' ' as i32 { - if Curl_isalnum(c as i32) != 0 { - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PART1; - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - } - 1 => { - // let ref mut fresh23 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PREPART2; - } else if Curl_isalnum(c as i32) - == 0 && c as i32 != '.' as i32 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - 2 => { - // let ref mut fresh24 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 != ' ' as i32 { - if Curl_isalnum(c as i32) != 0 { - (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PART2; - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - } - 3 => { - // let ref mut fresh25 = (*parser).item_length; - (*parser).item_length = ( (*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PREPART3; - } else if Curl_isalnum(c as i32) - == 0 && c as i32 != '.' as i32 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - 4 => { - // let ref mut fresh26 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 != ' ' as i32 { - if Curl_isalnum(c as i32) != 0 { - (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PART3; - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - } - 5 => { - // let ref mut fresh27 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - (*parser).offsets.time = (*parser).item_offset; - /* - if(ftp_pl_gettime(parser, finfo->b_data + parser->item_offset)) { - parser->file_data->flags |= CURLFINFOFLAG_KNOWN_TIME; - } - */ - if (*finfo).filetype as u32 - == CURLFILETYPE_SYMLINK as u32 - { - (*parser).state.UNIX.main = PL_UNIX_SYMLINK; - (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE; - } else { - (*parser).state.UNIX.main = PL_UNIX_FILENAME; - (*parser) - .state - .UNIX - .sub - .filename = PL_UNIX_FILENAME_PRESPACE; - } - } else if Curl_isalnum(c as i32) - == 0 && c as i32 != '.' as i32 - && c as i32 != ':' as i32 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - _ => {} - } - } - 8 => { - match (*parser).state.UNIX.sub.filename as u32 { - 0 => { - if c as i32 != ' ' as i32 { - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - (*parser).state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME; - } - } - 1 => { - // let ref mut fresh28 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == '\r' as i32 { - (*parser) - .state - .UNIX - .sub - .filename = PL_UNIX_FILENAME_WINDOWSEOL; - } else if c as i32 == '\n' as i32 { - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - (*parser).offsets.filename = (*parser).item_offset; - (*parser).state.UNIX.main = PL_UNIX_FILETYPE; - result = ftp_pl_insert_finfo(data, infop); - if result as u64 != 0 { - (*parser).error = result; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - } - 2 => { - if c as i32 == '\n' as i32 { - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - (*parser).offsets.filename = (*parser).item_offset; - (*parser).state.UNIX.main = PL_UNIX_FILETYPE; - result = ftp_pl_insert_finfo(data, infop); - if result as u64 != 0 { - (*parser).error = result; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - _ => {} - } - } - 9 => { - match (*parser).state.UNIX.sub.symlink as u32 { - 0 => { - if c as i32 != ' ' as i32 { - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - /* now place where is symlink following */ - } - } - 1 => { - // let ref mut fresh29 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - (*parser) - .state - .UNIX - .sub - .symlink = PL_UNIX_SYMLINK_PRETARGET1; - } else if c as i32 == '\r' as i32 - || c as i32 == '\n' as i32 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - 2 => { - // let ref mut fresh30 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == '-' as i32 { - (*parser) - .state - .UNIX - .sub - .symlink = PL_UNIX_SYMLINK_PRETARGET2; - } else if c as i32 == '\r' as i32 - || c as i32 == '\n' as i32 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } else { - (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - } - } - 3 => { - // let ref mut fresh31 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == '>' as i32 { - (*parser) - .state - .UNIX - .sub - .symlink = PL_UNIX_SYMLINK_PRETARGET3; - } else if c as i32 == '\r' as i32 - || c as i32 == '\n' as i32 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } else { - (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - } - } - 4 => { - // let ref mut fresh32 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - (*parser) - .state - .UNIX - .sub - .symlink = PL_UNIX_SYMLINK_PRETARGET4; - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(4 as u64) as isize, - ) = 0 as libc::c_char; - (*parser).offsets.filename = (*parser).item_offset; - (*parser).item_length = 0 as u32; - (*parser).item_offset = 0 as size_t; - } else if c as i32 == '\r' as i32 - || c as i32 == '\n' as i32 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } else { - (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - } - } - 5 => { - if c as i32 != '\r' as i32 - && c as i32 != '\n' as i32 - { - (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET; - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - 6 => { - // let ref mut fresh33 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == '\r' as i32 { - (*parser) - .state - .UNIX - .sub - .symlink = PL_UNIX_SYMLINK_WINDOWSEOL; - } else if c as i32 == '\n' as i32 { - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - (*parser).offsets.symlink_target = (*parser).item_offset; - result = ftp_pl_insert_finfo(data, infop); - if result as u64 != 0 { - (*parser).error = result; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - (*parser).state.UNIX.main = PL_UNIX_FILETYPE; - } - } - 7 => { - if c as i32 == '\n' as i32 { - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - (*parser).offsets.symlink_target = (*parser).item_offset; - result = ftp_pl_insert_finfo(data, infop); - if result as u64 != 0 { - (*parser).error = result; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - (*parser).state.UNIX.main = PL_UNIX_FILETYPE; - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - _ => {} - } - } - _ => {} - } - } - 2 => { - match (*parser).state.NT.main as u32 { - 0 => { - // let ref mut fresh34 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if (*parser).item_length < 9 as u32 { - if (strchr( - b"0123456789-\0" as *const u8 as *const libc::c_char, - c as i32, - )) - .is_null() - {/* only simple control */ - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } else if (*parser).item_length - == 9 as u32 - { - if c as i32 == ' ' as i32 { - (*parser).state.NT.main = PL_WINNT_TIME; - (*parser).state.NT.sub.time = PL_WINNT_TIME_PRESPACE; - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - 1 => { - // let ref mut fresh35 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - match (*parser).state.NT.sub.time as u32 { - 0 => { - if Curl_isspace(c as i32) == 0 { - (*parser).state.NT.sub.time = PL_WINNT_TIME_TIME; - } - } - 1 => { - if c as i32 == ' ' as i32 { - (*parser).offsets.time = (*parser).item_offset; - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - (*parser).state.NT.main = PL_WINNT_DIRORSIZE; - (*parser) - .state - .NT - .sub - .dirorsize = PL_WINNT_DIRORSIZE_PRESPACE; - (*parser).item_length = 0 as u32; - } else if (strchr( - b"APM0123456789:\0" as *const u8 as *const libc::c_char, - c as i32, - )) - .is_null() - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - _ => {} - } - } - 2 => { - match (*parser).state.NT.sub.dirorsize as u32 { - 0 => { - if c as i32 != ' ' as i32 { - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - (*parser) - .state - .NT - .sub - .dirorsize = PL_WINNT_DIRORSIZE_CONTENT; - } - } - 1 => { - // let ref mut fresh36 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == ' ' as i32 { - *((*finfo).b_data) - .offset( - ((*parser).item_offset) - .wrapping_add((*parser).item_length as u64) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - if strcmp( - b"\0" as *const u8 as *const libc::c_char, - ((*finfo).b_data).offset((*parser).item_offset as isize), - ) == 0 as i32 - { - (*finfo).filetype = CURLFILETYPE_DIRECTORY; - (*finfo).size = 0 as curl_off_t; - } else { - let mut endptr_0: *mut libc::c_char = 0 - as *mut libc::c_char; - if curlx_strtoofft( - ((*finfo).b_data).offset((*parser).item_offset as isize), - &mut endptr_0, - 10 as i32, - &mut (*finfo).size, - ) as u64 != 0 - { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - /* correct file type */ - (*(*parser).file_data).info.filetype = CURLFILETYPE_FILE; - } - (*(*parser).file_data).info.flags - |= ((1 as i32) << 6 as i32) as u32; - (*parser).item_length = 0 as u32; - (*parser).state.NT.main = PL_WINNT_FILENAME; - (*parser) - .state - .NT - .sub - .filename = PL_WINNT_FILENAME_PRESPACE; - } - } - _ => {} - } - } - 3 => { - match (*parser).state.NT.sub.filename as u32 { - 0 => { - if c as i32 != ' ' as i32 { - (*parser) - .item_offset = ((*finfo).b_used) - .wrapping_sub(1 as u64); - (*parser).item_length = 1 as u32; - (*parser).state.NT.sub.filename = PL_WINNT_FILENAME_CONTENT; - } - } - 1 => { - // let ref mut fresh37 = (*parser).item_length; - (*parser).item_length = ((*parser).item_length).wrapping_add(1); - if c as i32 == '\r' as i32 { - (*parser).state.NT.sub.filename = PL_WINNT_FILENAME_WINEOL; - *((*finfo).b_data) - .offset( - ((*finfo).b_used) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - } else if c as i32 == '\n' as i32 { - (*parser).offsets.filename = (*parser).item_offset; - *((*finfo).b_data) - .offset( - ((*finfo).b_used) - .wrapping_sub(1 as u64) as isize, - ) = 0 as libc::c_char; - result = ftp_pl_insert_finfo(data, infop); - if result as u64 != 0 { - (*parser).error = result; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - (*parser).state.NT.main = PL_WINNT_DATE; - (*parser) - .state - .NT - .sub - .filename = PL_WINNT_FILENAME_PRESPACE; - } - } - 2 => { - if c as i32 == '\n' as i32 { - (*parser).offsets.filename = (*parser).item_offset; - result = ftp_pl_insert_finfo(data, infop); - if result as u64 != 0 { - (*parser).error = result; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - (*parser).state.NT.main = PL_WINNT_DATE; - (*parser) - .state - .NT - .sub - .filename = PL_WINNT_FILENAME_PRESPACE; - } else { - (*parser).error = CURLE_FTP_BAD_FILE_LIST; - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } - _ => {} - } - } - _ => {} - } - } - _ => { - retsize = bufflen.wrapping_add(1 as u64); - // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); - break 'fail; - } - } } - i = i.wrapping_add(1); - } - // original normal exit - return retsize; - break 'fail; - - } - + while i < bufflen { + /* FSM */ + let mut c: libc::c_char = unsafe { *buffer.offset(i as isize) }; + if unsafe { ((*parser).file_data).is_null() } { + /* tmp file data is not allocated yet */ + // let ref mut fresh7 = (*parser).file_data; + unsafe { + (*parser).file_data = Curl_fileinfo_alloc(); + } + if unsafe { ((*parser).file_data).is_null() } { + unsafe { + (*parser).error = CURLE_OUT_OF_MEMORY; + } + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + unsafe { + match () { + #[cfg(not(CURLDEBUG))] + _ => { + (*(*parser).file_data).info.b_data = + Curl_cmalloc.expect("non-null function pointer")(160 as size_t) + as *mut libc::c_char; + } + #[cfg(CURLDEBUG)] + _ => { + (*(*parser).file_data).info.b_data = curl_dbg_malloc( + 160 as size_t, + 364 as i32, + b"ftplistparser.c\0" as *const u8 as *const libc::c_char, + ) + as *mut libc::c_char; + } + } + } + if unsafe { ((*(*parser).file_data).info.b_data).is_null() } { + unsafe { + (*parser).error = CURLE_OUT_OF_MEMORY; + } + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + unsafe { + (*(*parser).file_data).info.b_size = 160 as size_t; + (*parser).item_offset = 0 as size_t; + (*parser).item_length = 0 as u32; + } + } + infop = unsafe { (*parser).file_data }; + finfo = unsafe { &mut (*infop).info }; + // let ref mut fresh9 = (*finfo).b_used; + let fresh10 = unsafe { (*finfo).b_used }; + unsafe { + (*finfo).b_used = ((*finfo).b_used).wrapping_add(1); + *((*finfo).b_data).offset(fresh10 as isize) = c; + } + if unsafe { (*finfo).b_used } >= unsafe { ((*finfo).b_size).wrapping_sub(1 as u64) } { + /* if it is important, extend buffer space for file data */ + #[cfg(not(CURLDEBUG))] + let mut tmp: *mut libc::c_char = unsafe { + Curl_crealloc.expect("non-null function pointer")( + (*finfo).b_data as *mut libc::c_void, + ((*finfo).b_size).wrapping_add(160 as u64), + ) as *mut libc::c_char + }; + #[cfg(CURLDEBUG)] + let mut tmp: *mut libc::c_char = unsafe { + curl_dbg_realloc( + (*finfo).b_data as *mut libc::c_void, + ((*finfo).b_size).wrapping_add(160 as u64), + 381 as i32, + b"ftplistparser.c\0" as *const u8 as *const libc::c_char, + ) as *mut libc::c_char + }; + if !tmp.is_null() { + // let ref mut fresh11 = (*finfo).b_size; + unsafe { + (*finfo).b_size = + ((*finfo).b_size as u64).wrapping_add(160 as u64) as size_t as size_t; + // let ref mut fresh12 = (*finfo).b_data; + (*finfo).b_data = tmp; + } + } else { + unsafe { + Curl_fileinfo_cleanup((*parser).file_data); + // let ref mut fresh13 = (*parser).file_data; + (*parser).file_data = 0 as *mut fileinfo; + (*parser).error = CURLE_OUT_OF_MEMORY; + } + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + unsafe { + match (*parser).os_type as u32 { + 1 => { + match (*parser).state.UNIX.main as u32 { + 0 => { + match (*parser).state.UNIX.sub.total_dirsize as u32 { + 0 => { + if c as i32 == 't' as i32 { + (*parser).state.UNIX.sub.total_dirsize = + PL_UNIX_TOTALSIZE_READING; + // let ref mut fresh14 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + } else { + (*parser).state.UNIX.main = PL_UNIX_FILETYPE; + /* start FSM again not considering size of directory */ + (*finfo).b_used = 0 as size_t; + continue; + } + } + 1 => { + // let ref mut fresh15 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == '\r' as i32 { + // let ref mut fresh16 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_sub(1); + // let ref mut fresh17 = (*finfo).b_used; + (*finfo).b_used = ((*finfo).b_used).wrapping_sub(1); + } else if c as i32 == '\n' as i32 { + *((*finfo).b_data).offset( + ((*parser).item_length).wrapping_sub(1 as u32) + as isize, + ) = 0 as libc::c_char; + if strncmp( + b"total \0" as *const u8 as *const libc::c_char, + (*finfo).b_data, + 6 as u64, + ) == 0 as i32 + { + let mut endptr: *mut libc::c_char = + ((*finfo).b_data).offset(6 as isize); + /* here we can deal with directory size, pass the leading + whitespace and then the digits */ + while Curl_isspace(*endptr as u8 as i32) != 0 { + endptr = endptr.offset(1); + } + while Curl_isdigit(*endptr as u8 as i32) != 0 { + endptr = endptr.offset(1); + } + if *endptr != 0 { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + (*parser).state.UNIX.main = PL_UNIX_FILETYPE; + (*finfo).b_used = 0 as size_t; /* terminate permissions */ + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + } + _ => {} + } + } + 1 => { + match c as i32 { + 45 => { + (*finfo).filetype = CURLFILETYPE_FILE; + } + 100 => { + (*finfo).filetype = CURLFILETYPE_DIRECTORY; + } + 108 => { + (*finfo).filetype = CURLFILETYPE_SYMLINK; + } + 112 => { + (*finfo).filetype = CURLFILETYPE_NAMEDPIPE; + } + 115 => { + (*finfo).filetype = CURLFILETYPE_SOCKET; + } + 99 => { + (*finfo).filetype = CURLFILETYPE_DEVICE_CHAR; + } + 98 => { + (*finfo).filetype = CURLFILETYPE_DEVICE_BLOCK; + } + 68 => { + (*finfo).filetype = CURLFILETYPE_DOOR; + } + _ => { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + (*parser).state.UNIX.main = PL_UNIX_PERMISSION; + (*parser).item_length = 0 as u32; + (*parser).item_offset = 1 as size_t; + } + 2 => { + // let ref mut fresh18 = (*parser).item_length; + (*parser).item_length = ((*parser).item_length).wrapping_add(1); + if (*parser).item_length <= 9 as u32 { + if (strchr( + b"rwx-tTsS\0" as *const u8 as *const libc::c_char, + c as i32, + )) + .is_null() + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } else if (*parser).item_length == 10 as u32 { + let mut perm: u32 = 0; + if c as i32 != ' ' as i32 { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + *((*finfo).b_data).offset(10 as isize) = 0 as libc::c_char; + perm = ftp_pl_get_permission( + ((*finfo).b_data).offset((*parser).item_offset as isize), + ) as u32; + if perm & 0x1000000 as u32 != 0 { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + (*(*parser).file_data).info.flags |= + ((1 as i32) << 3 as i32) as u32; + (*(*parser).file_data).info.perm = perm; + (*parser).offsets.perm = (*parser).item_offset; + (*parser).item_length = 0 as u32; + (*parser).state.UNIX.main = PL_UNIX_HLINKS; + (*parser).state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE; + } + } + 3 => { + match (*parser).state.UNIX.sub.hlinks as u32 { + 0 => { + if c as i32 != ' ' as i32 { + if c as i32 >= '0' as i32 && c as i32 <= '9' as i32 { + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + (*parser).state.UNIX.sub.hlinks = + PL_UNIX_HLINKS_NUMBER; + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + } + 1 => { + // let ref mut fresh19 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut hlinks: i64 = 0; + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + hlinks = strtol( + ((*finfo).b_data) + .offset((*parser).item_offset as isize), + &mut p, + 10 as i32, + ); + if *p.offset(0 as isize) as i32 == '\u{0}' as i32 + && hlinks != 9223372036854775807 as i64 + && hlinks + != -(9223372036854775807 as i64) - 1 as i64 + { + (*(*parser).file_data).info.flags |= + ((1 as i32) << 7 as i32) as u32; + (*(*parser).file_data).info.hardlinks = hlinks; + } + (*parser).item_length = 0 as u32; + (*parser).item_offset = 0 as size_t; + (*parser).state.UNIX.main = PL_UNIX_USER; + (*parser).state.UNIX.sub.user = PL_UNIX_USER_PRESPACE; + } else if (c as i32) < '0' as i32 || c as i32 > '9' as i32 { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + _ => {} + } + } + 4 => { + match (*parser).state.UNIX.sub.user as u32 { + 0 => { + if c as i32 != ' ' as i32 { + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + (*parser).state.UNIX.sub.user = PL_UNIX_USER_PARSING; + } + } + 1 => { + // let ref mut fresh20 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + (*parser).offsets.user = (*parser).item_offset; + (*parser).state.UNIX.main = PL_UNIX_GROUP; + (*parser).state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE; + (*parser).item_offset = 0 as size_t; + (*parser).item_length = 0 as u32; + } + } + _ => {} + } + } + 5 => { + match (*parser).state.UNIX.sub.group as u32 { + 0 => { + if c as i32 != ' ' as i32 { + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + (*parser).state.UNIX.sub.group = PL_UNIX_GROUP_NAME; + } + } + 1 => { + // let ref mut fresh21 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + (*parser).offsets.group = (*parser).item_offset; + (*parser).state.UNIX.main = PL_UNIX_SIZE; + (*parser).state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE; + (*parser).item_offset = 0 as size_t; + (*parser).item_length = 0 as u32; + } + } + _ => {} + } + } + 6 => { + match (*parser).state.UNIX.sub.size as u32 { + 0 => { + if c as i32 != ' ' as i32 { + if c as i32 >= '0' as i32 && c as i32 <= '9' as i32 { + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + (*parser).state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER; + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + } + 1 => { + // let ref mut fresh22 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + let mut p_0: *mut libc::c_char = 0 as *mut libc::c_char; + let mut fsize: curl_off_t = 0; + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + if curlx_strtoofft( + ((*finfo).b_data) + .offset((*parser).item_offset as isize), + &mut p_0, + 10 as i32, + &mut fsize, + ) as u64 + == 0 + { + if *p_0.offset(0 as isize) as i32 == '\u{0}' as i32 + && fsize != 0x7fffffffffffffff as i64 + && fsize + != -(0x7fffffffffffffff as i64) - 1 as i64 + { + (*(*parser).file_data).info.flags |= + ((1 as i32) << 6 as i32) as u32; + (*(*parser).file_data).info.size = fsize; + } + (*parser).item_length = 0 as u32; + (*parser).item_offset = 0 as size_t; + (*parser).state.UNIX.main = PL_UNIX_TIME; + (*parser).state.UNIX.sub.time = + PL_UNIX_TIME_PREPART1; + } + } else if Curl_isdigit(c as i32) == 0 { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + _ => {} + } + } + 7 => { + match (*parser).state.UNIX.sub.time as u32 { + 0 => { + if c as i32 != ' ' as i32 { + if Curl_isalnum(c as i32) != 0 { + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PART1; + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + } + 1 => { + // let ref mut fresh23 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PREPART2; + } else if Curl_isalnum(c as i32) == 0 + && c as i32 != '.' as i32 + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + 2 => { + // let ref mut fresh24 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 != ' ' as i32 { + if Curl_isalnum(c as i32) != 0 { + (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PART2; + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + } + 3 => { + // let ref mut fresh25 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PREPART3; + } else if Curl_isalnum(c as i32) == 0 + && c as i32 != '.' as i32 + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + 4 => { + // let ref mut fresh26 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 != ' ' as i32 { + if Curl_isalnum(c as i32) != 0 { + (*parser).state.UNIX.sub.time = PL_UNIX_TIME_PART3; + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + } + 5 => { + // let ref mut fresh27 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + (*parser).offsets.time = (*parser).item_offset; + /* + if(ftp_pl_gettime(parser, finfo->b_data + parser->item_offset)) { + parser->file_data->flags |= CURLFINFOFLAG_KNOWN_TIME; + } + */ + if (*finfo).filetype as u32 + == CURLFILETYPE_SYMLINK as u32 + { + (*parser).state.UNIX.main = PL_UNIX_SYMLINK; + (*parser).state.UNIX.sub.symlink = + PL_UNIX_SYMLINK_PRESPACE; + } else { + (*parser).state.UNIX.main = PL_UNIX_FILENAME; + (*parser).state.UNIX.sub.filename = + PL_UNIX_FILENAME_PRESPACE; + } + } else if Curl_isalnum(c as i32) == 0 + && c as i32 != '.' as i32 + && c as i32 != ':' as i32 + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + _ => {} + } + } + 8 => { + match (*parser).state.UNIX.sub.filename as u32 { + 0 => { + if c as i32 != ' ' as i32 { + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + (*parser).state.UNIX.sub.filename = + PL_UNIX_FILENAME_NAME; + } + } + 1 => { + // let ref mut fresh28 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == '\r' as i32 { + (*parser).state.UNIX.sub.filename = + PL_UNIX_FILENAME_WINDOWSEOL; + } else if c as i32 == '\n' as i32 { + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + (*parser).offsets.filename = (*parser).item_offset; + (*parser).state.UNIX.main = PL_UNIX_FILETYPE; + result = ftp_pl_insert_finfo(data, infop); + if result as u64 != 0 { + (*parser).error = result; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + } + 2 => { + if c as i32 == '\n' as i32 { + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + (*parser).offsets.filename = (*parser).item_offset; + (*parser).state.UNIX.main = PL_UNIX_FILETYPE; + result = ftp_pl_insert_finfo(data, infop); + if result as u64 != 0 { + (*parser).error = result; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + _ => {} + } + } + 9 => { + match (*parser).state.UNIX.sub.symlink as u32 { + 0 => { + if c as i32 != ' ' as i32 { + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + /* now place where is symlink following */ + } + } + 1 => { + // let ref mut fresh29 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + (*parser).state.UNIX.sub.symlink = + PL_UNIX_SYMLINK_PRETARGET1; + } else if c as i32 == '\r' as i32 || c as i32 == '\n' as i32 + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + 2 => { + // let ref mut fresh30 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == '-' as i32 { + (*parser).state.UNIX.sub.symlink = + PL_UNIX_SYMLINK_PRETARGET2; + } else if c as i32 == '\r' as i32 || c as i32 == '\n' as i32 + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } else { + (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + } + } + 3 => { + // let ref mut fresh31 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == '>' as i32 { + (*parser).state.UNIX.sub.symlink = + PL_UNIX_SYMLINK_PRETARGET3; + } else if c as i32 == '\r' as i32 || c as i32 == '\n' as i32 + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } else { + (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + } + } + 4 => { + // let ref mut fresh32 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + (*parser).state.UNIX.sub.symlink = + PL_UNIX_SYMLINK_PRETARGET4; + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(4 as u64) + as isize, + ) = 0 as libc::c_char; + (*parser).offsets.filename = (*parser).item_offset; + (*parser).item_length = 0 as u32; + (*parser).item_offset = 0 as size_t; + } else if c as i32 == '\r' as i32 || c as i32 == '\n' as i32 + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } else { + (*parser).state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + } + } + 5 => { + if c as i32 != '\r' as i32 && c as i32 != '\n' as i32 { + (*parser).state.UNIX.sub.symlink = + PL_UNIX_SYMLINK_TARGET; + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + 6 => { + // let ref mut fresh33 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == '\r' as i32 { + (*parser).state.UNIX.sub.symlink = + PL_UNIX_SYMLINK_WINDOWSEOL; + } else if c as i32 == '\n' as i32 { + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + (*parser).offsets.symlink_target = + (*parser).item_offset; + result = ftp_pl_insert_finfo(data, infop); + if result as u64 != 0 { + (*parser).error = result; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + (*parser).state.UNIX.main = PL_UNIX_FILETYPE; + } + } + 7 => { + if c as i32 == '\n' as i32 { + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + (*parser).offsets.symlink_target = + (*parser).item_offset; + result = ftp_pl_insert_finfo(data, infop); + if result as u64 != 0 { + (*parser).error = result; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + (*parser).state.UNIX.main = PL_UNIX_FILETYPE; + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + _ => {} + } + } + _ => {} + } + } + 2 => { + match (*parser).state.NT.main as u32 { + 0 => { + // let ref mut fresh34 = (*parser).item_length; + (*parser).item_length = ((*parser).item_length).wrapping_add(1); + if (*parser).item_length < 9 as u32 { + if (strchr( + b"0123456789-\0" as *const u8 as *const libc::c_char, + c as i32, + )) + .is_null() + { + /* only simple control */ + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } else if (*parser).item_length == 9 as u32 { + if c as i32 == ' ' as i32 { + (*parser).state.NT.main = PL_WINNT_TIME; + (*parser).state.NT.sub.time = PL_WINNT_TIME_PRESPACE; + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + 1 => { + // let ref mut fresh35 = (*parser).item_length; + (*parser).item_length = ((*parser).item_length).wrapping_add(1); + match (*parser).state.NT.sub.time as u32 { + 0 => { + if Curl_isspace(c as i32) == 0 { + (*parser).state.NT.sub.time = PL_WINNT_TIME_TIME; + } + } + 1 => { + if c as i32 == ' ' as i32 { + (*parser).offsets.time = (*parser).item_offset; + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + (*parser).state.NT.main = PL_WINNT_DIRORSIZE; + (*parser).state.NT.sub.dirorsize = + PL_WINNT_DIRORSIZE_PRESPACE; + (*parser).item_length = 0 as u32; + } else if (strchr( + b"APM0123456789:\0" as *const u8 as *const libc::c_char, + c as i32, + )) + .is_null() + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + _ => {} + } + } + 2 => { + match (*parser).state.NT.sub.dirorsize as u32 { + 0 => { + if c as i32 != ' ' as i32 { + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + (*parser).state.NT.sub.dirorsize = + PL_WINNT_DIRORSIZE_CONTENT; + } + } + 1 => { + // let ref mut fresh36 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == ' ' as i32 { + *((*finfo).b_data).offset( + ((*parser).item_offset) + .wrapping_add((*parser).item_length as u64) + .wrapping_sub(1 as u64) + as isize, + ) = 0 as libc::c_char; + if strcmp( + b"\0" as *const u8 as *const libc::c_char, + ((*finfo).b_data) + .offset((*parser).item_offset as isize), + ) == 0 as i32 + { + (*finfo).filetype = CURLFILETYPE_DIRECTORY; + (*finfo).size = 0 as curl_off_t; + } else { + let mut endptr_0: *mut libc::c_char = + 0 as *mut libc::c_char; + if curlx_strtoofft( + ((*finfo).b_data) + .offset((*parser).item_offset as isize), + &mut endptr_0, + 10 as i32, + &mut (*finfo).size, + ) + as u64 + != 0 + { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + /* correct file type */ + (*(*parser).file_data).info.filetype = + CURLFILETYPE_FILE; + } + (*(*parser).file_data).info.flags |= + ((1 as i32) << 6 as i32) as u32; + (*parser).item_length = 0 as u32; + (*parser).state.NT.main = PL_WINNT_FILENAME; + (*parser).state.NT.sub.filename = + PL_WINNT_FILENAME_PRESPACE; + } + } + _ => {} + } + } + 3 => { + match (*parser).state.NT.sub.filename as u32 { + 0 => { + if c as i32 != ' ' as i32 { + (*parser).item_offset = + ((*finfo).b_used).wrapping_sub(1 as u64); + (*parser).item_length = 1 as u32; + (*parser).state.NT.sub.filename = + PL_WINNT_FILENAME_CONTENT; + } + } + 1 => { + // let ref mut fresh37 = (*parser).item_length; + (*parser).item_length = + ((*parser).item_length).wrapping_add(1); + if c as i32 == '\r' as i32 { + (*parser).state.NT.sub.filename = + PL_WINNT_FILENAME_WINEOL; + *((*finfo).b_data) + .offset(((*finfo).b_used).wrapping_sub(1 as u64) + as isize) = 0 as libc::c_char; + } else if c as i32 == '\n' as i32 { + (*parser).offsets.filename = (*parser).item_offset; + *((*finfo).b_data) + .offset(((*finfo).b_used).wrapping_sub(1 as u64) + as isize) = 0 as libc::c_char; + result = ftp_pl_insert_finfo(data, infop); + if result as u64 != 0 { + (*parser).error = result; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + (*parser).state.NT.main = PL_WINNT_DATE; + (*parser).state.NT.sub.filename = + PL_WINNT_FILENAME_PRESPACE; + } + } + 2 => { + if c as i32 == '\n' as i32 { + (*parser).offsets.filename = (*parser).item_offset; + result = ftp_pl_insert_finfo(data, infop); + if result as u64 != 0 { + (*parser).error = result; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + (*parser).state.NT.main = PL_WINNT_DATE; + (*parser).state.NT.sub.filename = + PL_WINNT_FILENAME_PRESPACE; + } else { + (*parser).error = CURLE_FTP_BAD_FILE_LIST; + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + _ => {} + } + } + _ => {} + } + } + _ => { + retsize = bufflen.wrapping_add(1 as u64); + // printf(b"hanxj\n\0" as *const u8 as *const libc::c_char); + break 'fail; + } + } + } + i = i.wrapping_add(1); + } + // original normal exit + return retsize; + break 'fail; + } - // original label fail + // original label fail /* Clean up any allocated memory. */ - if unsafe{!((*parser).file_data).is_null() }{ - unsafe{Curl_fileinfo_cleanup((*parser).file_data); - // let ref mut fresh38 = (*parser).file_data; - (*parser).file_data = 0 as *mut fileinfo;} - } - return retsize; + if unsafe { !((*parser).file_data).is_null() } { + unsafe { + Curl_fileinfo_cleanup((*parser).file_data); + // let ref mut fresh38 = (*parser).file_data; + (*parser).file_data = 0 as *mut fileinfo; + } + } + return retsize; } diff --git a/rust/rust_project/src/http.rs b/rust/rust_project/src/http.rs index f72ad1f..2258caa 100644 --- a/rust/rust_project/src/http.rs +++ b/rust/rust_project/src/http.rs @@ -170,16 +170,15 @@ pub static mut Curl_handler_https: Curl_handler = Curl_handler { flags: PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | PROTOPT_USERPWDCTRL, }; - extern "C" fn http_setup_conn( +extern "C" fn http_setup_conn( mut data: *mut Curl_easy, mut conn: *mut connectdata, ) -> CURLcode { /* allocate the HTTP-specific struct for the Curl_easy, only to survive during this request */ let mut http: *mut HTTP = 0 as *mut HTTP; - unsafe{ #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ((*data).req.p.http).is_null() { + unsafe {if ((*data).req.p.http).is_null() { } else { __assert_fail( b"data->req.p.http == ((void*)0)\0" as *const u8 as *const libc::c_char, @@ -193,12 +192,12 @@ pub static mut Curl_handler_https: Curl_handler = Curl_handler { }} #[cfg(not(CURLDEBUG))] - let mut new_http: *mut HTTP = unsafe{Curl_ccalloc.expect("non-null function pointer")( + let mut new_http: *mut HTTP =unsafe { Curl_ccalloc.expect("non-null function pointer")( 1 as size_t, ::std::mem::size_of::() as u64, ) as *mut HTTP}; #[cfg(CURLDEBUG)] - let mut new_http: *mut HTTP = unsafe{curl_dbg_calloc( + let mut new_http: *mut HTTP = unsafe {curl_dbg_calloc( 1 as size_t, ::std::mem::size_of::() as u64, 181, @@ -209,7 +208,7 @@ pub static mut Curl_handler_https: Curl_handler = Curl_handler { if http.is_null() { return CURLE_OUT_OF_MEMORY; } - unsafe{ + unsafe { #[cfg(any( all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), not(CURL_DISABLE_SMTP), @@ -250,30 +249,30 @@ pub static mut Curl_handler_https: Curl_handler = Curl_handler { * prefix without colon! */ #[no_mangle] -pub extern "C" fn Curl_checkProxyheaders( +pub extern "C" fn Curl_checkProxyheaders( mut data: *mut Curl_easy, mut conn: *const connectdata, mut thisheader: *const libc::c_char, ) -> *mut libc::c_char { let mut head: *mut curl_slist = 0 as *mut curl_slist; - let mut thislen: size_t = unsafe{strlen(thisheader)}; - - head = unsafe{if ((*conn).bits).proxy() as i32 != 0 && ((*data).set).sep_headers() as i32 != 0 { + let mut thislen: size_t =unsafe { strlen(thisheader)}; + unsafe { + head = if ((*conn).bits).proxy() as i32 != 0 && ((*data).set).sep_headers() as i32 != 0 { (*data).set.proxyheaders } else { (*data).set.headers - }}; + }; while !head.is_null() { - if unsafe{Curl_strncasecompare((*head).data, thisheader, thislen) != 0 + if Curl_strncasecompare((*head).data, thisheader, thislen) != 0 && (*((*head).data).offset(thislen as isize) as i32 == ':' as i32 - || *((*head).data).offset(thislen as isize) as i32 == ';' as i32)} + || *((*head).data).offset(thislen as isize) as i32 == ';' as i32) { - return unsafe{(*head).data}; + return (*head).data; } - head = unsafe{(*head).next}; + head = (*head).next; + } } - return 0 as *mut libc::c_char; } @@ -285,7 +284,8 @@ pub extern "C" fn Curl_checkProxyheaders( mut conn: *const connectdata, mut thisheader: *const libc::c_char, ) -> *mut libc::c_char { - return 0 as *mut libc::c_char; + unsafe { + return 0 as *mut libc::c_char;} } /* @@ -295,7 +295,7 @@ pub extern "C" fn Curl_checkProxyheaders( * consists entirely of whitespace. */ #[no_mangle] -pub extern "C" fn Curl_copy_header_value( +pub extern "C" fn Curl_copy_header_value( mut header: *const libc::c_char, ) -> *mut libc::c_char { let mut start: *const libc::c_char = 0 as *const libc::c_char; @@ -304,47 +304,47 @@ pub extern "C" fn Curl_copy_header_value( let mut len: size_t = 0; /* Find the end of the header name */ - while unsafe{*header as i32 != 0 && *header as i32 != ':' as i32} { - header = unsafe{header.offset(1)}; + while unsafe {*header as i32 != 0 && *header as i32 != ':' as i32} { + header = unsafe {header.offset(1)}; } - if unsafe{*header != 0 }{ + if unsafe {*header != 0} { /* Skip over colon */ - header = unsafe{header.offset(1)}; + header = unsafe {header.offset(1)}; } /* Find the first non-space letter */ start = header; - while unsafe{*start as i32 != 0 && Curl_isspace(*start as u8 as i32) != 0} { - start = unsafe{start.offset(1)}; + while unsafe {*start as i32 != 0 && Curl_isspace(*start as u8 as i32) != 0} { + start = unsafe {start.offset(1)}; } /* data is in the host encoding so use '\r' and '\n' instead of 0x0d and 0x0a */ - end = unsafe{strchr(start, '\r' as i32)}; + end = unsafe {strchr(start, '\r' as i32)}; if end.is_null() { - end = unsafe{strchr(start, '\n' as i32)}; + end = unsafe {strchr(start, '\n' as i32)}; } if end.is_null() { - end = unsafe{strchr(start, '\0' as i32)}; + end = unsafe {strchr(start, '\0' as i32)}; } if end.is_null() { return 0 as *mut libc::c_char; } /* skip all trailing space letters */ - while end > start && unsafe{Curl_isspace(*end as u8 as i32) != 0} { - end = unsafe{end.offset(-1)}; + while unsafe {end > start && Curl_isspace(*end as u8 as i32) != 0} { + end =unsafe { end.offset(-1)}; } /* get length of the type */ - len = unsafe{(end.offset_from(start) as i64 + 1 as i64) as size_t}; + len = unsafe {(end.offset_from(start) as i64 + 1 as i64) as size_t}; #[cfg(not(CURLDEBUG))] - let mut new_value: *mut libc::c_char = - unsafe{Curl_cmalloc.expect("non-null function pointer")(len.wrapping_add(1 as u64)) + let mut new_value: *mut libc::c_char =unsafe { + Curl_cmalloc.expect("non-null function pointer")(len.wrapping_add(1 as i32 as u64)) as *mut libc::c_char}; #[cfg(CURLDEBUG)] - let mut new_value: *mut libc::c_char = unsafe{curl_dbg_malloc( + let mut new_value: *mut libc::c_char =unsafe { curl_dbg_malloc( len.wrapping_add(1 as u64), 282, b"http.c\0" as *const u8 as *const libc::c_char, @@ -353,12 +353,12 @@ pub extern "C" fn Curl_copy_header_value( if value.is_null() { return 0 as *mut libc::c_char; } - unsafe{ memcpy( + unsafe {memcpy( value as *mut libc::c_void, start as *const libc::c_void, len, ); - *value.offset(len as isize) = 0 as libc::c_char;} /* null-terminate */ + *value.offset(len as isize) = 0 as libc::c_char; /* null-terminate */} return value; } @@ -369,7 +369,7 @@ pub extern "C" fn Curl_copy_header_value( * * Returns CURLcode. */ - extern "C" fn http_output_basic(mut data: *mut Curl_easy, mut proxy: bool) -> CURLcode { +extern "C" fn http_output_basic(mut data: *mut Curl_easy, mut proxy: bool) -> CURLcode { let mut size: size_t = 0 as size_t; let mut authorization: *mut libc::c_char = 0 as *mut libc::c_char; let mut userp: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; @@ -377,16 +377,16 @@ pub extern "C" fn Curl_copy_header_value( let mut pwd: *const libc::c_char = 0 as *const libc::c_char; let mut result: CURLcode = CURLE_OK; let mut out: *mut libc::c_char = 0 as *mut libc::c_char; - + unsafe { /* credentials are unique per transfer for HTTP, do not use the ones for the connection */ if proxy { match () { #[cfg(not(CURL_DISABLE_PROXY))] _ => { - userp = unsafe{&mut (*data).state.aptr.proxyuserpwd}; - user = unsafe{(*data).state.aptr.proxyuser}; - pwd = unsafe{(*data).state.aptr.proxypasswd}; + userp = &mut (*data).state.aptr.proxyuserpwd; + user = (*data).state.aptr.proxyuser; + pwd = (*data).state.aptr.proxypasswd; } #[cfg(CURL_DISABLE_PROXY)] _ => { @@ -394,12 +394,12 @@ pub extern "C" fn Curl_copy_header_value( } } } else { - userp = unsafe{&mut (*data).state.aptr.userpwd}; - user = unsafe{(*data).state.aptr.user}; - pwd = unsafe{(*data).state.aptr.passwd}; + userp = &mut (*data).state.aptr.userpwd; + user = (*data).state.aptr.user; + pwd = (*data).state.aptr.passwd; } - out =unsafe{ curl_maprintf( + out = curl_maprintf( b"%s:%s\0" as *const u8 as *const libc::c_char, user, if !pwd.is_null() { @@ -407,16 +407,16 @@ pub extern "C" fn Curl_copy_header_value( } else { b"\0" as *const u8 as *const libc::c_char }, - )}; + ); if out.is_null() { return CURLE_OUT_OF_MEMORY; } - result = unsafe{Curl_base64_encode(data, out, strlen(out), &mut authorization, &mut size)}; + result = Curl_base64_encode(data, out, strlen(out), &mut authorization, &mut size); if !(result as u64 != 0) { if authorization.is_null() { result = CURLE_REMOTE_ACCESS_DENIED; - } else {unsafe{ + } else { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(*userp as *mut libc::c_void); #[cfg(CURLDEBUG)] @@ -444,10 +444,9 @@ pub extern "C" fn Curl_copy_header_value( ); if (*userp).is_null() { result = CURLE_OUT_OF_MEMORY; - }} + } } } - unsafe{ #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(out as *mut libc::c_void); #[cfg(CURLDEBUG)] @@ -455,8 +454,8 @@ pub extern "C" fn Curl_copy_header_value( out as *mut libc::c_void, 350 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} - return result; + ); + return result;} } /* @@ -466,12 +465,11 @@ pub extern "C" fn Curl_copy_header_value( * Returns CURLcode. */ #[cfg(not(CURL_DISABLE_HTTP_AUTH))] - extern "C" fn http_output_bearer(mut data: *mut Curl_easy) -> CURLcode { +extern "C" fn http_output_bearer(mut data: *mut Curl_easy) -> CURLcode { let mut userp: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; let mut result: CURLcode = CURLE_OK; - - userp = unsafe{&mut (*data).state.aptr.userpwd}; - unsafe{ + unsafe { + userp = &mut (*data).state.aptr.userpwd; #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(*userp as *mut libc::c_void); #[cfg(CURLDEBUG)] @@ -482,13 +480,13 @@ pub extern "C" fn Curl_copy_header_value( ); *userp = curl_maprintf( b"Authorization: Bearer %s\r\n\0" as *const u8 as *const libc::c_char, - (*data).set.str_0[STRING_BEARER as usize], - );} + (*data).set.str_0[STRING_BEARER as i32 as usize], + ); - if unsafe{(*userp).is_null()} { + if (*userp).is_null() { result = CURLE_OUT_OF_MEMORY; } - + } return result; } @@ -497,16 +495,15 @@ pub extern "C" fn Curl_copy_header_value( * * return TRUE if one was picked */ - extern "C" fn pickoneauth(mut pick: *mut auth, mut mask: u64) -> bool { +extern "C" fn pickoneauth(mut pick: *mut auth, mut mask: u64) -> bool { let mut picked: bool = false; - /* only deal with authentication we want */ - let mut avail: u64 = unsafe{(*pick).avail & (*pick).want & mask}; + let mut avail: u64 =unsafe { (*pick).avail & (*pick).want & mask}; picked = true; /* The order of these checks is highly relevant, as this will be the order of preference in case of the existence of multiple accepted types. */ - unsafe{ + unsafe { if avail & CURLAUTH_NEGOTIATE != 0 { (*pick).picked = CURLAUTH_NEGOTIATE; } else if avail & CURLAUTH_BEARER != 0 { @@ -553,30 +550,30 @@ pub extern "C" fn Curl_copy_header_value( * } * } */ - extern "C" fn http_perhapsrewind( +extern "C" fn http_perhapsrewind( mut data: *mut Curl_easy, mut conn: *mut connectdata, ) -> CURLcode { - let mut http: *mut HTTP = unsafe{(*data).req.p.http}; + let mut http: *mut HTTP =unsafe { (*data).req.p.http}; let mut bytessent: curl_off_t = 0; let mut expectsend: curl_off_t = -1 as curl_off_t; /* default is unknown */ - + unsafe { if http.is_null() { /* If this is still NULL, we have not reach very far and we can safely skip this rewinding stuff */ return CURLE_OK; } - match unsafe{(*data).state.httpreq as u32} { + match (*data).state.httpreq as u32 { // 0 | 5 => return CURLE_OK, HTTPREQ_GET | HTTPREQ_HEAD => return CURLE_OK, _ => {} } - bytessent = unsafe{(*data).req.writebytecount}; + bytessent = (*data).req.writebytecount; // todo 解决clippy错误,代码通过测试后就可以删掉注释 - if unsafe{((*conn).bits).authneg() != 0 || ((*conn).bits).protoconnstart() == 0} { + if ((*conn).bits).authneg() != 0 || ((*conn).bits).protoconnstart() == 0 { /* This is a state where we are known to be negotiating and we don't send any data then. */ expectsend = 0 as curl_off_t; @@ -584,35 +581,35 @@ pub extern "C" fn Curl_copy_header_value( /* HTTP CONNECT in progress: there is no body */ // expectsend = 0 as curl_off_t; } else { - match unsafe{(*data).state.httpreq as u32} { + match (*data).state.httpreq as u32 { /* figure out how much data we are expected to send */ HTTPREQ_POST | HTTPREQ_PUT => { - if unsafe{(*data).state.infilesize != -1 as i64} { - expectsend = unsafe{(*data).state.infilesize}; + if (*data).state.infilesize != -1 as i64 { + expectsend = (*data).state.infilesize; } } HTTPREQ_POST_FORM | HTTPREQ_POST_MIME => { - expectsend = unsafe{(*http).postsize}; + expectsend = (*http).postsize; } _ => {} } } - unsafe{ (*conn).bits.set_rewindaftersend(0 as bit); }/* default */ + (*conn).bits.set_rewindaftersend(0 as bit); /* default */ if expectsend == -1 as i64 || expectsend > bytessent { match () { #[cfg(USE_NTLM)] /* There is still data left to send */ - _ => {unsafe{ + _ => { if (*data).state.authproxy.picked == CURLAUTH_NTLM || (*data).state.authhost.picked == CURLAUTH_NTLM || (*data).state.authproxy.picked == CURLAUTH_NTLM_WB || (*data).state.authhost.picked == CURLAUTH_NTLM_WB { if expectsend - bytessent < 2000 as i64 - || (*conn).http_ntlm_state as u32 != NTLMSTATE_NONE as u32 - || (*conn).proxy_ntlm_state as u32 != NTLMSTATE_NONE as u32 + || (*conn).http_ntlm_state as u32 != NTLMSTATE_NONE as i32 as u32 + || (*conn).proxy_ntlm_state as u32 != NTLMSTATE_NONE as i32 as u32 { /* The NTLM-negotiation has started *OR* there is just a little (<2K) data left to send, keep on sending. */ @@ -639,7 +636,7 @@ pub extern "C" fn Curl_copy_header_value( as *const libc::c_char, expectsend - bytessent, ); - }} + } } #[cfg(not(USE_NTLM))] _ => {} @@ -648,13 +645,13 @@ pub extern "C" fn Curl_copy_header_value( match () { #[cfg(USE_SPNEGO)] /* There is still data left to send */ - _ => {unsafe{ + _ => { if (*data).state.authproxy.picked == CURLAUTH_NEGOTIATE || (*data).state.authhost.picked == CURLAUTH_NEGOTIATE { if expectsend - bytessent < 2000 as i64 - || (*conn).http_negotiate_state as u32 != GSS_AUTHNONE as u32 - || (*conn).proxy_negotiate_state as u32 != GSS_AUTHNONE as u32 + || (*conn).http_negotiate_state as u32 != GSS_AUTHNONE as i32 as u32 + || (*conn).proxy_negotiate_state as u32 != GSS_AUTHNONE as i32 as u32 { /* The NEGOTIATE-negotiation has started *OR* there is just a little (<2K) data left to send, keep on sending. */ @@ -678,12 +675,12 @@ pub extern "C" fn Curl_copy_header_value( as *const libc::c_char, expectsend - bytessent, ); - }} + } } #[cfg(not(USE_SPNEGO))] _ => {} } - unsafe{ + /* This is not NEGOTIATE/NTLM or many bytes left to send: close */ #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 2); @@ -697,12 +694,11 @@ pub extern "C" fn Curl_copy_header_value( /* There still is data left to send, but this connection is marked for closure so we can safely do the rewind right now */ } - } if bytessent != 0 { /* we rewind now at once since if we already sent something */ - return unsafe{Curl_readrewind(data)}; + return Curl_readrewind(data); + } } - return CURLE_OK; } @@ -713,42 +709,42 @@ pub extern "C" fn Curl_copy_header_value( * picked. */ #[no_mangle] -pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { - let mut conn: *mut connectdata = unsafe{(*data).conn}; +pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { + let mut conn: *mut connectdata =unsafe { (*data).conn}; let mut pickhost: bool = false; let mut pickproxy: bool = false; let mut result: CURLcode = CURLE_OK; let mut authmask: u64 = !(0 as u64); - - if unsafe{((*data).set.str_0[STRING_BEARER as usize]).is_null()} { + unsafe { + if ((*data).set.str_0[STRING_BEARER as i32 as usize]).is_null() { authmask &= !CURLAUTH_BEARER; } - if unsafe{100 <= (*data).req.httpcode && 199 >= (*data).req.httpcode} { + if 100 <= (*data).req.httpcode && 199 >= (*data).req.httpcode { /* this is a transient response code, ignore */ return CURLE_OK; } - if unsafe{((*data).state).authproblem() != 0} { - return (if unsafe{((*data).set).http_fail_on_error() as i32 != 0} { + if ((*data).state).authproblem() != 0 { + return (if ((*data).set).http_fail_on_error() as i32 != 0 { CURLE_HTTP_RETURNED_ERROR as i32 } else { CURLE_OK as i32 }) as CURLcode; } - if unsafe{(((*conn).bits).user_passwd() as i32 != 0 - || !((*data).set.str_0[STRING_BEARER as usize]).is_null()) + if (((*conn).bits).user_passwd() as i32 != 0 + || !((*data).set.str_0[STRING_BEARER as i32 as usize]).is_null()) && ((*data).req.httpcode == 401 - || ((*conn).bits).authneg() as i32 != 0 && (*data).req.httpcode < 300)} + || ((*conn).bits).authneg() as i32 != 0 && (*data).req.httpcode < 300) { - pickhost = unsafe{pickoneauth(&mut (*data).state.authhost, authmask)}; + pickhost = pickoneauth(&mut (*data).state.authhost, authmask); if !pickhost { - unsafe{ (*data).state.set_authproblem(1 as bit);} + (*data).state.set_authproblem(1 as bit); } - if unsafe{(*data).state.authhost.picked == CURLAUTH_NTLM && (*conn).httpversion as i32 > 11 }{ - unsafe{Curl_infof( + if (*data).state.authhost.picked == CURLAUTH_NTLM && (*conn).httpversion as i32 > 11 { + Curl_infof( data, b"Forcing HTTP/1.1 for NTLM\0" as *const u8 as *const libc::c_char, ); @@ -761,10 +757,10 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { 1, b"Force HTTP/1.1 connection\0" as *const u8 as *const libc::c_char, ); - (*data).state.httpwant = CURL_HTTP_VERSION_1_1 as u8;} + (*data).state.httpwant = CURL_HTTP_VERSION_1_1 as i32 as u8; } } - unsafe{ + #[cfg(not(CURL_DISABLE_PROXY))] if ((*conn).bits).proxy_user_passwd() as i32 != 0 && ((*data).req.httpcode == 407 @@ -774,11 +770,11 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { if !pickproxy { (*data).state.set_authproblem(1 as bit); } - }} + } if pickhost as i32 != 0 || pickproxy as i32 != 0 { - if unsafe{(*data).state.httpreq as u32 != HTTPREQ_GET as u32 + if (*data).state.httpreq as u32 != HTTPREQ_GET as u32 && (*data).state.httpreq as u32 != HTTPREQ_HEAD as u32 - && ((*conn).bits).rewindaftersend() == 0} + && ((*conn).bits).rewindaftersend() == 0 { result = http_perhapsrewind(data, conn); if result as u64 != 0 { @@ -791,17 +787,16 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { /* In case this is GSS auth, the newurl field is already allocated so we must make sure to free it before allocating a new one. As figured out in bug #2284386 */ - unsafe{ Curl_cfree.expect("non-null function pointer")( (*data).req.newurl as *mut libc::c_void, ); (*data).req.newurl = 0 as *mut libc::c_char; /* clone URL */ (*data).req.newurl = - Curl_cstrdup.expect("non-null function pointer")((*data).state.url);} + Curl_cstrdup.expect("non-null function pointer")((*data).state.url); } #[cfg(CURLDEBUG)] - _ => {unsafe{ + _ => { /* In case this is GSS auth, the newurl field is already allocated so we must make sure to free it before allocating a new one. As figured out in bug #2284386 */ @@ -816,47 +811,48 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { (*data).state.url, 627, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); } } - if unsafe{((*data).req.newurl).is_null()} { + if ((*data).req.newurl).is_null() { return CURLE_OUT_OF_MEMORY; } - } else if unsafe{(*data).req.httpcode < 300 + } else if (*data).req.httpcode < 300 && ((*data).state.authhost).done() == 0 - && ((*conn).bits).authneg() as i32 != 0} + && ((*conn).bits).authneg() as i32 != 0 { /* no (known) authentication available, authentication is not "done" yet and no authentication seems to be required and we didn't try HEAD or GET */ - if unsafe{(*data).state.httpreq as u32 != HTTPREQ_GET as u32 - && (*data).state.httpreq as u32 != HTTPREQ_HEAD as u32} + if (*data).state.httpreq as u32 != HTTPREQ_GET as u32 + && (*data).state.httpreq as u32 != HTTPREQ_HEAD as u32 { #[cfg(not(CURLDEBUG))] let new_url: *mut libc::c_char = - unsafe{ Curl_cstrdup.expect("non-null function pointer")((*data).state.url)}; + Curl_cstrdup.expect("non-null function pointer")((*data).state.url); #[cfg(CURLDEBUG)] - let new_url: *mut libc::c_char = unsafe{curl_dbg_strdup( + let new_url: *mut libc::c_char = curl_dbg_strdup( (*data).state.url, 640, b"http.c\0" as *const u8 as *const libc::c_char, - )}; - unsafe{(*data).req.newurl = new_url;} /* clone URL */ - if unsafe{((*data).req.newurl).is_null()} { + ); + (*data).req.newurl = new_url; /* clone URL */ + if ((*data).req.newurl).is_null() { return CURLE_OUT_OF_MEMORY; } - unsafe{ (*data).state.authhost.set_done(1 as bit)}; + (*data).state.authhost.set_done(1 as bit); } } - if unsafe{http_should_fail(data)} { - unsafe{Curl_failf( + if http_should_fail(data) { + Curl_failf( data, b"The requested URL returned error: %d\0" as *const u8 as *const libc::c_char, (*data).req.httpcode, - );} + ); result = CURLE_HTTP_RETURNED_ERROR; } +} return result; } @@ -865,7 +861,7 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { * Output the correct authentication header depending on the auth type * and whether or not it is to a proxy. */ - extern "C" fn output_auth_headers( +extern "C" fn output_auth_headers( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut authstatus: *mut auth, @@ -877,63 +873,64 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { let mut result: CURLcode = CURLE_OK; let flag1: bool = if cfg!(not(CURL_DISABLE_CRYPTO_AUTH)) { - unsafe{(*authstatus).picked == CURLAUTH_AWS_SIGV4} + unsafe { (*authstatus).picked == CURLAUTH_AWS_SIGV4} } else { false }; let flag2: bool = if cfg!(USE_SPNEGO) { - unsafe{ (*authstatus).picked == CURLAUTH_NEGOTIATE} + unsafe { (*authstatus).picked == CURLAUTH_NEGOTIATE} } else { false }; let flag3: bool = if cfg!(USE_NTLM) { - unsafe{(*authstatus).picked == CURLAUTH_NTLM} + unsafe {(*authstatus).picked == CURLAUTH_NTLM} } else { false }; let flag4: bool = if cfg!(all(USE_NTLM, NTLM_WB_ENABLED)) { - unsafe{(*authstatus).picked == CURLAUTH_NTLM_WB} + unsafe { (*authstatus).picked == CURLAUTH_NTLM_WB} } else { false }; let flag5: bool = if cfg!(not(CURL_DISABLE_CRYPTO_AUTH)) { - unsafe{(*authstatus).picked == CURLAUTH_DIGEST} + unsafe { (*authstatus).picked == CURLAUTH_DIGEST} } else { false }; if flag1 { auth = b"AWS_SIGV4\0" as *const u8 as *const libc::c_char; - result = unsafe{Curl_output_aws_sigv4(data, proxy)}; + result =unsafe { Curl_output_aws_sigv4(data, proxy)}; if result as u64 != 0 { return result; } } else if flag2 { auth = b"Negotiate\0" as *const u8 as *const libc::c_char; - result = unsafe{Curl_output_negotiate(data, conn, proxy)}; + result =unsafe { Curl_output_negotiate(data, conn, proxy)}; if result as u64 != 0 { return result; } } else if flag3 { auth = b"NTLM\0" as *const u8 as *const libc::c_char; - result = unsafe{Curl_output_ntlm(data, proxy)}; + result = unsafe {Curl_output_ntlm(data, proxy)}; if result as u64 != 0 { return result; } } else if flag4 { auth = b"NTLM_WB\0" as *const u8 as *const libc::c_char; - result = unsafe{Curl_output_ntlm_wb(data, conn, proxy)}; + result =unsafe { Curl_output_ntlm_wb(data, conn, proxy)}; if result as u64 != 0 { return result; } } else if flag5 { auth = b"Digest\0" as *const u8 as *const libc::c_char; - result = unsafe{Curl_output_digest(data, proxy, request as *const u8, path as *const u8)}; + result = unsafe {Curl_output_digest(data, proxy, request as *const u8, path as *const u8)}; if result as u64 != 0 { return result; } - } else if unsafe{(*authstatus).picked == CURLAUTH_BASIC} { + } else if unsafe {(*authstatus).picked == CURLAUTH_BASIC} { + unsafe { #[cfg(not(CURL_DISABLE_PROXY))] - let flag6: bool = unsafe{proxy as i32 != 0 + let flag6: bool = proxy as i32 != 0 && ((*conn).bits).proxy_user_passwd() as i32 != 0 && (Curl_checkProxyheaders( data, @@ -947,12 +944,12 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { data, b"Authorization\0" as *const u8 as *const libc::c_char, )) - .is_null()}; + .is_null(); #[cfg(CURL_DISABLE_PROXY)] - let flag6: bool = unsafe{!proxy + let flag6: bool = !proxy && ((*conn).bits).user_passwd() as i32 != 0 && (Curl_checkheaders(data, b"Authorization\0" as *const u8 as *const libc::c_char)) - .is_null()}; + .is_null(); if flag6 { auth = b"Basic\0" as *const u8 as *const libc::c_char; result = http_output_basic(data, proxy); @@ -963,15 +960,17 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { /* NOTE: this function should set 'done' TRUE, as the other auth functions work that way */ - unsafe{ (*authstatus).set_done(1 as bit);} + (*authstatus).set_done(1 as bit); + } } - if unsafe{(*authstatus).picked == CURLAUTH_BEARER} { + if unsafe {(*authstatus).picked == CURLAUTH_BEARER} { + unsafe { /* Bearer */ - if unsafe{!proxy - && !((*data).set.str_0[STRING_BEARER as usize]).is_null() + if !proxy + && !((*data).set.str_0[STRING_BEARER as i32 as usize]).is_null() && (Curl_checkheaders(data, b"Authorization\0" as *const u8 as *const libc::c_char)) - .is_null()} + .is_null() { auth = b"Bearer\0" as *const u8 as *const libc::c_char; result = http_output_bearer(data); @@ -982,9 +981,10 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { /* NOTE: this function should set 'done' TRUE, as the other auth functions work that way */ - unsafe{(*authstatus).set_done(1 as bit);} + (*authstatus).set_done(1 as bit);} } - if !auth.is_null() {unsafe{ + if !auth.is_null() { + unsafe { #[cfg(not(CURL_DISABLE_PROXY))] Curl_infof( data, @@ -1008,7 +1008,7 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { }, ); #[cfg(CURL_DISABLE_PROXY)] - Curl_infof( + Curl_infof( data, b"Server auth using %s with user '%s'\0" as *const u8 as *const libc::c_char, auth, @@ -1018,9 +1018,11 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { b"\0" as *const u8 as *const libc::c_char }, ); - (*authstatus).set_multipass((if (*authstatus).done() == 0 { 1 } else { 0 }) as bit)}; + (*authstatus).set_multipass((if (*authstatus).done() == 0 { 1 } else { 0 }) as bit); + } } else { - unsafe{ (*authstatus).set_multipass(0 as bit)}; + unsafe { + (*authstatus).set_multipass(0 as bit);} } return CURLE_OK; } @@ -1041,7 +1043,7 @@ pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { */ #[cfg(not(CURL_DISABLE_HTTP_AUTH))] #[no_mangle] -pub extern "C" fn Curl_http_output_auth( +pub extern "C" fn Curl_http_output_auth( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut request: *const libc::c_char, @@ -1052,109 +1054,123 @@ pub extern "C" fn Curl_http_output_auth( let mut result: CURLcode = CURLE_OK; let mut authhost: *mut auth = 0 as *mut auth; let mut authproxy: *mut auth = 0 as *mut auth; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !data.is_null() {} else { - unsafe{__assert_fail( - b"data\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 805 as u32, - (*::std::mem::transmute::< - &[u8; 122], - &[libc::c_char; 122], - >( - b"CURLcode Curl_http_output_auth(struct Curl_easy *, struct connectdata *, const char *, Curl_HttpReq, const char *, _Bool)\0", - )) - .as_ptr(), - );} - } + unsafe{ + if !data.is_null() { + } else { + __assert_fail( + b"data\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 805 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::< + &[u8; 122], + &[libc::c_char; 122], + >( + b"CURLcode Curl_http_output_auth(struct Curl_easy *, struct connectdata *, const char *, Curl_HttpReq, const char *, _Bool)\0", + )) + .as_ptr(), + ); + }} authhost = unsafe{&mut (*data).state.authhost}; - authproxy = unsafe{&mut (*data).state.authproxy}; + authproxy =unsafe{ &mut (*data).state.authproxy}; #[cfg(not(CURL_DISABLE_PROXY))] - let flag1: bool =unsafe{ ((*conn).bits).httpproxy() as i32 != 0 - && ((*conn).bits).proxy_user_passwd() as i32 != 0 - || ((*conn).bits).user_passwd() as i32 != 0 - || !((*data).set.str_0[STRING_BEARER as usize]).is_null()}; + let flag1: bool = unsafe{((*conn).bits).httpproxy() as libc::c_int != 0 + && ((*conn).bits).proxy_user_passwd() as libc::c_int != 0 + || ((*conn).bits).user_passwd() as libc::c_int != 0 + || !((*data).set.str_0[STRING_BEARER as libc::c_int as usize]).is_null()}; #[cfg(CURL_DISABLE_PROXY)] - let flag1: bool = unsafe{((*conn).bits).user_passwd() as i32 != 0 - || !((*data).set.str_0[STRING_BEARER as usize]).is_null()}; + let flag1: bool =unsafe{ ((*conn).bits).user_passwd() as libc::c_int != 0 + || !((*data).set.str_0[STRING_BEARER as libc::c_int as usize]).is_null()}; if flag1 { } else { - unsafe{ (*authhost).set_done(1 as bit); - (*authproxy).set_done(1 as bit);} + unsafe{ + (*authhost).set_done(1 as libc::c_int as bit); + (*authproxy).set_done(1 as libc::c_int as bit);} return CURLE_OK; } if unsafe{(*authhost).want != 0 && (*authhost).picked == 0} { /* The app has selected one or more methods, but none has been picked so far by a server round-trip. Then we set the picked one to the want one, and if this is one single bit it'll be used instantly. */ - unsafe{ (*authhost).picked = (*authhost).want;} + unsafe{(*authhost).picked = (*authhost).want;} } if unsafe{(*authproxy).want != 0 && (*authproxy).picked == 0} { /* The app has selected one or more methods, but none has been picked so far by a proxy round-trip. Then we set the picked one to the want one, and if this is one single bit it'll be used instantly. */ - unsafe{ (*authproxy).picked = (*authproxy).want;} + unsafe{(*authproxy).picked = (*authproxy).want;} } + unsafe{ match () { #[cfg(not(CURL_DISABLE_PROXY))] /* Send proxy authentication header if needed */ _ => { - if unsafe{((*conn).bits).httpproxy() as i32 != 0 - && ((*conn).bits).tunnel_proxy() == proxytunnel as bit} - { - result = output_auth_headers(data, conn, authproxy, request, path, 1 as i32 != 0); - if result as u64 != 0 { - return result; - } - } else { - unsafe{(*authproxy).set_done(1 as bit);} - } + if ((*conn).bits).httpproxy() as libc::c_int != 0 + && ((*conn).bits).tunnel_proxy() == proxytunnel as bit + { + result = output_auth_headers( + data, + conn, + authproxy, + request, + path, + 1 as libc::c_int != 0, + ); + if result as u64 != 0 { + return result; + } + } else { + (*authproxy).set_done(1 as libc::c_int as bit); + } } /* CURL_DISABLE_PROXY */ #[cfg(CURL_DISABLE_PROXY)] /* we have no proxy so let's pretend we're done authenticating with it */ _ => { - unsafe{ (*authproxy).set_done(1 as i32 as bit);} + (*authproxy).set_done(1 as libc::c_int as bit); } } +} #[cfg(not(CURL_DISABLE_NETRC))] - let flag2: bool = unsafe{((*data).state).this_is_a_follow() == 0 - || ((*conn).bits).netrc() as i32 != 0 + let flag2: bool =unsafe{ ((*data).state).this_is_a_follow() == 0 + || ((*conn).bits).netrc() as libc::c_int != 0 || ((*data).state.first_host).is_null() - || ((*data).set).allow_auth_to_other_hosts() as i32 != 0 + || ((*data).set).allow_auth_to_other_hosts() as libc::c_int != 0 || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0}; /* To prevent the user+password to get sent to other than the original host due to a location-follow, we do some weirdo checks here */ #[cfg(CURL_DISABLE_NETRC)] - let flag2: bool = unsafe{((*data).state).this_is_a_follow() == 0 + let flag2: bool =unsafe{ ((*data).state).this_is_a_follow() == 0 || ((*data).state.first_host).is_null() - || ((*data).set).allow_auth_to_other_hosts() as i32 != 0 + || ((*data).set).allow_auth_to_other_hosts() as libc::c_int != 0 || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0}; + unsafe{ if flag2 { - result = output_auth_headers(data, conn, authhost, request, path, 0 as i32 != 0); + result = output_auth_headers(data, conn, authhost, request, path, 0 as libc::c_int != 0); } else { - unsafe{(*authhost).set_done(1 as bit);} + (*authhost).set_done(1 as libc::c_int as bit); } - if unsafe{ ((*authhost).multipass() as i32 != 0 && (*authhost).done() == 0 - || (*authproxy).multipass() as i32 != 0 && (*authproxy).done() == 0) - && httpreq as u32 != HTTPREQ_GET as u32 - && httpreq as u32 != HTTPREQ_HEAD as u32} + if ((*authhost).multipass() as libc::c_int != 0 && (*authhost).done() == 0 + || (*authproxy).multipass() as libc::c_int != 0 && (*authproxy).done() == 0) + && httpreq as libc::c_uint != HTTPREQ_GET as libc::c_int as libc::c_uint + && httpreq as libc::c_uint != HTTPREQ_HEAD as libc::c_int as libc::c_uint { - let ref mut fresh8 = unsafe{(*conn).bits}; - (*fresh8).set_authneg(1 as bit); + let ref mut fresh8 = (*conn).bits; + (*fresh8).set_authneg(1 as libc::c_int as bit); } else { - let ref mut fresh9 = unsafe{(*conn).bits}; - (*fresh9).set_authneg(0 as bit); - } + let ref mut fresh9 = (*conn).bits; + (*fresh9).set_authneg(0 as libc::c_int as bit); + }} return result; } /* when disabled */ #[cfg(CURL_DISABLE_HTTP_AUTH)] #[no_mangle] -pub extern "C" fn Curl_http_output_auth( +pub extern "C" fn Curl_http_output_auth( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut request: *const libc::c_char, @@ -1162,7 +1178,8 @@ pub extern "C" fn Curl_http_output_auth( mut path: *const libc::c_char, mut proxytunnel: bool, ) -> CURLcode { - return CURLE_OK; + unsafe{ + return CURLE_OK;} } /* @@ -1170,14 +1187,15 @@ pub extern "C" fn Curl_http_output_auth( * headers. They are dealt with both in the transfer.c main loop and in the * proxy CONNECT loop. */ - extern "C" fn is_valid_auth_separator(mut ch: libc::c_char) -> i32 { - return (ch as i32 == '\0' as i32 - || ch as i32 == ',' as i32 - || unsafe{Curl_isspace(ch as i32) != 0}) as i32; +extern "C" fn is_valid_auth_separator(mut ch: libc::c_char) -> libc::c_int { + unsafe{ + return (ch as libc::c_int == '\0' as i32 + || ch as libc::c_int == ',' as i32 + || Curl_isspace(ch as libc::c_uchar as libc::c_int) != 0) as libc::c_int;} } #[no_mangle] -pub extern "C" fn Curl_http_input_auth( +pub extern "C" fn Curl_http_input_auth( mut data: *mut Curl_easy, mut proxy: bool, mut auth: *const libc::c_char, @@ -1185,23 +1203,25 @@ pub extern "C" fn Curl_http_input_auth( /* * This resource requires authentication */ - let mut conn: *mut connectdata = unsafe{(*data).conn}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; #[cfg(USE_SPNEGO)] - let mut negstate: *mut curlnegotiate = if proxy as i32 != 0 { - unsafe{ &mut (*conn).proxy_negotiate_state} + let mut negstate: *mut curlnegotiate =unsafe{ if proxy as i32 != 0 { + &mut (*conn).proxy_negotiate_state } else { - unsafe{ &mut (*conn).http_negotiate_state} - }; + &mut (*conn).http_negotiate_state + }}; let mut availp: *mut u64 = 0 as *mut u64; let mut authp: *mut auth = 0 as *mut auth; if proxy { - availp = unsafe{&mut (*data).info.proxyauthavail}; - authp = unsafe{&mut (*data).state.authproxy}; + unsafe{ + availp = &mut (*data).info.proxyauthavail; + authp = &mut (*data).state.authproxy;} } else { - availp =unsafe{ &mut (*data).info.httpauthavail}; - authp = unsafe{&mut (*data).state.authhost}; + unsafe{ + availp = &mut (*data).info.httpauthavail; + authp = &mut (*data).state.authhost;} } /* @@ -1219,38 +1239,39 @@ pub extern "C" fn Curl_http_input_auth( * headers have been received but then only to a single preferred method * (bit). */ - while unsafe{*auth != 0 }{ + unsafe{ + while *auth != 0 { #[cfg(USE_SPNEGO)] - let flag1: bool = unsafe{curl_strnequal( + let flag1: bool = curl_strnequal( b"Negotiate\0" as *const u8 as *const libc::c_char, auth, strlen(b"Negotiate\0" as *const u8 as *const libc::c_char), ) != 0 - && is_valid_auth_separator(*auth.offset(9 as i32 as isize)) != 0}; + && is_valid_auth_separator(*auth.offset(9 as i32 as isize)) != 0; #[cfg(not(USE_SPNEGO))] let flag1: bool = false; #[cfg(USE_NTLM)] - let flag2: bool = unsafe{curl_strnequal( + let flag2: bool = curl_strnequal( b"NTLM\0" as *const u8 as *const libc::c_char, auth, strlen(b"NTLM\0" as *const u8 as *const libc::c_char), ) != 0 - && is_valid_auth_separator(*auth.offset(4 as isize)) != 0}; + && is_valid_auth_separator(*auth.offset(4 as isize)) != 0; #[cfg(not(USE_NTLM))] let flag2: bool = false; #[cfg(not(CURL_DISABLE_CRYPTO_AUTH))] - let flag3: bool = unsafe{curl_strnequal( + let flag3: bool = curl_strnequal( b"Digest\0" as *const u8 as *const libc::c_char, auth, strlen(b"Digest\0" as *const u8 as *const libc::c_char), ) != 0 - && is_valid_auth_separator(*auth.offset(6 as isize)) != 0}; + && is_valid_auth_separator(*auth.offset(6 as isize)) != 0; #[cfg(CURL_DISABLE_CRYPTO_AUTH)] let flag3: bool = false; if flag1 { match () { #[cfg(USE_SPNEGO)] - _ => {unsafe{ + _ => { if (*authp).avail & (1 as u64) << 2 != 0 || Curl_auth_is_spnego_supported() as i32 != 0 { @@ -1273,7 +1294,7 @@ pub extern "C" fn Curl_http_input_auth( (*data).state.set_authproblem(1 as bit); } } - }} + } } #[cfg(not(USE_SPNEGO))] _ => {} @@ -1307,38 +1328,38 @@ pub extern "C" fn Curl_http_input_auth( // } // } } else if flag2 { - if unsafe{(*authp).avail & CURLAUTH_NTLM != 0 + if (*authp).avail & CURLAUTH_NTLM != 0 || (*authp).avail & CURLAUTH_NTLM_WB != 0 - || Curl_auth_is_ntlm_supported() as i32 != 0} + || Curl_auth_is_ntlm_supported() as i32 != 0 { - unsafe{*availp |= CURLAUTH_NTLM; - (*authp).avail |= CURLAUTH_NTLM;} - if unsafe{(*authp).picked == CURLAUTH_NTLM || (*authp).picked == CURLAUTH_NTLM_WB} { - let mut result_0: CURLcode = unsafe{Curl_input_ntlm(data, proxy, auth)}; + *availp |= CURLAUTH_NTLM; + (*authp).avail |= CURLAUTH_NTLM; + if (*authp).picked == CURLAUTH_NTLM || (*authp).picked == CURLAUTH_NTLM_WB { + let mut result_0: CURLcode = Curl_input_ntlm(data, proxy, auth); if result_0 as u64 == 0 { - unsafe{(*data).state.set_authproblem(0 as bit)}; - if unsafe{ (*authp).picked == CURLAUTH_NTLM_WB} { - unsafe{ *availp &= !CURLAUTH_NTLM; + (*data).state.set_authproblem(0 as bit); + if (*authp).picked == CURLAUTH_NTLM_WB { + *availp &= !CURLAUTH_NTLM; (*authp).avail &= !CURLAUTH_NTLM; *availp |= CURLAUTH_NTLM_WB; - (*authp).avail |= CURLAUTH_NTLM_WB;} - result_0 = unsafe{Curl_input_ntlm_wb(data, conn, proxy, auth)}; + (*authp).avail |= CURLAUTH_NTLM_WB; + result_0 = Curl_input_ntlm_wb(data, conn, proxy, auth); if result_0 as u64 != 0 { - unsafe{Curl_infof( + Curl_infof( data, b"Authentication problem. Ignoring this.\0" as *const u8 as *const libc::c_char, ); - (*data).state.set_authproblem(1 as bit);} + (*data).state.set_authproblem(1 as bit); } } } else { - unsafe{Curl_infof( + Curl_infof( data, b"Authentication problem. Ignoring this.\0" as *const u8 as *const libc::c_char, ); - (*data).state.set_authproblem(1 as bit);} + (*data).state.set_authproblem(1 as bit); } } } @@ -1346,91 +1367,91 @@ pub extern "C" fn Curl_http_input_auth( match () { #[cfg(not(CURL_DISABLE_CRYPTO_AUTH))] _ => { - if unsafe{(*authp).avail & CURLAUTH_DIGEST != 0 as u64} { - unsafe{Curl_infof( + if (*authp).avail & CURLAUTH_DIGEST != 0 as u64 { + Curl_infof( data, b"Ignoring duplicate digest auth header.\0" as *const u8 as *const libc::c_char, - );} - } else if unsafe{Curl_auth_is_digest_supported()} { + ); + } else if Curl_auth_is_digest_supported() { let mut result: CURLcode = CURLE_OK; - unsafe{*availp |= CURLAUTH_DIGEST; - (*authp).avail |= CURLAUTH_DIGEST;} + *availp |= CURLAUTH_DIGEST; + (*authp).avail |= CURLAUTH_DIGEST; /* We call this function on input Digest headers even if Digest * authentication isn't activated yet, as we need to store the * incoming data from this header in case we are going to use * Digest */ - result = unsafe{Curl_input_digest(data, proxy, auth)}; + result = Curl_input_digest(data, proxy, auth); if result as u64 != 0 { - unsafe{ Curl_infof( + Curl_infof( data, b"Authentication problem. Ignoring this.\0" as *const u8 as *const libc::c_char, ); - (*data).state.set_authproblem(1 as bit);} + (*data).state.set_authproblem(1 as bit); } } } #[cfg(CURL_DISABLE_CRYPTO_AUTH)] _ => {} } - } else if unsafe{curl_strnequal( + } else if curl_strnequal( b"Basic\0" as *const u8 as *const libc::c_char, auth, strlen(b"Basic\0" as *const u8 as *const libc::c_char), ) != 0 - && is_valid_auth_separator(*auth.offset(5 as isize)) != 0} + && is_valid_auth_separator(*auth.offset(5 as isize)) != 0 { - unsafe{ *availp |= CURLAUTH_BASIC; - (*authp).avail |= CURLAUTH_BASIC;} - if unsafe{(*authp).picked == CURLAUTH_BASIC }{ + *availp |= CURLAUTH_BASIC; + (*authp).avail |= CURLAUTH_BASIC; + if (*authp).picked == CURLAUTH_BASIC { /* We asked for Basic authentication but got a 40X back anyway, which basically means our name+password isn't valid. */ - unsafe{ (*authp).avail = CURLAUTH_NONE; + (*authp).avail = CURLAUTH_NONE; Curl_infof( data, b"Authentication problem. Ignoring this.\0" as *const u8 as *const libc::c_char, ); - (*data).state.set_authproblem(1 as bit);} + (*data).state.set_authproblem(1 as bit); } - } else if unsafe{curl_strnequal( + } else if curl_strnequal( b"Bearer\0" as *const u8 as *const libc::c_char, auth, strlen(b"Bearer\0" as *const u8 as *const libc::c_char), ) != 0 - && is_valid_auth_separator(*auth.offset(6 as isize)) != 0} + && is_valid_auth_separator(*auth.offset(6 as isize)) != 0 { - unsafe{*availp |= CURLAUTH_BEARER; - (*authp).avail |= CURLAUTH_BEARER;} - if unsafe{ (*authp).picked == CURLAUTH_BEARER} { + *availp |= CURLAUTH_BEARER; + (*authp).avail |= CURLAUTH_BEARER; + if (*authp).picked == CURLAUTH_BEARER { /* We asked for Bearer authentication but got a 40X back anyway, which basically means our token isn't valid. */ - unsafe{(*authp).avail = CURLAUTH_NONE; + (*authp).avail = CURLAUTH_NONE; Curl_infof( data, b"Authentication problem. Ignoring this.\0" as *const u8 as *const libc::c_char, ); - (*data).state.set_authproblem(1 as bit);} + (*data).state.set_authproblem(1 as bit); } } /* there may be multiple methods on one line, so keep reading */ - while unsafe{ *auth as i32 != 0 && *auth as i32 != ',' as i32} { + while *auth as i32 != 0 && *auth as i32 != ',' as i32 { /* read up to the next comma */ - auth = unsafe{auth.offset(1)}; + auth = auth.offset(1); } - if unsafe{*auth as i32 == ',' as i32} { + if *auth as i32 == ',' as i32 { /* if we're on a comma, skip it */ - auth = unsafe{auth.offset(1)}; + auth = auth.offset(1); } - while unsafe{*auth as i32 != 0 && Curl_isspace(*auth as u8 as i32) != 0} { - auth = unsafe{auth.offset(1)}; + while *auth as i32 != 0 && Curl_isspace(*auth as u8 as i32) != 0 { + auth = auth.offset(1); } } - + } return CURLE_OK; } @@ -1444,13 +1465,13 @@ pub extern "C" fn Curl_http_input_auth( * * @retval TRUE communications should not continue */ - extern "C" fn http_should_fail(mut data: *mut Curl_easy) -> bool { +extern "C" fn http_should_fail(mut data: *mut Curl_easy) -> bool { let mut httpcode: i32 = 0; - + unsafe{ #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] if !data.is_null() { } else { - unsafe{ __assert_fail( + __assert_fail( b"data\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 1090 as u32, @@ -1458,13 +1479,13 @@ pub extern "C" fn Curl_http_input_auth( b"_Bool http_should_fail(struct Curl_easy *)\0", )) .as_ptr(), - );} + ); } - + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{!((*data).conn).is_null() }{ + if !((*data).conn).is_null() { } else { - unsafe{ __assert_fail( + __assert_fail( b"data->conn\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 1091 as u32, @@ -1472,16 +1493,16 @@ pub extern "C" fn Curl_http_input_auth( b"_Bool http_should_fail(struct Curl_easy *)\0", )) .as_ptr(), - );} + ); } - - httpcode = unsafe{(*data).req.httpcode}; + } + httpcode =unsafe{ (*data).req.httpcode}; /* ** If we haven't been asked to fail on error, ** don't fail. */ - if unsafe{((*data).set).http_fail_on_error() == 0} { + if unsafe{((*data).set).http_fail_on_error() == 0 }{ return false; } @@ -1515,9 +1536,10 @@ pub extern "C" fn Curl_http_input_auth( ** All we have left to deal with is 401 and 407 */ #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + unsafe{ if httpcode == 401 || httpcode == 407 { } else { - unsafe{ __assert_fail( + __assert_fail( b"(httpcode == 401) || (httpcode == 407)\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 1126 as u32, @@ -1525,9 +1547,9 @@ pub extern "C" fn Curl_http_input_auth( b"_Bool http_should_fail(struct Curl_easy *)\0", )) .as_ptr(), - );} + ); + } } - /* ** Examine the current authentication state to see if this ** is an error. The idea is for this function to get @@ -1546,14 +1568,15 @@ pub extern "C" fn Curl_http_input_auth( ** Either we're not authenticating, or we're supposed to ** be authenticating something else. This is an error. */ - if httpcode == 401 && unsafe{((*(*data).conn).bits).user_passwd() == 0} { + unsafe{ + if httpcode == 401 && ((*(*data).conn).bits).user_passwd() == 0 { return true; } #[cfg(not(CURL_DISABLE_PROXY))] - if httpcode == 407 && unsafe{((*(*data).conn).bits).proxy_user_passwd() == 0 }{ + if httpcode == 407 && ((*(*data).conn).bits).proxy_user_passwd() == 0 { return true; } - return unsafe{((*data).state).authproblem() != 0}; + return ((*data).state).authproblem() != 0;} } /* @@ -1565,7 +1588,7 @@ pub extern "C" fn Curl_http_input_auth( * Returns the amount of bytes it filled the buffer with. */ #[cfg(not(USE_HYPER))] - extern "C" fn readmoredata( +extern "C" fn readmoredata( mut buffer: *mut libc::c_char, mut size: size_t, mut nitems: size_t, @@ -1574,61 +1597,61 @@ pub extern "C" fn Curl_http_input_auth( let mut data: *mut Curl_easy = userp as *mut Curl_easy; let mut http: *mut HTTP = unsafe{(*data).req.p.http}; let mut fullsize: size_t = size.wrapping_mul(nitems); - - if unsafe{(*http).postsize == 0 }{ + unsafe{ + if (*http).postsize == 0 { /* nothing to return */ return 0 as size_t; } /* make sure that a HTTP request is never sent away chunked! */ - unsafe{ (*data).req.set_forbidchunk( + (*data).req.set_forbidchunk( (if (*http).sending as u32 == HTTPSEND_REQUEST { 1 } else { 0 }) as bit, - );} + ); /* speed limit */ - if unsafe{(*data).set.max_send_speed != 0 + if (*data).set.max_send_speed != 0 && (*data).set.max_send_speed < fullsize as curl_off_t - && (*data).set.max_send_speed < (*http).postsize} + && (*data).set.max_send_speed < (*http).postsize { - fullsize =unsafe{ (*data).set.max_send_speed as size_t}; - } else if unsafe{(*http).postsize <= fullsize as curl_off_t }{ - unsafe{memcpy( + fullsize = (*data).set.max_send_speed as size_t; + } else if (*http).postsize <= fullsize as curl_off_t { + memcpy( buffer as *mut libc::c_void, (*http).postdata as *const libc::c_void, (*http).postsize as size_t, - );} - fullsize = unsafe{(*http).postsize as size_t}; + ); + fullsize = (*http).postsize as size_t; - if unsafe{(*http).backup.postsize != 0} { + if (*http).backup.postsize != 0 { /* move backup data into focus and continue on that */ - unsafe{(*http).postdata = (*http).backup.postdata; + (*http).postdata = (*http).backup.postdata; (*http).postsize = (*http).backup.postsize; (*data).state.fread_func = (*http).backup.fread_func; (*data).state.in_0 = (*http).backup.fread_in; (*http).sending += 1; /* move one step up */ - (*http).backup.postsize = 0 as curl_off_t;} + (*http).backup.postsize = 0 as curl_off_t; } else { - unsafe{ (*http).postsize = 0 as curl_off_t;} + (*http).postsize = 0 as curl_off_t; } return fullsize; } - unsafe{memcpy( + memcpy( buffer as *mut libc::c_void, (*http).postdata as *const libc::c_void, fullsize, ); (*http).postdata = (*http).postdata.offset(fullsize as isize); - (*http).postsize = ((*http).postsize as u64).wrapping_sub(fullsize) as curl_off_t;} - + (*http).postsize = ((*http).postsize as u64).wrapping_sub(fullsize) as curl_off_t as curl_off_t; + } return fullsize; } @@ -1640,7 +1663,7 @@ pub extern "C" fn Curl_http_input_auth( */ #[cfg(not(USE_HYPER))] #[no_mangle] -pub extern "C" fn Curl_buffer_send( +pub extern "C" fn Curl_buffer_send( mut in_0: *mut dynbuf, mut data: *mut Curl_easy, /* add the number of sent bytes to this @@ -1654,56 +1677,56 @@ pub extern "C" fn Curl_buffer_send( let mut result: CURLcode = CURLE_OK; let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; let mut size: size_t = 0; - let mut conn: *mut connectdata = unsafe{(*data).conn}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; let mut http: *mut HTTP =unsafe{ (*data).req.p.http}; let mut sendsize: size_t = 0; let mut sockfd: curl_socket_t = 0; let mut headersize: size_t = 0; - + unsafe{ #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] if socketindex <= 1 { } else { - unsafe{ __assert_fail( - b"socketindex <= 1\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 1240 as u32, - (*::std::mem::transmute::< - &[u8; 94], - &[libc::c_char; 94], - >( - b"CURLcode Curl_buffer_send(struct dynbuf *, struct Curl_easy *, curl_off_t *, curl_off_t, int)\0", - )) - .as_ptr(), - );} - } + __assert_fail( + b"socketindex <= 1\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 1240 as u32, + (*::std::mem::transmute::< + &[u8; 94], + &[libc::c_char; 94], + >( + b"CURLcode Curl_buffer_send(struct dynbuf *, struct Curl_easy *, curl_off_t *, curl_off_t, int)\0", + )) + .as_ptr(), + ); + }} - sockfd = unsafe{(*conn).sock[socketindex as usize]}; + sockfd =unsafe{ (*conn).sock[socketindex as usize]}; /* The looping below is required since we use non-blocking sockets, but due to the circumstances we will just loop and try again and again etc */ - ptr = unsafe{Curl_dyn_ptr(in_0)}; - size = unsafe{Curl_dyn_len(in_0)}; + ptr =unsafe{ Curl_dyn_ptr(in_0)}; + size =unsafe{ Curl_dyn_len(in_0)}; headersize = size.wrapping_sub(included_body_bytes as size_t); /* the initial part that isn't body is header */ - + unsafe{ #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] if size > included_body_bytes as size_t { } else { - unsafe{ __assert_fail( - b"size > (size_t)included_body_bytes\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 1253 as u32, - (*::std::mem::transmute::< - &[u8; 94], - &[libc::c_char; 94], - >( - b"CURLcode Curl_buffer_send(struct dynbuf *, struct Curl_easy *, curl_off_t *, curl_off_t, int)\0", - )) - .as_ptr(), - );} - } + __assert_fail( + b"size > (size_t)included_body_bytes\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 1253 as u32, + (*::std::mem::transmute::< + &[u8; 94], + &[libc::c_char; 94], + >( + b"CURLcode Curl_buffer_send(struct dynbuf *, struct Curl_easy *, curl_off_t *, curl_off_t, int)\0", + )) + .as_ptr(), + ); + }} result = CURLE_OK; /* Curl_convert_to_network calls failf if unsuccessful */ @@ -1714,7 +1737,7 @@ pub extern "C" fn Curl_buffer_send( } #[cfg(not(CURL_DISABLE_PROXY))] - let flag: bool = unsafe{((*(*conn).handler).flags & PROTOPT_SSL != 0 + let flag: bool =unsafe{ ((*(*conn).handler).flags & PROTOPT_SSL != 0 || (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32) && (*conn).httpversion as i32 != 20}; #[cfg(CURL_DISABLE_PROXY)] @@ -1723,24 +1746,25 @@ pub extern "C" fn Curl_buffer_send( /* Make sure this doesn't send more body bytes than what the max send speed says. The request bytes do not count to the max speed. */ + unsafe{ if flag { - if unsafe{(*data).set.max_send_speed != 0 && included_body_bytes > (*data).set.max_send_speed} { - let mut overflow: curl_off_t = unsafe{included_body_bytes - (*data).set.max_send_speed}; + if (*data).set.max_send_speed != 0 && included_body_bytes > (*data).set.max_send_speed { + let mut overflow: curl_off_t = included_body_bytes - (*data).set.max_send_speed; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] if (overflow as size_t) < size { } else { - unsafe{ __assert_fail( - b"(size_t)overflow < size\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 1275 as u32, - (*::std::mem::transmute::< - &[u8; 94], - &[libc::c_char; 94], - >( - b"CURLcode Curl_buffer_send(struct dynbuf *, struct Curl_easy *, curl_off_t *, curl_off_t, int)\0", - )) - .as_ptr(), - );} + __assert_fail( + b"(size_t)overflow < size\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 1275 as u32, + (*::std::mem::transmute::< + &[u8; 94], + &[libc::c_char; 94], + >( + b"CURLcode Curl_buffer_send(struct dynbuf *, struct Curl_easy *, curl_off_t *, curl_off_t, int)\0", + )) + .as_ptr(), + ); } sendsize = size.wrapping_sub(overflow as size_t); } else { @@ -1753,10 +1777,10 @@ pub extern "C" fn Curl_buffer_send( must copy the data to the uploadbuffer first, since that is the buffer we will be using if this send is retried later. */ - result = unsafe{Curl_get_upload_buffer(data)}; + result = Curl_get_upload_buffer(data); if result as u64 != 0 { /* malloc failed, free memory and return to the caller */ - unsafe{Curl_dyn_free(in_0);} + Curl_dyn_free(in_0); return result; } /* We never send more than upload_buffer_size bytes in one single chunk @@ -1764,16 +1788,16 @@ pub extern "C" fn Curl_buffer_send( needs to fit into the normal read-callback buffer later on and that buffer is using this size. */ - if unsafe{sendsize > (*data).set.upload_buffer_size as size_t} { - sendsize = unsafe{(*data).set.upload_buffer_size as size_t}; + if sendsize > (*data).set.upload_buffer_size as size_t { + sendsize = (*data).set.upload_buffer_size as size_t; } - unsafe{memcpy( + memcpy( (*data).state.ulbuf as *mut libc::c_void, ptr as *const libc::c_void, sendsize, - );} - ptr = unsafe{(*data).state.ulbuf}; + ); + ptr = (*data).state.ulbuf; } else { #[cfg(CURLDEBUG)] { @@ -1781,32 +1805,32 @@ pub extern "C" fn Curl_buffer_send( sends */ let mut p: *mut libc::c_char = - unsafe{getenv(b"CURL_SMALLREQSEND\0" as *const u8 as *const libc::c_char)}; + getenv(b"CURL_SMALLREQSEND\0" as *const u8 as *const libc::c_char); if !p.is_null() { - let mut altsize: size_t = unsafe{strtoul(p, 0 as *mut *mut libc::c_char, 10)}; + let mut altsize: size_t = strtoul(p, 0 as *mut *mut libc::c_char, 10); if altsize != 0 { sendsize = if size < altsize { size } else { altsize }; } else { sendsize = size; } - } else if unsafe{(*data).set.max_send_speed != 0 - && included_body_bytes > (*data).set.max_send_speed} + } else if (*data).set.max_send_speed != 0 + && included_body_bytes > (*data).set.max_send_speed { - let mut overflow_0: curl_off_t = unsafe{included_body_bytes - (*data).set.max_send_speed}; + let mut overflow_0: curl_off_t = included_body_bytes - (*data).set.max_send_speed; if (overflow_0 as size_t) < size { } else { - unsafe{ __assert_fail( - b"(size_t)overflow < size\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 1326 as u32, - (*::std::mem::transmute::< - &[u8; 94], - &[libc::c_char; 94], - >( - b"CURLcode Curl_buffer_send(struct dynbuf *, struct Curl_easy *, curl_off_t *, curl_off_t, int)\0", - )) - .as_ptr(), - );} + __assert_fail( + b"(size_t)overflow < size\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 1326 as u32, + (*::std::mem::transmute::< + &[u8; 94], + &[libc::c_char; 94], + >( + b"CURLcode Curl_buffer_send(struct dynbuf *, struct Curl_easy *, curl_off_t *, curl_off_t, int)\0", + )) + .as_ptr(), + ); } sendsize = size.wrapping_sub(overflow_0 as size_t); } else { @@ -1818,15 +1842,15 @@ pub extern "C" fn Curl_buffer_send( /* Make sure this doesn't send more body bytes than what the max send speed says. The request bytes do not count to the max speed. */ - if unsafe{(*data).set.max_send_speed != 0 && included_body_bytes > (*data).set.max_send_speed} { - let mut overflow_0: curl_off_t = unsafe{included_body_bytes - (*data).set.max_send_speed}; + if (*data).set.max_send_speed != 0 && included_body_bytes > (*data).set.max_send_speed { + let mut overflow_0: curl_off_t = included_body_bytes - (*data).set.max_send_speed; sendsize = size.wrapping_sub(overflow_0 as size_t); } else { sendsize = size; } } } - + } result = unsafe{Curl_write( data, sockfd, @@ -1836,6 +1860,7 @@ pub extern "C" fn Curl_buffer_send( )}; if result as u64 == 0 { + unsafe{ /* * Note that we may not send the entire chunk at once, and we have a set * number of data bytes at the end of the big buffer (out of which we may @@ -1850,41 +1875,41 @@ pub extern "C" fn Curl_buffer_send( /* this data _may_ contain binary stuff */ let mut bodylen: size_t = (amount as u64).wrapping_sub(headlen); - unsafe{ Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);} + Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen); if bodylen != 0 { /* there was body data sent beyond the initial header part, pass that on to the debug callback too */ - unsafe{ Curl_debug( + Curl_debug( data, CURLINFO_DATA_OUT, ptr.offset(headlen as isize), bodylen, - );} + ); } /* 'amount' can never be a very large value here so typecasting it so a signed 31 bit value should not cause problems even if ssize_t is 64bit */ - unsafe{ *bytes_written += amount;} + *bytes_written += amount; if !http.is_null() { /* if we sent a piece of the body here, up the byte counter for it accordingly */ - unsafe{ (*data).req.writebytecount = ((*data).req.writebytecount as u64).wrapping_add(bodylen) + (*data).req.writebytecount = ((*data).req.writebytecount as u64).wrapping_add(bodylen) as curl_off_t as curl_off_t; - Curl_pgrsSetUploadCounter(data, (*data).req.writebytecount);} + Curl_pgrsSetUploadCounter(data, (*data).req.writebytecount); if amount as size_t != size { /* The whole request could not be sent in one system call. We must queue it up and send it later when we get the chance. We must not loop here and wait until it might work again. */ - size = (size as u64).wrapping_sub(amount as u64) as size_t; + size = (size as u64).wrapping_sub(amount as u64) as size_t as size_t; - ptr = unsafe{(Curl_dyn_ptr(in_0)).offset(amount as isize)}; + ptr = (Curl_dyn_ptr(in_0)).offset(amount as isize); /* backup the currently set pointers */ - unsafe{(*http).backup.fread_func = (*data).state.fread_func; + (*http).backup.fread_func = (*data).state.fread_func; (*http).backup.fread_in = (*data).state.in_0; (*http).backup.postdata = (*http).postdata; (*http).backup.postsize = (*http).postsize; @@ -1916,11 +1941,11 @@ pub extern "C" fn Curl_buffer_send( /* this much data is remaining header: */ (*data).req.pendingheader = headersize.wrapping_sub(headlen) as curl_off_t; (*http).send_buffer = *in_0; /* copy the whole struct */ - (*http).sending = HTTPSEND_REQUEST;} + (*http).sending = HTTPSEND_REQUEST; return CURLE_OK; } - unsafe{ (*http).sending = HTTPSEND_BODY;} + (*http).sending = HTTPSEND_BODY; } else if amount as size_t != size { /* We have no continue-send mechanism now, fail. This can only happen when this function is used from the CONNECT sending function. We @@ -1932,7 +1957,8 @@ pub extern "C" fn Curl_buffer_send( return CURLE_SEND_ERROR; } } - unsafe{ Curl_dyn_free(in_0); +} +unsafe{Curl_dyn_free(in_0); /* no remaining header data */ (*data).req.pendingheader = 0 as curl_off_t;} @@ -1948,7 +1974,8 @@ pub extern "C" fn Curl_buffer_send( mut included_body_bytes: curl_off_t, mut socketindex: i32, ) -> CURLcode { - return CURLE_OK; + unsafe{ + return CURLE_OK;} } /* @@ -1958,7 +1985,7 @@ pub extern "C" fn Curl_buffer_send( * Pass headers WITH the colon. */ #[no_mangle] -pub extern "C" fn Curl_compareheader( +pub extern "C" fn Curl_compareheader( mut headerline: *const libc::c_char, /* line to check */ mut header: *const libc::c_char, /* header keyword _with_ colon */ mut content: *const libc::c_char, /* content string to find */ @@ -1979,7 +2006,7 @@ pub extern "C" fn Curl_compareheader( } /* pass the header */ - start = unsafe{&*headerline.offset(hlen as isize) as *const libc::c_char}; + start =unsafe{ &*headerline.offset(hlen as isize) as *const libc::c_char}; /* pass all whitespace */ while unsafe{*start as i32 != 0 && Curl_isspace(*start as u8 as i32) != 0} { @@ -1990,7 +2017,7 @@ pub extern "C" fn Curl_compareheader( end = unsafe{strchr(start, '\r' as i32)}; /* lines end with CRLF */ if end.is_null() { /* in case there's a non-standard compliant line here */ - end = unsafe{strchr(start, '\n' as i32)}; + end =unsafe{ strchr(start, '\n' as i32)}; if end.is_null() { /* hm, there's no line ending here, use the zero byte! */ @@ -1998,16 +2025,18 @@ pub extern "C" fn Curl_compareheader( } } - len = unsafe{end.offset_from(start) as size_t}; /* length of the content part of the input line */ + len = unsafe{end.offset_from(start) as i64 as size_t}; /* length of the content part of the input line */ clen = unsafe{strlen(content)}; /* length of the word to find */ /* find the content string in the rest of the line */ while len >= clen { - if unsafe{Curl_strncasecompare(start, content, clen) != 0} { + unsafe{ + if Curl_strncasecompare(start, content, clen) != 0 { return true; /* match! */ } len = len.wrapping_sub(1); - start = unsafe{start.offset(1)}; + start = start.offset(1); + } } return false; /* no match */ } @@ -2017,47 +2046,49 @@ pub extern "C" fn Curl_compareheader( * the generic Curl_connect(). */ #[no_mangle] -pub extern "C" fn Curl_http_connect( +pub extern "C" fn Curl_http_connect( mut data: *mut Curl_easy, mut done: *mut bool, ) -> CURLcode { let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = unsafe{(*data).conn}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + /* We default to persistent connections. We set this already in this connect function to make the re-use checks properly be able to check this bit. */ - unsafe{ #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, FIRSTSOCKET); + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + unsafe{Curl_conncontrol(conn, FIRSTSOCKET);} #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( + unsafe{Curl_conncontrol( conn, FIRSTSOCKET, b"HTTP default\0" as *const u8 as *const libc::c_char, );} + unsafe{ match () { #[cfg(not(CURL_DISABLE_PROXY))] _ => { /* the CONNECT procedure might not have been completed */ - result = unsafe{Curl_proxy_connect(data, 0 as i32)}; + result = Curl_proxy_connect(data, 0 as i32); if result as u64 != 0 { return result; } - if unsafe{ ((*conn).bits).proxy_connect_closed() != 0} { + if ((*conn).bits).proxy_connect_closed() != 0 { /* this is not an error, just part of the connection negotiation */ return CURLE_OK; } - if unsafe{(*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32 - && !(*conn).bits.proxy_ssl_connected[0 as usize]} + if (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as i32 as u32 + && !(*conn).bits.proxy_ssl_connected[0 as i32 as usize] { return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */ } - if unsafe{Curl_connect_ongoing(conn)} { + if Curl_connect_ongoing(conn) { /* nothing else to do except wait right now - we're not done here. */ return CURLE_OK; } - if unsafe{((*data).set).haproxyprotocol() != 0 }{ + if ((*data).set).haproxyprotocol() != 0 { /* add HAProxy PROXY protocol header */ result = add_haproxy_protocol_header(data); if result as u64 != 0 { @@ -2068,14 +2099,15 @@ pub extern "C" fn Curl_http_connect( #[cfg(CURL_DISABLE_PROXY)] _ => {} } +} if unsafe{(*(*conn).given).protocol & CURLPROTO_HTTPS != 0} { /* perform SSL initialization */ - result = https_connecting(data, done); + result = unsafe{https_connecting(data, done)}; if result as u64 != 0 { return result; } } else { - unsafe{ *done = true;} + unsafe{ *done = true;} } return CURLE_OK; } @@ -2083,18 +2115,19 @@ pub extern "C" fn Curl_http_connect( /* this returns the socket to wait for in the DO and DOING state for the multi interface and then we're always _sending_ a request and thus we wait for the single socket to become writable only */ - extern "C" fn http_getsock_do( +extern "C" fn http_getsock_do( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut socks: *mut curl_socket_t, ) -> i32 { /* write mode */ - unsafe{*socks.offset(0 as isize) = (*conn).sock[FIRSTSOCKET as usize];} + unsafe{ + *socks.offset(0 as isize) = (*conn).sock[FIRSTSOCKET as usize];} return GETSOCK_WRITESOCK(0); } #[cfg(not(CURL_DISABLE_PROXY))] - extern "C" fn add_haproxy_protocol_header(mut data: *mut Curl_easy) -> CURLcode { +extern "C" fn add_haproxy_protocol_header(mut data: *mut Curl_easy) -> CURLcode { let mut req: dynbuf = dynbuf { bufr: 0 as *mut libc::c_char, leng: 0, @@ -2107,9 +2140,9 @@ the single socket to become writable only */ let mut tcp_version: *const libc::c_char = 0 as *const libc::c_char; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{!((*data).conn).is_null()} { + unsafe{if !((*data).conn).is_null() { } else { - unsafe{__assert_fail( + __assert_fail( b"data->conn\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 1546 as u32, @@ -2117,27 +2150,28 @@ the single socket to become writable only */ b"CURLcode add_haproxy_protocol_header(struct Curl_easy *)\0", )) .as_ptr(), - );} - } - unsafe{Curl_dyn_init(&mut req, 2048 as size_t);} + ); + }} + unsafe{ Curl_dyn_init(&mut req, 2048 as size_t);} #[cfg(USE_UNIX_SOCKETS)] - let flag: bool = unsafe{!((*(*data).conn).unix_domain_socket).is_null()}; + let flag: bool =unsafe{ !((*(*data).conn).unix_domain_socket).is_null()}; #[cfg(not(USE_UNIX_SOCKETS))] let flag: bool = false; + unsafe{ if flag { /* the buffer is large enough to hold this! */ - result = unsafe{Curl_dyn_add( + result = Curl_dyn_add( &mut req, b"PROXY UNKNOWN\r\n\0" as *const u8 as *const libc::c_char, - )}; + ); } else { /* Emit the correct prefix for IPv6 */ - tcp_version = if unsafe{((*(*data).conn).bits).ipv6() as i32 != 0 }{ + tcp_version = if ((*(*data).conn).bits).ipv6() as i32 != 0 { b"TCP6\0" as *const u8 as *const libc::c_char } else { b"TCP4\0" as *const u8 as *const libc::c_char }; - result = unsafe{Curl_dyn_addf( + result = Curl_dyn_addf( &mut req as *mut dynbuf, b"PROXY %s %s %s %i %i\r\n\0" as *const u8 as *const libc::c_char, tcp_version, @@ -2145,30 +2179,31 @@ the single socket to become writable only */ ((*data).info.conn_primary_ip).as_mut_ptr(), (*data).info.conn_local_port, (*data).info.conn_primary_port, - )}; - } + ); + }} if result as u64 == 0 { - result = unsafe{Curl_buffer_send( + unsafe{ + result = Curl_buffer_send( &mut req, data, &mut (*data).info.request_size, 0 as curl_off_t, FIRSTSOCKET, - )}; + );} } return result; } #[cfg(USE_SSL)] - extern "C" fn https_connecting(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { +extern "C" fn https_connecting(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = unsafe{(*data).conn}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{!data.is_null() && (*(*(*data).conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0} { + unsafe{if !data.is_null() && (*(*(*data).conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 { } else { - unsafe{__assert_fail( + __assert_fail( b"(data) && (data->conn->handler->flags & (1<<0))\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, @@ -2177,17 +2212,17 @@ the single socket to become writable only */ b"CURLcode https_connecting(struct Curl_easy *, _Bool *)\0", )) .as_ptr(), - );} - } + ); + }} #[cfg(ENABLE_QUIC)] - if unsafe{(*conn).transport as u32 == TRNSPRT_QUIC as u32} { - unsafe{ *done = true;} + unsafe{if (*conn).transport as u32 == TRNSPRT_QUIC as i32 as u32 { + *done = true; return CURLE_OK; - } - + }} + unsafe{ /* perform SSL initialization for this socket */ - result = unsafe{Curl_ssl_connect_nonblocking(data, conn, false, 0, done)}; - if result as u64 != 0 {unsafe{ + result = Curl_ssl_connect_nonblocking(data, conn, false, 0, done); + if result as u64 != 0 { #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 1); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] @@ -2195,40 +2230,41 @@ the single socket to become writable only */ conn, 1, b"Failed HTTPS connection\0" as *const u8 as *const libc::c_char, - );} + ); } - return result; + return result;} } #[cfg(not(USE_SSL))] - extern "C" fn https_connecting(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { +unsafe extern "C" fn https_connecting(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { return CURLE_COULDNT_CONNECT; } #[cfg(USE_SSL)] - extern "C" fn https_getsock( +extern "C" fn https_getsock( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut socks: *mut curl_socket_t, ) -> i32 { - if unsafe{(*(*conn).handler).flags & PROTOPT_SSL != 0} { - return unsafe{((*Curl_ssl).getsock).expect("non-null function pointer")(conn, socks)}; + unsafe{ + if (*(*conn).handler).flags & PROTOPT_SSL != 0 { + return ((*Curl_ssl).getsock).expect("non-null function pointer")(conn, socks); } - return 0; + return 0;} } #[no_mangle] -pub extern "C" fn Curl_http_done( +pub extern "C" fn Curl_http_done( mut data: *mut Curl_easy, mut status: CURLcode, mut premature: bool, ) -> CURLcode { - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut http: *mut HTTP = unsafe{(*data).req.p.http}; - + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut http: *mut HTTP =unsafe{ (*data).req.p.http}; + unsafe{ /* Clear multipass flag. If authentication isn't done yet, then it will get - * a chance to be set back to true when we output the next auth header */ - unsafe{(*data).state.authhost.set_multipass(0 as bit); + * a chance to be set back to true when we output the next auth header */ + (*data).state.authhost.set_multipass(0 as bit); (*data).state.authproxy.set_multipass(0 as bit); Curl_unencode_cleanup(data); @@ -2236,11 +2272,11 @@ pub extern "C" fn Curl_http_done( /* set the proper values (possibly modified on POST) */ (*conn).seek_func = (*data).set.seek_func; /* restore */ (*conn).seek_client = (*data).set.seek_client; /* restore */ - } + if http.is_null() { return CURLE_OK; } - unsafe{ + Curl_dyn_free(&mut (*http).send_buffer); Curl_http2_done(data, premature); #[cfg(any( @@ -2251,23 +2287,23 @@ pub extern "C" fn Curl_http_done( Curl_mime_cleanpart(&mut (*http).form); Curl_dyn_reset(&mut (*data).state.headerb); #[cfg(all(not(CURL_DISABLE_HTTP), USE_HYPER))] - Curl_hyper_done(data);} + Curl_hyper_done(data); if status as u64 != 0 { return status; } - if unsafe{!premature /* this check is pointless when DONE is called before the - entire operation is complete */ - && ((*conn).bits).retry() == 0 - && ((*data).set).connect_only() == 0 - && (*data).req.bytecount + (*data).req.headerbytecount - (*data).req.deductheadercount - <= 0 as i64} + if !premature /* this check is pointless when DONE is called before the + entire operation is complete */ + && ((*conn).bits).retry() == 0 + && ((*data).set).connect_only() == 0 + && (*data).req.bytecount + (*data).req.headerbytecount - (*data).req.deductheadercount + <= 0 as i64 { /* If this connection isn't simply closed to be retried, AND nothing was - read from the HTTP server (that counts), this can't be right so we - return an error here */ - unsafe{Curl_failf( + read from the HTTP server (that counts), this can't be right so we + return an error here */ + Curl_failf( data, b"Empty reply from server\0" as *const u8 as *const libc::c_char, ); @@ -2279,9 +2315,9 @@ pub extern "C" fn Curl_http_done( conn, 2, b"Empty reply from server\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_GOT_NOTHING; - } + }} return CURLE_OK; } @@ -2295,82 +2331,85 @@ pub extern "C" fn Curl_http_done( * 1.0. */ #[no_mangle] -pub extern "C" fn Curl_use_http_1_1plus( +pub extern "C" fn Curl_use_http_1_1plus( mut data: *const Curl_easy, mut conn: *const connectdata, ) -> bool { - if unsafe{(*data).state.httpversion as i32 == 10 || (*conn).httpversion as i32 == 10} { + unsafe{ + if (*data).state.httpversion as i32 == 10 || (*conn).httpversion as i32 == 10 { return false; } - if unsafe{(*data).state.httpwant as i32 == CURL_HTTP_VERSION_1_0 as i32 - && (*conn).httpversion as i32 <= 10} + if (*data).state.httpwant as i32 == CURL_HTTP_VERSION_1_0 as i32 + && (*conn).httpversion as i32 <= 10 { return false; } - return unsafe{(*data).state.httpwant as i32 == CURL_HTTP_VERSION_NONE as i32 - || (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_1_1 as i32}; + return (*data).state.httpwant as i32 == CURL_HTTP_VERSION_NONE as i32 + || (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_1_1 as i32;} } #[cfg(not(USE_HYPER))] - extern "C" fn get_http_string( +extern "C" fn get_http_string( mut data: *const Curl_easy, mut conn: *const connectdata, ) -> *const libc::c_char { + unsafe{ #[cfg(ENABLE_QUIC)] - if unsafe{(*data).state.httpwant as i32 == CURL_HTTP_VERSION_3 as i32 - || (*conn).httpversion as i32 == 30} + if (*data).state.httpwant as i32 == CURL_HTTP_VERSION_3 as i32 + || (*conn).httpversion as i32 == 30 { return b"3\0" as *const u8 as *const libc::c_char; } #[cfg(USE_NGHTTP2)] - if !(unsafe{(*conn).proto.httpc.h2}).is_null() { + if !((*conn).proto.httpc.h2).is_null() { return b"2\0" as *const u8 as *const libc::c_char; } if Curl_use_http_1_1plus(data, conn) { return b"1.1\0" as *const u8 as *const libc::c_char; } - return b"1.0\0" as *const u8 as *const libc::c_char; + return b"1.0\0" as *const u8 as *const libc::c_char;} } /* check and possibly add an Expect: header */ - extern "C" fn expect100( +extern "C" fn expect100( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut req: *mut dynbuf, ) -> CURLcode { let mut result: CURLcode = CURLE_OK; - unsafe{(*data).state.set_expect100header(0 as bit);} /* default to false unless it is set - to TRUE below */ - if unsafe{((*data).state).disableexpect() == 0 + unsafe{ + (*data).state.set_expect100header(0 as bit); /* default to false unless it is set + to TRUE below */ + if ((*data).state).disableexpect() == 0 && Curl_use_http_1_1plus(data, conn) as i32 != 0 - && ((*conn).httpversion as i32) < 20} + && ((*conn).httpversion as i32) < 20 { /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an - Expect: 100-continue to the headers which actually speeds up post - operations (as there is one packet coming back from the web server) */ + Expect: 100-continue to the headers which actually speeds up post + operations (as there is one packet coming back from the web server) */ let mut ptr: *const libc::c_char = - unsafe{Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char)}; + Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char); if !ptr.is_null() { - unsafe{(*data).state.set_expect100header(Curl_compareheader( + (*data).state.set_expect100header(Curl_compareheader( ptr, b"Expect:\0" as *const u8 as *const libc::c_char, b"100-continue\0" as *const u8 as *const libc::c_char, - ) as bit);} + ) as bit); } else { - result = unsafe{Curl_dyn_add( + result = Curl_dyn_add( req, b"Expect: 100-continue\r\n\0" as *const u8 as *const libc::c_char, - )}; + ); if result as u64 == 0 { - unsafe{(*data).state.set_expect100header(1 as bit);} + (*data).state.set_expect100header(1 as bit); } } - } + }} return result; } #[no_mangle] -pub extern "C" fn Curl_http_compile_trailers( +pub extern "C" fn Curl_http_compile_trailers( mut trailers: *mut curl_slist, mut b: *mut dynbuf, mut handle: *mut Curl_easy, @@ -2379,14 +2418,13 @@ pub extern "C" fn Curl_http_compile_trailers( let mut result: CURLcode = CURLE_OK; let mut endofline_native: *const libc::c_char = 0 as *const libc::c_char; let mut endofline_network: *const libc::c_char = 0 as *const libc::c_char; - // TODO 测试通过后,把注释删掉 - let flag: bool = if cfg!(CURL_DO_LINEEND_CONV) { - unsafe{ ((*handle).state).prefer_ascii() as i32 != 0 || ((*handle).set).crlf() as i32 != 0} + let flag: bool = unsafe{if cfg!(CURL_DO_LINEEND_CONV) { + ((*handle).state).prefer_ascii() as i32 != 0 || ((*handle).set).crlf() as i32 != 0 } else { - unsafe{ ((*handle).set).crlf() as i32 != 0} + ((*handle).set).crlf() as i32 != 0 /* \n will become \r\n later on */ - }; + }}; if flag { endofline_native = b"\n\0" as *const u8 as *const libc::c_char; endofline_network = b"\n\0" as *const u8 as *const libc::c_char; @@ -2395,38 +2433,41 @@ pub extern "C" fn Curl_http_compile_trailers( endofline_network = b"\r\n\0" as *const u8 as *const libc::c_char; } while !trailers.is_null() { + unsafe{ /* only add correctly formatted trailers */ - ptr = unsafe{strchr((*trailers).data, ':' as i32)}; - if unsafe{!ptr.is_null() && *ptr.offset(1 as isize) as i32 == ' ' as i32} { - result = unsafe{Curl_dyn_add(b, (*trailers).data)}; + ptr = strchr((*trailers).data, ':' as i32); + if !ptr.is_null() && *ptr.offset(1 as isize) as i32 == ' ' as i32 { + result = Curl_dyn_add(b, (*trailers).data); if result as u64 != 0 { return result; } - result = unsafe{Curl_dyn_add(b, endofline_native)}; + result = Curl_dyn_add(b, endofline_native); if result as u64 != 0 { return result; } } else { - unsafe{Curl_infof( + Curl_infof( handle, b"Malformatted trailing header ! Skipping trailer.\0" as *const u8 as *const libc::c_char, - );} + ); } - trailers =unsafe{ (*trailers).next}; + trailers = (*trailers).next; + } } - result = unsafe{Curl_dyn_add(b, endofline_network)}; + result =unsafe{ Curl_dyn_add(b, endofline_network)}; return result; } #[cfg(USE_HYPER)] #[no_mangle] -pub extern "C" fn Curl_add_custom_headers( +pub extern "C" fn Curl_add_custom_headers( mut data: *mut Curl_easy, mut is_connect: bool, mut req: *mut dynbuf, ) -> CURLcode { - let mut conn: *mut connectdata = unsafe{(*data).conn}; + unsafe{ + let mut conn: *mut connectdata = (*data).conn; let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; let mut h: [*mut curl_slist; 2] = [0 as *mut curl_slist; 2]; let mut headers: *mut curl_slist = 0 as *mut curl_slist; @@ -2436,7 +2477,7 @@ pub extern "C" fn Curl_add_custom_headers( if is_connect { proxy = HEADER_CONNECT; } else { - proxy = (if unsafe{((*conn).bits).httpproxy() as i32 != 0 && ((*conn).bits).tunnel_proxy() == 0} { + proxy = (if ((*conn).bits).httpproxy() as i32 != 0 && ((*conn).bits).tunnel_proxy() == 0 { HEADER_PROXY as i32 } else { HEADER_SERVER as i32 @@ -2444,20 +2485,20 @@ pub extern "C" fn Curl_add_custom_headers( } match proxy as u32 { 0 => { - h[0 as usize] = unsafe{(*data).set.headers}; + h[0 as usize] = (*data).set.headers; } 1 => { - h[0 as usize] = unsafe{(*data).set.headers}; - if unsafe{((*data).set).sep_headers() != 0} { - h[1 as usize] = unsafe{(*data).set.proxyheaders}; + h[0 as usize] = (*data).set.headers; + if ((*data).set).sep_headers() != 0 { + h[1 as usize] = (*data).set.proxyheaders; numlists += 1; } } 2 => { - if unsafe{((*data).set).sep_headers() != 0 }{ - h[0 as usize] = unsafe{(*data).set.proxyheaders}; + if ((*data).set).sep_headers() != 0 { + h[0 as usize] = (*data).set.proxyheaders; } else { - h[0 as usize] = unsafe{(*data).set.headers}; + h[0 as usize] = (*data).set.headers; } } _ => {} @@ -2467,85 +2508,85 @@ pub extern "C" fn Curl_add_custom_headers( headers = h[i as usize]; while !headers.is_null() { let mut semicolonp: *mut libc::c_char = 0 as *mut libc::c_char; - ptr = unsafe{strchr((*headers).data, ':' as i32)}; + ptr = strchr((*headers).data, ':' as i32); if ptr.is_null() { let mut optr: *mut libc::c_char = 0 as *mut libc::c_char; - ptr = unsafe{strchr((*headers).data, ';' as i32)}; + ptr = strchr((*headers).data, ';' as i32); if !ptr.is_null() { optr = ptr; - ptr = unsafe{ptr.offset(1)}; - while unsafe{*ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0} { - ptr = unsafe{ptr.offset(1)}; + ptr = ptr.offset(1); + while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + ptr = ptr.offset(1); } - if unsafe{*ptr != 0} { + if *ptr != 0 { optr = 0 as *mut libc::c_char; } else { - ptr = unsafe{ptr.offset(-1)}; - if unsafe{*ptr as i32 == ';' as i32 }{ + ptr = ptr.offset(-1); + if *ptr as i32 == ';' as i32 { match () { #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] _ => { - semicolonp =unsafe{ Curl_cstrdup.expect("non-null function pointer")( + semicolonp = Curl_cstrdup.expect("non-null function pointer")( (*headers).data, - )}; + ); } #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] _ => { - semicolonp = unsafe{curl_dbg_strdup( + semicolonp = curl_dbg_strdup( (*headers).data, 1857 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - )}; + ); } } if semicolonp.is_null() { - unsafe{Curl_dyn_free(req);} + Curl_dyn_free(req); return CURLE_OUT_OF_MEMORY; } - unsafe{ *semicolonp.offset(ptr.offset_from((*headers).data) as i64 as isize) = - ':' as i32 as libc::c_char;} - optr =unsafe{ &mut *semicolonp + *semicolonp.offset(ptr.offset_from((*headers).data) as i64 as isize) = + ':' as i32 as libc::c_char; + optr = &mut *semicolonp .offset(ptr.offset_from((*headers).data) as i64 as isize) - as *mut libc::c_char}; + as *mut libc::c_char; } } ptr = optr; } } if !ptr.is_null() { - ptr =unsafe{ ptr.offset(1)}; - while unsafe{*ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 }{ - ptr = unsafe{ptr.offset(1)}; + ptr = ptr.offset(1); + while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + ptr = ptr.offset(1); } - if unsafe{*ptr as i32 != 0 || !semicolonp.is_null()} { + if *ptr as i32 != 0 || !semicolonp.is_null() { let mut result: CURLcode = CURLE_OK; let mut compare: *mut libc::c_char = if !semicolonp.is_null() { semicolonp } else { - unsafe{(*headers).data} + (*headers).data }; - if unsafe{!(!((*data).state.aptr.host).is_null() + if !(!((*data).state.aptr.host).is_null() && curl_strnequal( b"Host:\0" as *const u8 as *const libc::c_char, compare, strlen(b"Host:\0" as *const u8 as *const libc::c_char), - ) != 0)} + ) != 0) { - if unsafe{!((*data).state.httpreq as u32 == HTTPREQ_POST_FORM as i32 as u32 + if !((*data).state.httpreq as u32 == HTTPREQ_POST_FORM as i32 as u32 && curl_strnequal( b"Content-Type:\0" as *const u8 as *const libc::c_char, compare, strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), - ) != 0)} + ) != 0) { - if unsafe{!((*data).state.httpreq as u32 == HTTPREQ_POST_MIME as i32 as u32 + if !((*data).state.httpreq as u32 == HTTPREQ_POST_MIME as i32 as u32 && curl_strnequal( b"Content-Type:\0" as *const u8 as *const libc::c_char, compare, strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), - ) != 0)} + ) != 0) { - if unsafe{!(((*conn).bits).authneg() as i32 != 0 + if !(((*conn).bits).authneg() as i32 != 0 && curl_strnequal( b"Content-Length:\0" as *const u8 as *const libc::c_char, compare, @@ -2553,9 +2594,9 @@ pub extern "C" fn Curl_add_custom_headers( b"Content-Length:\0" as *const u8 as *const libc::c_char, ), - ) != 0)} + ) != 0) { - if unsafe{!(!((*data).state.aptr.te).is_null() + if !(!((*data).state.aptr.te).is_null() && curl_strnequal( b"Connection:\0" as *const u8 as *const libc::c_char, compare, @@ -2563,9 +2604,9 @@ pub extern "C" fn Curl_add_custom_headers( b"Connection:\0" as *const u8 as *const libc::c_char, ), - ) != 0)} + ) != 0) { - if unsafe{!((*conn).httpversion as i32 >= 20 as i32 + if !((*conn).httpversion as i32 >= 20 as i32 && curl_strnequal( b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, @@ -2574,9 +2615,9 @@ pub extern "C" fn Curl_add_custom_headers( b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, ), - ) != 0)} + ) != 0) { - if unsafe{!((curl_strnequal( + if !((curl_strnequal( b"Authorization:\0" as *const u8 as *const libc::c_char, compare, @@ -2601,13 +2642,13 @@ pub extern "C" fn Curl_add_custom_headers( && Curl_strcasecompare( (*data).state.first_host, (*conn).host.name, - ) == 0))} + ) == 0)) { - result = unsafe{Curl_hyper_header( + result = Curl_hyper_header( data, req as *mut hyper_headers, compare, - )}; + ); } } } @@ -2617,27 +2658,28 @@ pub extern "C" fn Curl_add_custom_headers( } if !semicolonp.is_null() { #[cfg(not(CURLDEBUG))] - unsafe{ Curl_cfree.expect("non-null function pointer")( + Curl_cfree.expect("non-null function pointer")( semicolonp as *mut libc::c_void, - );} + ); #[cfg(CURLDEBUG)] - unsafe{ curl_dbg_free( + curl_dbg_free( semicolonp as *mut libc::c_void, 1929 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); } if result as u64 != 0 { return result; } } } - headers = unsafe{(*headers).next}; + headers = (*headers).next; } i += 1; } return CURLE_OK; } +} const HEADER_SERVER: u32 = 0; /* direct to server */ const HEADER_PROXY: u32 = 1; /* regular request to proxy */ @@ -2645,18 +2687,18 @@ const HEADER_CONNECT: u32 = 2; /* sending CONNECT to a proxy */ #[cfg(not(USE_HYPER))] #[no_mangle] -pub extern "C" fn Curl_add_custom_headers( +pub extern "C" fn Curl_add_custom_headers( mut data: *mut Curl_easy, mut is_connect: bool, mut req: *mut dynbuf, ) -> CURLcode { - let mut conn: *mut connectdata = unsafe{(*data).conn}; + let mut conn: *mut connectdata =unsafe{ (*data).conn}; let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; let mut h: [*mut curl_slist; 2] = [0 as *mut curl_slist; 2]; let mut headers: *mut curl_slist = 0 as *mut curl_slist; let mut numlists: i32 = 1; /* by default */ let mut i: i32 = 0; - + unsafe{ match () { #[cfg(not(CURL_DISABLE_PROXY))] _ => { @@ -2664,8 +2706,8 @@ pub extern "C" fn Curl_add_custom_headers( if is_connect { proxy = HEADER_CONNECT; } else { - proxy = (if unsafe{((*conn).bits).httpproxy() as i32 != 0 - && ((*conn).bits).tunnel_proxy() == 0} + proxy = (if ((*conn).bits).httpproxy() as i32 != 0 + && ((*conn).bits).tunnel_proxy() == 0 { HEADER_PROXY as i32 } else { @@ -2674,20 +2716,20 @@ pub extern "C" fn Curl_add_custom_headers( } match proxy as u32 { HEADER_SERVER => { - h[0 as usize] = unsafe{(*data).set.headers}; + h[0 as usize] = (*data).set.headers; } HEADER_PROXY => { - h[0 as usize] = unsafe{(*data).set.headers}; - if unsafe{((*data).set).sep_headers() != 0} { - h[1 as usize] =unsafe{ (*data).set.proxyheaders}; + h[0 as usize] = (*data).set.headers; + if ((*data).set).sep_headers() != 0 { + h[1 as usize] = (*data).set.proxyheaders; numlists += 1; } } HEADER_CONNECT => { - if unsafe{((*data).set).sep_headers() != 0} { - h[0 as usize] = unsafe{(*data).set.proxyheaders}; + if ((*data).set).sep_headers() != 0 { + h[0 as usize] = (*data).set.proxyheaders; } else { - h[0 as usize] = unsafe{(*data).set.headers}; + h[0 as usize] = (*data).set.headers; } } _ => {} @@ -2695,7 +2737,7 @@ pub extern "C" fn Curl_add_custom_headers( } #[cfg(CURL_DISABLE_PROXY)] _ => { - h[0 as usize] = unsafe{(*data).set.headers}; + h[0 as usize] = (*data).set.headers; } } @@ -2706,53 +2748,53 @@ pub extern "C" fn Curl_add_custom_headers( while !headers.is_null() { let mut semicolonp: *mut libc::c_char = 0 as *mut libc::c_char; - ptr = unsafe{strchr((*headers).data, ':' as i32)}; + ptr = strchr((*headers).data, ':' as i32); if ptr.is_null() { let mut optr: *mut libc::c_char = 0 as *mut libc::c_char; /* no colon, semicolon? */ - ptr = unsafe{strchr((*headers).data, ';' as i32)}; + ptr = strchr((*headers).data, ';' as i32); if !ptr.is_null() { optr = ptr; - ptr = unsafe{ptr.offset(1)}; /* pass the semicolon */ - while unsafe{*ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0} { - ptr = unsafe{ptr.offset(1)}; + ptr = ptr.offset(1); /* pass the semicolon */ + while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + ptr = ptr.offset(1); } - if unsafe{*ptr != 0} { + if *ptr != 0 { optr = 0 as *mut libc::c_char; } else { - ptr = unsafe{ptr.offset(-1)}; - if unsafe{*ptr as i32 == ';' as i32} { + ptr = ptr.offset(-1); + if *ptr as i32 == ';' as i32 { /* this may be used for something else in the future */ match () { #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] _ => { - semicolonp = unsafe{Curl_cstrdup.expect("non-null function pointer")( + semicolonp = Curl_cstrdup.expect("non-null function pointer")( (*headers).data, - )}; + ); } #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] _ => { - semicolonp = unsafe{curl_dbg_strdup( + semicolonp = curl_dbg_strdup( (*headers).data, 1857, b"http.c\0" as *const u8 as *const libc::c_char, - )}; + ); } } if semicolonp.is_null() { /* copy the source */ #[cfg(not(USE_HYPER))] - unsafe{Curl_dyn_free(req);} + Curl_dyn_free(req); return CURLE_OUT_OF_MEMORY; } /* put a colon where the semicolon is */ - unsafe{ *semicolonp.offset(ptr.offset_from((*headers).data) as i64 as isize) = - ':' as i32 as libc::c_char;} + *semicolonp.offset(ptr.offset_from((*headers).data) as i64 as isize) = + ':' as i32 as libc::c_char; /* point at the colon */ - optr = unsafe{&mut *semicolonp + optr = &mut *semicolonp .offset(ptr.offset_from((*headers).data) as i64 as isize) - as *mut libc::c_char}; + as *mut libc::c_char; } } ptr = optr; @@ -2760,125 +2802,125 @@ pub extern "C" fn Curl_add_custom_headers( } if !ptr.is_null() { /* we require a colon for this to be a true header */ - ptr = unsafe{ptr.offset(1)}; - while unsafe{*ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0} { - ptr = unsafe{ptr.offset(1)}; + ptr = ptr.offset(1); + while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + ptr = ptr.offset(1); } - if unsafe{*ptr as i32 != 0 || !semicolonp.is_null()} { + if *ptr as i32 != 0 || !semicolonp.is_null() { /* only send this if the contents was non-blank or done special */ let mut result: CURLcode = CURLE_OK; let mut compare: *mut libc::c_char = if !semicolonp.is_null() { semicolonp } else { - unsafe{(*headers).data} + (*headers).data }; - if unsafe{!(!((*data).state.aptr.host).is_null() && - /* a Host: header was sent already, don't pass on any custom Host: - header as that will produce *two* in the same request! */ - curl_strnequal( - b"Host:\0" as *const u8 as *const libc::c_char, - compare, - strlen(b"Host:\0" as *const u8 as *const libc::c_char), - ) != 0)} + if !(!((*data).state.aptr.host).is_null() && + /* a Host: header was sent already, don't pass on any custom Host: + header as that will produce *two* in the same request! */ + curl_strnequal( + b"Host:\0" as *const u8 as *const libc::c_char, + compare, + strlen(b"Host:\0" as *const u8 as *const libc::c_char), + ) != 0) { - if unsafe{!((*data).state.httpreq as u32 == HTTPREQ_POST_FORM - /* this header (extended by formdata.c) is sent later */ - && curl_strnequal( - b"Content-Type:\0" as *const u8 as *const libc::c_char, - compare, - strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), - ) != 0)} + if !((*data).state.httpreq as u32 == HTTPREQ_POST_FORM + /* this header (extended by formdata.c) is sent later */ + && curl_strnequal( + b"Content-Type:\0" as *const u8 as *const libc::c_char, + compare, + strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), + ) != 0) { - if unsafe{!((*data).state.httpreq as u32 == HTTPREQ_POST_MIME - /* this header is sent later */ - && curl_strnequal( - b"Content-Type:\0" as *const u8 as *const libc::c_char, - compare, - strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), - ) != 0)} + if !((*data).state.httpreq as u32 == HTTPREQ_POST_MIME + /* this header is sent later */ + && curl_strnequal( + b"Content-Type:\0" as *const u8 as *const libc::c_char, + compare, + strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), + ) != 0) { - if unsafe{!(((*conn).bits).authneg() as i32 != 0 - && - /* while doing auth neg, don't allow the custom length since - we will force length zero then */ - curl_strnequal( - b"Content-Length:\0" as *const u8 as *const libc::c_char, - compare, - strlen( - b"Content-Length:\0" as *const u8 - as *const libc::c_char, - ), - ) != 0)} + if !(((*conn).bits).authneg() as i32 != 0 + && + /* while doing auth neg, don't allow the custom length since + we will force length zero then */ + curl_strnequal( + b"Content-Length:\0" as *const u8 as *const libc::c_char, + compare, + strlen( + b"Content-Length:\0" as *const u8 + as *const libc::c_char, + ), + ) != 0) { - if unsafe{!(!((*data).state.aptr.te).is_null() - && - /* when asking for Transfer-Encoding, don't pass on a custom - Connection: */ - curl_strnequal( - b"Connection:\0" as *const u8 as *const libc::c_char, - compare, - strlen( - b"Connection:\0" as *const u8 - as *const libc::c_char, - ), - ) != 0)} + if !(!((*data).state.aptr.te).is_null() + && + /* when asking for Transfer-Encoding, don't pass on a custom + Connection: */ + curl_strnequal( + b"Connection:\0" as *const u8 as *const libc::c_char, + compare, + strlen( + b"Connection:\0" as *const u8 + as *const libc::c_char, + ), + ) != 0) { - if unsafe{!((*conn).httpversion as i32 >= 20 - && - /* HTTP/2 doesn't support chunked requests */ - curl_strnequal( - b"Transfer-Encoding:\0" as *const u8 - as *const libc::c_char, - compare, - strlen( - b"Transfer-Encoding:\0" as *const u8 - as *const libc::c_char, - ), - ) != 0)} + if !((*conn).httpversion as i32 >= 20 + && + /* HTTP/2 doesn't support chunked requests */ + curl_strnequal( + b"Transfer-Encoding:\0" as *const u8 + as *const libc::c_char, + compare, + strlen( + b"Transfer-Encoding:\0" as *const u8 + as *const libc::c_char, + ), + ) != 0) { - if unsafe{!((curl_strnequal( - b"Authorization:\0" as *const u8 - as *const libc::c_char, - compare, - strlen( - b"Authorization:\0" as *const u8 - as *const libc::c_char, - ), - ) != 0 - || curl_strnequal( - b"Cookie:\0" as *const u8 - as *const libc::c_char, - compare, - strlen( - b"Cookie:\0" as *const u8 - as *const libc::c_char, - ), - ) != 0) - /* be careful of sending this potentially sensitive header to - other hosts */ - && (((*data).state).this_is_a_follow() as i32 != 0 - && !((*data).state.first_host).is_null() - && ((*data).set).allow_auth_to_other_hosts() - == 0 - && Curl_strcasecompare( - (*data).state.first_host, - (*conn).host.name, - ) == 0))} + if !((curl_strnequal( + b"Authorization:\0" as *const u8 + as *const libc::c_char, + compare, + strlen( + b"Authorization:\0" as *const u8 + as *const libc::c_char, + ), + ) != 0 + || curl_strnequal( + b"Cookie:\0" as *const u8 + as *const libc::c_char, + compare, + strlen( + b"Cookie:\0" as *const u8 + as *const libc::c_char, + ), + ) != 0) + /* be careful of sending this potentially sensitive header to + other hosts */ + && (((*data).state).this_is_a_follow() as i32 != 0 + && !((*data).state.first_host).is_null() + && ((*data).set).allow_auth_to_other_hosts() + == 0 + && Curl_strcasecompare( + (*data).state.first_host, + (*conn).host.name, + ) == 0)) { match () { #[cfg(USE_HYPER)] _ => { result = - unsafe{Curl_hyper_header(data, req, compare)}; + Curl_hyper_header(data, req, compare); } #[cfg(not(USE_HYPER))] _ => { - result =unsafe{ Curl_dyn_addf( + result = Curl_dyn_addf( req, b"%s\r\n\0" as *const u8 as *const libc::c_char, compare, - )}; + ); } } } @@ -2890,26 +2932,26 @@ pub extern "C" fn Curl_add_custom_headers( } if !semicolonp.is_null() { #[cfg(not(CURLDEBUG))] - unsafe{ Curl_cfree.expect("non-null function pointer")( + Curl_cfree.expect("non-null function pointer")( semicolonp as *mut libc::c_void, - );} + ); #[cfg(CURLDEBUG)] - unsafe{ curl_dbg_free( + curl_dbg_free( semicolonp as *mut libc::c_void, 1929 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); } if result as u64 != 0 { return result; } } } - headers = unsafe{(*headers).next}; + headers = (*headers).next; } i += 1; } - + } return CURLE_OK; } @@ -2919,10 +2961,11 @@ const CURL_TIMECOND_LASTMOD: u32 = 3; #[cfg(all(not(CURL_DISABLE_PARSEDATE), USE_HYPER))] #[no_mangle] -pub extern "C" fn Curl_add_timecondition( +pub extern "C" fn Curl_add_timecondition( mut data: *mut Curl_easy, mut req: *mut dynbuf, ) -> CURLcode { + unsafe{ let mut tm: *const tm = 0 as *const tm; let mut keeptime: tm = tm { tm_sec: 0, @@ -2940,21 +2983,21 @@ pub extern "C" fn Curl_add_timecondition( let mut result: CURLcode = CURLE_OK; let mut datestr: [libc::c_char; 80] = [0; 80]; let mut condp: *const libc::c_char = 0 as *const libc::c_char; - if unsafe{(*data).set.timecondition as u32 == CURL_TIMECOND_NONE as u32} { + if (*data).set.timecondition as u32 == CURL_TIMECOND_NONE as i32 as u32 { /* no condition was asked for */ return CURLE_OK; } - result = unsafe{Curl_gmtime((*data).set.timevalue, &mut keeptime)}; + result = Curl_gmtime((*data).set.timevalue, &mut keeptime); if result as u64 != 0 { - unsafe{Curl_failf( + Curl_failf( data, b"Invalid TIMEVALUE\0" as *const u8 as *const libc::c_char, - );} + ); return result; } tm = &mut keeptime; - match unsafe{(*data).set.timecondition as u32} { + match (*data).set.timecondition as u32 { CURL_TIMECOND_IFMODSINCE => { condp = b"If-Modified-Since\0" as *const u8 as *const libc::c_char; } @@ -2966,7 +3009,7 @@ pub extern "C" fn Curl_add_timecondition( } _ => return CURLE_BAD_FUNCTION_ARGUMENT, } - if unsafe{!(Curl_checkheaders(data, condp)).is_null()} { + if !(Curl_checkheaders(data, condp)).is_null() { /* A custom header was specified; it will be sent instead. */ return CURLE_OK; } @@ -2979,7 +3022,7 @@ pub extern "C" fn Curl_add_timecondition( */ /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - unsafe{curl_msnprintf( + curl_msnprintf( datestr.as_mut_ptr(), ::std::mem::size_of::<[libc::c_char; 80]>() as u64, b"%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\0" as *const u8 as *const libc::c_char, @@ -2995,15 +3038,16 @@ pub extern "C" fn Curl_add_timecondition( (*tm).tm_hour, (*tm).tm_min, (*tm).tm_sec, - );} + ); - result = unsafe{Curl_hyper_header(data, req as *mut hyper_headers, datestr.as_mut_ptr())}; + result = Curl_hyper_header(data, req as *mut hyper_headers, datestr.as_mut_ptr()); return result; } +} #[cfg(all(not(CURL_DISABLE_PARSEDATE), not(USE_HYPER)))] #[no_mangle] -pub extern "C" fn Curl_add_timecondition( +pub extern "C" fn Curl_add_timecondition( mut data: *mut Curl_easy, mut req: *mut dynbuf, ) -> CURLcode { @@ -3024,19 +3068,20 @@ pub extern "C" fn Curl_add_timecondition( let mut result: CURLcode = CURLE_OK; let mut datestr: [libc::c_char; 80] = [0; 80]; let mut condp: *const libc::c_char = 0 as *const libc::c_char; - if unsafe{(*data).set.timecondition as u32 == CURL_TIMECOND_NONE as u32 }{ + unsafe{ + if (*data).set.timecondition as u32 == CURL_TIMECOND_NONE as i32 as u32 { return CURLE_OK; } - result =unsafe{ Curl_gmtime((*data).set.timevalue, &mut keeptime)}; + result = Curl_gmtime((*data).set.timevalue, &mut keeptime); if result as u64 != 0 { - unsafe{ Curl_failf( + Curl_failf( data, b"Invalid TIMEVALUE\0" as *const u8 as *const libc::c_char, - );} + ); return result; } tm = &mut keeptime; - match unsafe{(*data).set.timecondition as u32} { + match (*data).set.timecondition as u32 { CURL_TIMECOND_IFMODSINCE => { condp = b"If-Modified-Since\0" as *const u8 as *const libc::c_char; } @@ -3048,10 +3093,10 @@ pub extern "C" fn Curl_add_timecondition( } _ => return CURLE_BAD_FUNCTION_ARGUMENT, } - if unsafe{!(Curl_checkheaders(data, condp)).is_null()} { + if !(Curl_checkheaders(data, condp)).is_null() { return CURLE_OK; } - unsafe{ curl_msnprintf( + curl_msnprintf( datestr.as_mut_ptr(), ::std::mem::size_of::<[libc::c_char; 80]>() as u64, b"%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\0" as *const u8 as *const libc::c_char, @@ -3067,92 +3112,93 @@ pub extern "C" fn Curl_add_timecondition( (*tm).tm_hour, (*tm).tm_min, (*tm).tm_sec, - );} - result = unsafe{Curl_dyn_add(req, datestr.as_mut_ptr())}; + ); + result = Curl_dyn_add(req, datestr.as_mut_ptr()); return result; } +} /* disabled */ #[cfg(CURL_DISABLE_PARSEDATE)] -pub extern "C" fn Curl_add_timecondition( +pub extern "C" fn Curl_add_timecondition( mut data: *mut Curl_easy, mut req: *mut dynbuf, ) -> CURLcode { - return CURLE_OK; + unsafe{ + return CURLE_OK;} } const PROTO_FAMILY_HTTP: u32 = 1 << 0 | 1 << 1; const CURLPROTO_FTP: u32 = 1 << 2; #[no_mangle] -pub extern "C" fn Curl_http_method( +pub extern "C" fn Curl_http_method( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut method: *mut *const libc::c_char, mut reqp: *mut Curl_HttpReq, ) { - let mut httpreq: Curl_HttpReq = unsafe{(*data).state.httpreq}; + let mut httpreq: Curl_HttpReq =unsafe{ (*data).state.httpreq}; let mut request: *const libc::c_char = 0 as *const libc::c_char; - if unsafe{(*(*conn).handler).protocol - & (PROTO_FAMILY_HTTP | CURLPROTO_FTP) - != 0 - && ((*data).set).upload() as i32 != 0} + unsafe{ + if (*(*conn).handler).protocol & (PROTO_FAMILY_HTTP | CURLPROTO_FTP) != 0 + && ((*data).set).upload() as i32 != 0 { httpreq = HTTPREQ_PUT; } /* Now set the 'request' pointer to the proper request string */ - if unsafe{!((*data).set.str_0[STRING_CUSTOMREQUEST as usize]).is_null()} { - request = unsafe{(*data).set.str_0[STRING_CUSTOMREQUEST as usize]}; - } else if unsafe{((*data).set).opt_no_body() != 0} { + if !((*data).set.str_0[STRING_CUSTOMREQUEST as i32 as usize]).is_null() { + request = (*data).set.str_0[STRING_CUSTOMREQUEST as i32 as usize]; + } else if ((*data).set).opt_no_body() != 0 { request = b"HEAD\0" as *const u8 as *const libc::c_char; } else { #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if httpreq as u32 >= HTTPREQ_GET as u32 - && httpreq as u32 <= HTTPREQ_HEAD as u32 + if httpreq as u32 >= HTTPREQ_GET as i32 as u32 + && httpreq as u32 <= HTTPREQ_HEAD as i32 as u32 { - } else {unsafe{ + } else { __assert_fail( - b"(httpreq >= HTTPREQ_GET) && (httpreq <= HTTPREQ_HEAD)\0" as *const u8 - as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 2041 as u32, - (*::std::mem::transmute::< - &[u8; 95], - &[libc::c_char; 95], - >( - b"void Curl_http_method(struct Curl_easy *, struct connectdata *, const char **, Curl_HttpReq *)\0", - )) - .as_ptr(), - );} + b"(httpreq >= HTTPREQ_GET) && (httpreq <= HTTPREQ_HEAD)\0" as *const u8 + as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 2041 as i32 as u32, + (*::std::mem::transmute::< + &[u8; 95], + &[libc::c_char; 95], + >( + b"void Curl_http_method(struct Curl_easy *, struct connectdata *, const char **, Curl_HttpReq *)\0", + )) + .as_ptr(), + ); } match httpreq as u32 { - HTTPREQ_POST | HTTPREQ_POST_FORM | HTTPREQ_POST_MIME => { - request = b"POST\0" as *const u8 as *const libc::c_char; - } - HTTPREQ_PUT => { - request = b"PUT\0" as *const u8 as *const libc::c_char; - } - HTTPREQ_HEAD => { - request = b"HEAD\0" as *const u8 as *const libc::c_char; - } - HTTPREQ_GET | _ /* this should never happen */ => { - request = b"GET\0" as *const u8 as *const libc::c_char; - } - } - } - unsafe{*method = request; + HTTPREQ_POST | HTTPREQ_POST_FORM | HTTPREQ_POST_MIME => { + request = b"POST\0" as *const u8 as *const libc::c_char; + } + HTTPREQ_PUT => { + request = b"PUT\0" as *const u8 as *const libc::c_char; + } + HTTPREQ_HEAD => { + request = b"HEAD\0" as *const u8 as *const libc::c_char; + } + HTTPREQ_GET | _ /* this should never happen */ => { + request = b"GET\0" as *const u8 as *const libc::c_char; + } + } + } + *method = request; *reqp = httpreq;} } #[no_mangle] -pub extern "C" fn Curl_http_useragent(mut data: *mut Curl_easy) -> CURLcode { - /* The User-Agent string might have been allocated in url.c already, because - it might have been used in the proxy connect, but if we have got a header - with the user-agent string specified, we erase the previously made string - here. */ - if unsafe{!(Curl_checkheaders(data, b"User-Agent\0" as *const u8 as *const libc::c_char)).is_null()} { - unsafe{ +pub extern "C" fn Curl_http_useragent(mut data: *mut Curl_easy) -> CURLcode { + unsafe{ + /* The User-Agent string might have been allocated in url.c already, because + it might have been used in the proxy connect, but if we have got a header + with the user-agent string specified, we erase the previously made string + here. */ + if !(Curl_checkheaders(data, b"User-Agent\0" as *const u8 as *const libc::c_char)).is_null() { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( (*data).state.aptr.uagent as *mut libc::c_void, @@ -3163,20 +3209,21 @@ pub extern "C" fn Curl_http_useragent(mut data: *mut Curl_easy) -> CURLcode { 2072, b"http.c\0" as *const u8 as *const libc::c_char, ); - (*data).state.aptr.uagent = 0 as *mut libc::c_char;} + (*data).state.aptr.uagent = 0 as *mut libc::c_char; } return CURLE_OK; } +} #[no_mangle] -pub extern "C" fn Curl_http_host( +pub extern "C" fn Curl_http_host( mut data: *mut Curl_easy, mut conn: *mut connectdata, ) -> CURLcode { let mut ptr: *const libc::c_char = 0 as *const libc::c_char; - if unsafe{((*data).state).this_is_a_follow() == 0} { + unsafe{ + if ((*data).state).this_is_a_follow() == 0 { /* Free to avoid leaking memory on multiple requests*/ - unsafe{ #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( (*data).state.first_host as *mut libc::c_void, @@ -3186,28 +3233,27 @@ pub extern "C" fn Curl_http_host( (*data).state.first_host as *mut libc::c_void, 2084, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); match () { #[cfg(not(CURLDEBUG))] _ => { - unsafe{(*data).state.first_host = - Curl_cstrdup.expect("non-null function pointer")((*conn).host.name);} + (*data).state.first_host = + Curl_cstrdup.expect("non-null function pointer")((*conn).host.name); } #[cfg(CURLDEBUG)] _ => { - unsafe{ (*data).state.first_host = curl_dbg_strdup( + (*data).state.first_host = curl_dbg_strdup( (*conn).host.name, 2086 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); } } - if unsafe{((*data).state.first_host).is_null()} { + if ((*data).state.first_host).is_null() { return CURLE_OUT_OF_MEMORY; } - unsafe{ (*data).state.first_remote_port = (*conn).remote_port;} + (*data).state.first_remote_port = (*conn).remote_port; } - unsafe{ #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")((*data).state.aptr.host as *mut libc::c_void); #[cfg(CURLDEBUG)] @@ -3216,25 +3262,25 @@ pub extern "C" fn Curl_http_host( 2092 as i32, b"http.c\0" as *const u8 as *const libc::c_char, ); - (*data).state.aptr.host = 0 as *mut libc::c_char;} - ptr = unsafe{Curl_checkheaders(data, b"Host\0" as *const u8 as *const libc::c_char)}; - if unsafe{!ptr.is_null() + (*data).state.aptr.host = 0 as *mut libc::c_char; + ptr = Curl_checkheaders(data, b"Host\0" as *const u8 as *const libc::c_char); + if !ptr.is_null() && (((*data).state).this_is_a_follow() == 0 - || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0)} + || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0) { match () { #[cfg(not(CURL_DISABLE_COOKIES))] /* If we have a given custom Host: header, we extract the host name in - order to possibly use it for cookie reasons later on. We only allow the - custom Host: header if this is NOT a redirect, as setting Host: in the - redirected request is being out on thin ice. Except if the host name - is the same as the first one! */ + order to possibly use it for cookie reasons later on. We only allow the + custom Host: header if this is NOT a redirect, as setting Host: in the + redirected request is being out on thin ice. Except if the host name + is the same as the first one! */ _ => { let mut cookiehost: *mut libc::c_char = Curl_copy_header_value(ptr); if cookiehost.is_null() { return CURLE_OUT_OF_MEMORY; } - if unsafe{*cookiehost == 0 }{unsafe{ + if *cookiehost == 0 { /* ignore empty data */ #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(cookiehost as *mut libc::c_void); @@ -3243,31 +3289,31 @@ pub extern "C" fn Curl_http_host( cookiehost as *mut libc::c_void, 2108, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); } else { /* If the host begins with '[', we start searching for the port after - the bracket has been closed */ - if unsafe{*cookiehost as i32 == '[' as i32} { + the bracket has been closed */ + if *cookiehost as i32 == '[' as i32 { let mut closingbracket: *mut libc::c_char = 0 as *mut libc::c_char; /* since the 'cookiehost' is an allocated memory area that will be - freed later we cannot simply increment the pointer */ - unsafe{ memmove( + freed later we cannot simply increment the pointer */ + memmove( cookiehost as *mut libc::c_void, - cookiehost.offset(1 as isize) as *const libc::c_void, + cookiehost.offset(1 as i32 as isize) as *const libc::c_void, (strlen(cookiehost)).wrapping_sub(1 as u64), ); closingbracket = strchr(cookiehost, ']' as i32); if !closingbracket.is_null() { *closingbracket = 0 as libc::c_char; - }} + } } else { let mut startsearch: i32 = 0; let mut colon: *mut libc::c_char = - unsafe{strchr(cookiehost.offset(startsearch as isize), ':' as i32)}; + strchr(cookiehost.offset(startsearch as isize), ':' as i32); if !colon.is_null() { - unsafe{ *colon = 0 as libc::c_char; }/* The host must not include an embedded port number */ + *colon = 0 as i32 as libc::c_char; /* The host must not include an embedded port number */ } - }unsafe{ + } #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( (*data).state.aptr.cookiehost as *mut libc::c_void, @@ -3279,36 +3325,34 @@ pub extern "C" fn Curl_http_host( b"http.c\0" as *const u8 as *const libc::c_char, ); (*data).state.aptr.cookiehost = 0 as *mut libc::c_char; - (*data).state.aptr.cookiehost = cookiehost;} + (*data).state.aptr.cookiehost = cookiehost; } } #[cfg(CURL_DISABLE_COOKIES)] _ => {} } - if unsafe{strcmp(b"Host:\0" as *const u8 as *const libc::c_char, ptr) != 0 }{ - unsafe{ (*data).state.aptr.host = curl_maprintf( + if strcmp(b"Host:\0" as *const u8 as *const libc::c_char, ptr) != 0 { + (*data).state.aptr.host = curl_maprintf( b"Host:%s\r\n\0" as *const u8 as *const libc::c_char, - &*ptr.offset(5 as isize) as *const libc::c_char, + &*ptr.offset(5 as i32 as isize) as *const libc::c_char, ); if ((*data).state.aptr.host).is_null() { return CURLE_OUT_OF_MEMORY; - }} + } } else { /* when clearing the header */ - unsafe{(*data).state.aptr.host = 0 as *mut libc::c_char;} + (*data).state.aptr.host = 0 as *mut libc::c_char; } } else { /* When building Host: headers, we must put the host name within - [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ - let mut host: *const libc::c_char = unsafe{(*conn).host.name}; - if unsafe{(*(*conn).given).protocol & CURLPROTO_HTTPS != 0 - && (*conn).remote_port == PORT_HTTPS - || (*(*conn).given).protocol & CURLPROTO_HTTP != 0 - && (*conn).remote_port == PORT_HTTP} + [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ + let mut host: *const libc::c_char = (*conn).host.name; + if (*(*conn).given).protocol & CURLPROTO_HTTPS != 0 && (*conn).remote_port == PORT_HTTPS + || (*(*conn).given).protocol & CURLPROTO_HTTP != 0 && (*conn).remote_port == PORT_HTTP { /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include - the port number in the host string */ - unsafe{(*data).state.aptr.host = curl_maprintf( + the port number in the host string */ + (*data).state.aptr.host = curl_maprintf( b"Host: %s%s%s\r\n\0" as *const u8 as *const libc::c_char, if ((*conn).bits).ipv6_ip() as i32 != 0 { b"[\0" as *const u8 as *const libc::c_char @@ -3321,9 +3365,9 @@ pub extern "C" fn Curl_http_host( } else { b"\0" as *const u8 as *const libc::c_char }, - );} + ); } else { - unsafe{(*data).state.aptr.host = curl_maprintf( + (*data).state.aptr.host = curl_maprintf( b"Host: %s%s%s:%d\r\n\0" as *const u8 as *const libc::c_char, if ((*conn).bits).ipv6_ip() as i32 != 0 { b"[\0" as *const u8 as *const libc::c_char @@ -3337,13 +3381,14 @@ pub extern "C" fn Curl_http_host( b"\0" as *const u8 as *const libc::c_char }, (*conn).remote_port, - );} + ); } /* without Host: we can't make a nice request */ - if unsafe{((*data).state.aptr.host).is_null()} { + if ((*data).state.aptr.host).is_null() { return CURLE_OUT_OF_MEMORY; } } +} return CURLE_OK; } @@ -3351,95 +3396,85 @@ pub extern "C" fn Curl_http_host( * Append the request-target to the HTTP request */ #[no_mangle] -pub extern "C" fn Curl_http_target( +pub extern "C" fn Curl_http_target( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut r: *mut dynbuf, ) -> CURLcode { let mut result: CURLcode = CURLE_OK; - let mut path: *const libc::c_char = unsafe{(*data).state.up.path}; - let mut query: *const libc::c_char = unsafe{ (*data).state.up.query}; - - if unsafe{!((*data).set.str_0[STRING_TARGET as usize]).is_null()} { - path = unsafe{(*data).set.str_0[STRING_TARGET as usize]}; + let mut path: *const libc::c_char =unsafe{ (*data).state.up.path}; + let mut query: *const libc::c_char =unsafe{ (*data).state.up.query}; + unsafe{ + if !((*data).set.str_0[STRING_TARGET as i32 as usize]).is_null() { + path = (*data).set.str_0[STRING_TARGET as i32 as usize]; query = 0 as *const libc::c_char; } match () { #[cfg(not(CURL_DISABLE_PROXY))] _ => { - if unsafe{((*conn).bits).httpproxy() as i32 != 0 && ((*conn).bits).tunnel_proxy() == 0} { + if ((*conn).bits).httpproxy() as i32 != 0 && ((*conn).bits).tunnel_proxy() == 0 { /* Using a proxy but does not tunnel through it */ - /* The path sent to the proxy is in fact the entire URL. But if the remote - host is a IDN-name, we must make sure that the request we produce only - uses the encoded host name! */ + /* The path sent to the proxy is in fact the entire URL. But if the remote + host is a IDN-name, we must make sure that the request we produce only + uses the encoded host name! */ - /* and no fragment part */ + /* and no fragment part */ let mut uc: CURLUcode = CURLUE_OK; let mut url: *mut libc::c_char = 0 as *mut libc::c_char; - let mut h: *mut CURLU = unsafe{curl_url_dup((*data).state.uh)}; + let mut h: *mut CURLU = curl_url_dup((*data).state.uh); if h.is_null() { return CURLE_OUT_OF_MEMORY; } - if unsafe{(*conn).host.dispname != (*conn).host.name as *const libc::c_char} { - uc = unsafe{curl_url_set(h, CURLUPART_HOST, (*conn).host.name, 0 as u32)}; + if (*conn).host.dispname != (*conn).host.name as *const libc::c_char { + uc = curl_url_set(h, CURLUPART_HOST, (*conn).host.name, 0 as i32 as u32); if uc as u64 != 0 { - unsafe{ curl_url_cleanup(h);} + curl_url_cleanup(h); return CURLE_OUT_OF_MEMORY; } } - uc = unsafe{curl_url_set( - h, - CURLUPART_FRAGMENT, - 0 as *const libc::c_char, - 0 as u32, - )}; + uc = curl_url_set(h, CURLUPART_FRAGMENT, 0 as *const libc::c_char, 0 as u32); if uc as u64 != 0 { - unsafe{ curl_url_cleanup(h);} + curl_url_cleanup(h); return CURLE_OUT_OF_MEMORY; } - if unsafe{Curl_strcasecompare( + if Curl_strcasecompare( b"http\0" as *const u8 as *const libc::c_char, (*data).state.up.scheme, - ) != 0} + ) != 0 { /* when getting HTTP, we don't want the userinfo the URL */ - uc = unsafe{curl_url_set(h, CURLUPART_USER, 0 as *const libc::c_char, 0 as u32)}; + uc = curl_url_set(h, CURLUPART_USER, 0 as *const libc::c_char, 0 as i32 as u32); if uc as u64 != 0 { - unsafe{curl_url_cleanup(h);} + curl_url_cleanup(h); return CURLE_OUT_OF_MEMORY; } - uc = unsafe{curl_url_set( - h, - CURLUPART_PASSWORD, - 0 as *const libc::c_char, - 0 as u32, - )}; + uc = curl_url_set(h, CURLUPART_PASSWORD, 0 as *const libc::c_char, 0 as u32); if uc as u64 != 0 { - unsafe{curl_url_cleanup(h);} + curl_url_cleanup(h); return CURLE_OUT_OF_MEMORY; } } /* Extract the URL to use in the request. Store in STRING_TEMP_URL for - clean-up reasons if the function returns before the free() further - down. */ - uc = unsafe{curl_url_get(h, CURLUPART_URL, &mut url, ((1 as i32) << 1 as i32) as u32)}; + clean-up reasons if the function returns before the free() further + down. */ + uc = curl_url_get(h, CURLUPART_URL, &mut url, ((1 as i32) << 1 as i32) as u32); if uc as u64 != 0 { - unsafe{ curl_url_cleanup(h);} + curl_url_cleanup(h); return CURLE_OUT_OF_MEMORY; } - unsafe{ curl_url_cleanup(h);} - result = unsafe{Curl_dyn_add( + curl_url_cleanup(h); + result = Curl_dyn_add( r, - if !((*data).set.str_0[STRING_TARGET as usize]).is_null() { - (*data).set.str_0[STRING_TARGET as usize] + if !((*data).set.str_0[STRING_TARGET as i32 as usize]).is_null() { + (*data).set.str_0[STRING_TARGET as i32 as usize] } else { url }, - )}; - unsafe{ + ); + #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(url as *mut libc::c_void); #[cfg(CURLDEBUG)] @@ -3448,25 +3483,25 @@ pub extern "C" fn Curl_http_target( 2241, b"http.c\0" as *const u8 as *const libc::c_char, ); - } + /* target or url */ if result as u64 != 0 { return result; } - if unsafe{Curl_strcasecompare( + if Curl_strcasecompare( b"ftp\0" as *const u8 as *const libc::c_char, (*data).state.up.scheme, - ) != 0} + ) != 0 { - if unsafe{((*data).set).proxy_transfer_mode() != 0} { + if ((*data).set).proxy_transfer_mode() != 0 { /* when doing ftp, append ;type= if not present */ let mut type_0: *mut libc::c_char = - unsafe{ strstr(path, b";type=\0" as *const u8 as *const libc::c_char)}; - if unsafe{!type_0.is_null() + strstr(path, b";type=\0" as *const u8 as *const libc::c_char); + if !type_0.is_null() && *type_0.offset(6 as isize) as i32 != 0 - && *type_0.offset(7 as isize) as i32 == 0} + && *type_0.offset(7 as isize) as i32 == 0 { - match unsafe{Curl_raw_toupper(*type_0.offset(6 as isize)) as i32} { + match Curl_raw_toupper(*type_0.offset(6 as isize)) as i32 { 65 | 68 | 73 => {} _ => { type_0 = 0 as *mut libc::c_char; @@ -3474,7 +3509,7 @@ pub extern "C" fn Curl_http_target( } } if type_0.is_null() { - result = unsafe{Curl_dyn_addf( + result = Curl_dyn_addf( r, b";type=%c\0" as *const u8 as *const libc::c_char, if ((*data).state).prefer_ascii() as i32 != 0 { @@ -3482,7 +3517,7 @@ pub extern "C" fn Curl_http_target( } else { 'i' as i32 }, - )}; + ); if result as u64 != 0 { return result; } @@ -3490,31 +3525,32 @@ pub extern "C" fn Curl_http_target( } } } else { - result = unsafe{Curl_dyn_add(r, path)}; + result = Curl_dyn_add(r, path); if result as u64 != 0 { return result; } if !query.is_null() { - result = unsafe{Curl_dyn_addf(r, b"?%s\0" as *const u8 as *const libc::c_char, query)}; + result = Curl_dyn_addf(r, b"?%s\0" as *const u8 as *const libc::c_char, query); } } } #[cfg(CURL_DISABLE_PROXY)] _ => { - result = unsafe{Curl_dyn_add(r, path)}; + result = Curl_dyn_add(r, path); if result as u64 != 0 { return result; } if !query.is_null() { - result = unsafe{Curl_dyn_addf(r, b"?%s\0" as *const u8 as *const libc::c_char, query)}; + result = Curl_dyn_addf(r, b"?%s\0" as *const u8 as *const libc::c_char, query); } } } +} return result; } #[no_mangle] -pub extern "C" fn Curl_http_body( +pub extern "C" fn Curl_http_body( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut httpreq: Curl_HttpReq, @@ -3522,15 +3558,14 @@ pub extern "C" fn Curl_http_body( ) -> CURLcode { let mut result: CURLcode = CURLE_OK; let mut ptr: *const libc::c_char = 0 as *const libc::c_char; - let mut http: *mut HTTP = unsafe{(*data).req.p.http}; + let mut http: *mut HTTP =unsafe{ (*data).req.p.http}; unsafe{(*http).postsize = 0 as curl_off_t;} - + unsafe{ match httpreq as u32 { HTTPREQ_POST_MIME => { - unsafe{(*http).sendit = &mut (*data).set.mimepost;} + (*http).sendit = &mut (*data).set.mimepost; } HTTPREQ_POST_FORM => { - unsafe{ /* Convert the form structure into a mime structure. */ #[cfg(any( all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), @@ -3563,30 +3598,31 @@ pub extern "C" fn Curl_http_body( if result as u64 != 0 { return result; } - (*http).sendit = &mut (*http).form;} + (*http).sendit = &mut (*http).form; } _ => { - unsafe{(*http).sendit = 0 as *mut curl_mimepart;} + (*http).sendit = 0 as *mut curl_mimepart; } } + #[cfg(not(CURL_DISABLE_MIME))] - if !(unsafe{(*http).sendit}).is_null(){ + if !((*http).sendit).is_null() { let mut cthdr: *const libc::c_char = - unsafe{Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char)}; - + Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char); + /* Read and seek body only. */ - unsafe{(*(*http).sendit).flags |= MIME_BODY_ONLY;} + (*(*http).sendit).flags |= MIME_BODY_ONLY; /* Prepare the mime structure headers & set content type. */ if !cthdr.is_null() { - cthdr = unsafe{cthdr.offset(13 as isize)}; - while unsafe{*cthdr as i32 == ' ' as i32} { - cthdr = unsafe{cthdr.offset(1)}; + cthdr = cthdr.offset(13 as i32 as isize); + while *cthdr as i32 == ' ' as i32 { + cthdr = cthdr.offset(1); } - } else if unsafe{(*(*http).sendit).kind as u32 == MIMEKIND_MULTIPART as u32} { + } else if (*(*http).sendit).kind as u32 == MIMEKIND_MULTIPART as i32 as u32 { cthdr = b"multipart/form-data\0" as *const u8 as *const libc::c_char; } - unsafe{ curl_mime_headers((*http).sendit, (*data).set.headers, 0 as i32);} + curl_mime_headers((*http).sendit, (*data).set.headers, 0 as i32); // 好像这里其实可以不要条件编译 match () { #[cfg(any( @@ -3595,12 +3631,12 @@ pub extern "C" fn Curl_http_body( not(CURL_DISABLE_IMAP) ))] _ => { - result = unsafe{Curl_mime_prepare_headers( + result = Curl_mime_prepare_headers( (*http).sendit, cthdr, 0 as *const libc::c_char, MIMESTRATEGY_FORM, - )}; + ); } _ => { result = CURLE_NOT_BUILT_IN; @@ -3612,36 +3648,36 @@ pub extern "C" fn Curl_http_body( // 0 as *const libc::c_char, // MIMESTRATEGY_FORM, // ); - unsafe{ curl_mime_headers((*http).sendit, 0 as *mut curl_slist, 0 as i32);} + curl_mime_headers((*http).sendit, 0 as *mut curl_slist, 0 as i32); if result as u64 == 0 { - result =unsafe{ Curl_mime_rewind((*http).sendit)}; + result = Curl_mime_rewind((*http).sendit); } if result as u64 != 0 { return result; } - unsafe{(*http).postsize = Curl_mime_size((*http).sendit);} + (*http).postsize = Curl_mime_size((*http).sendit); } - ptr = unsafe{Curl_checkheaders( + ptr = Curl_checkheaders( data, b"Transfer-Encoding\0" as *const u8 as *const libc::c_char, - )}; + ); if !ptr.is_null() { /* Some kind of TE is requested, check if 'chunked' is chosen */ - unsafe{ (*data).req.set_upload_chunky(Curl_compareheader( + (*data).req.set_upload_chunky(Curl_compareheader( ptr, b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, b"chunked\0" as *const u8 as *const libc::c_char, - ) as bit);} + ) as bit); } else { - if unsafe{(*(*conn).handler).protocol & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32) as u32 + if (*(*conn).handler).protocol & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32) as u32 != 0 - && ((httpreq as u32 == HTTPREQ_POST_MIME as u32 - || httpreq as u32 == HTTPREQ_POST_FORM as u32) + && ((httpreq as u32 == HTTPREQ_POST_MIME as i32 as u32 + || httpreq as u32 == HTTPREQ_POST_FORM as i32 as u32) && (*http).postsize < 0 as i32 as i64 || (((*data).set).upload() as i32 != 0 - || httpreq as u32 == HTTPREQ_POST as u32) - && (*data).state.infilesize == -(1 as i32) as i64)} - {unsafe{ + || httpreq as u32 == HTTPREQ_POST as i32 as u32) + && (*data).state.infilesize == -(1 as i32) as i64) + { if !(((*conn).bits).authneg() != 0) { if Curl_use_http_1_1plus(data, conn) { if ((*conn).httpversion as i32) < 20 { @@ -3655,19 +3691,20 @@ pub extern "C" fn Curl_http_body( ); return CURLE_UPLOAD_FAILED; } - }} + } } else { - unsafe{ (*data).req.set_upload_chunky(0 as bit);} + (*data).req.set_upload_chunky(0 as i32 as bit); } - if unsafe{ ((*data).req).upload_chunky() != 0 }{ - unsafe{*tep = b"Transfer-Encoding: chunked\r\n\0" as *const u8 as *const libc::c_char;} + if ((*data).req).upload_chunky() != 0 { + *tep = b"Transfer-Encoding: chunked\r\n\0" as *const u8 as *const libc::c_char; } } return result; } +} #[no_mangle] -pub extern "C" fn Curl_http_bodysend( +pub extern "C" fn Curl_http_bodysend( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut r: *mut dynbuf, @@ -3675,81 +3712,72 @@ pub extern "C" fn Curl_http_bodysend( ) -> CURLcode { /* Hyper always handles the body separately */ #[cfg(not(USE_HYPER))] - let mut included_body: curl_off_t = 0 as curl_off_t; + let mut included_body: curl_off_t = 0 as i32 as curl_off_t; let mut result: CURLcode = CURLE_OK; - let mut http: *mut HTTP = unsafe{(*data).req.p.http}; + let mut http: *mut HTTP =unsafe{ (*data).req.p.http}; let mut ptr: *const libc::c_char = 0 as *const libc::c_char; - + /* If 'authdone' is FALSE, we must not set the write socket index to the - Curl_transfer() call below, as we're not ready to actually upload any - data yet. */ - + Curl_transfer() call below, as we're not ready to actually upload any + data yet. */ + unsafe{ match httpreq as u32 { - HTTPREQ_PUT => { /* Let's PUT the data to the server! */ - if unsafe{((*conn).bits).authneg() != 0 }{ - unsafe{ (*http).postsize = 0 as curl_off_t;} + HTTPREQ_PUT => { + /* Let's PUT the data to the server! */ + if ((*conn).bits).authneg() != 0 { + (*http).postsize = 0 as curl_off_t; } else { - unsafe{ (*http).postsize = (*data).state.infilesize;} + (*http).postsize = (*data).state.infilesize; } - if unsafe{(*http).postsize != -1 as i64 + if (*http).postsize != -1 as i64 && ((*data).req).upload_chunky() == 0 && (((*conn).bits).authneg() as i32 != 0 || (Curl_checkheaders( data, b"Content-Length\0" as *const u8 as *const libc::c_char, )) - .is_null())} + .is_null()) { /* only add Content-Length if not uploading chunked */ - result = unsafe{Curl_dyn_addf( + result = Curl_dyn_addf( r, b"Content-Length: %ld\r\n\0" as *const u8 as *const libc::c_char, (*http).postsize, - )}; + ); if result as u64 != 0 { return result; } } - if unsafe{(*http).postsize != 0 }{ - result = unsafe{expect100(data, conn, r)}; + if (*http).postsize != 0 { + result = expect100(data, conn, r); if result as u64 != 0 { return result; } } - result = unsafe{Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char)}; + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); if result as u64 != 0 { return result; } /* set the upload size to the progress meter */ - unsafe{Curl_pgrsSetUploadSize(data, (*http).postsize);} + Curl_pgrsSetUploadSize(data, (*http).postsize); /* this sends the buffer and frees all the buffer resources */ - result = unsafe{Curl_buffer_send( - r, - data, - &mut (*data).info.request_size, - 0 as curl_off_t, - 0, - )}; + result = Curl_buffer_send(r, data, &mut (*data).info.request_size, 0 as curl_off_t, 0); /* this sends the buffer and frees all the buffer resources */ if result as u64 != 0 { - unsafe{ Curl_failf( + Curl_failf( data, b"Failed sending PUT request\0" as *const u8 as *const libc::c_char, - )}; + ); } else { /* prepare for transfer */ - unsafe{ Curl_setup_transfer( + Curl_setup_transfer( data, 0, -1 as curl_off_t, true, - if (*http).postsize != 0 { - 0 - } else { - -1 - }, - );} + if (*http).postsize != 0 { 0 } else { -1 }, + ); } if result as u64 != 0 { return result; @@ -3757,60 +3785,49 @@ pub extern "C" fn Curl_http_bodysend( } HTTPREQ_POST_FORM | HTTPREQ_POST_MIME => { /* This is form posting using mime data. */ - if unsafe{((*conn).bits).authneg() != 0 }{ + if ((*conn).bits).authneg() != 0 { /* nothing to post! */ - result = unsafe{Curl_dyn_add( + result = Curl_dyn_add( r, b"Content-Length: 0\r\n\r\n\0" as *const u8 as *const libc::c_char, - )}; + ); if result as u64 != 0 { return result; } - result = unsafe{Curl_buffer_send( - r, - data, - &mut (*data).info.request_size, - 0 as curl_off_t, - 0, - )}; + result = + Curl_buffer_send(r, data, &mut (*data).info.request_size, 0 as curl_off_t, 0); if result as u64 != 0 { - unsafe{Curl_failf( + Curl_failf( data, b"Failed sending POST request\0" as *const u8 as *const libc::c_char, - );} + ); } else { - unsafe{Curl_setup_transfer( - data, - 0, - -1 as curl_off_t, - true, - -1, - );} + Curl_setup_transfer(data, 0, -1 as curl_off_t, true, -1); } } else { - unsafe{ (*data).state.infilesize = (*http).postsize;} - + (*data).state.infilesize = (*http).postsize; + /* We only set Content-Length and allow a custom Content-Length if - we don't upload data chunked, as RFC2616 forbids us to set both - kinds of headers (Transfer-Encoding: chunked and Content-Length) */ - if unsafe{(*http).postsize != -1 as i64 + we don't upload data chunked, as RFC2616 forbids us to set both + kinds of headers (Transfer-Encoding: chunked and Content-Length) */ + if (*http).postsize != -1 as i64 && ((*data).req).upload_chunky() == 0 && (((*conn).bits).authneg() as i32 != 0 || (Curl_checkheaders( data, b"Content-Length\0" as *const u8 as *const libc::c_char, )) - .is_null())} + .is_null()) { /* we allow replacing this header if not during auth negotiation, - although it isn't very wise to actually set your own */ - result = unsafe{Curl_dyn_addf( + although it isn't very wise to actually set your own */ + result = Curl_dyn_addf( r, b"Content-Length: %ld\r\n\0" as *const u8 as *const libc::c_char, (*http).postsize, - )}; + ); if result as u64 != 0 { return result; } @@ -3818,17 +3835,17 @@ pub extern "C" fn Curl_http_bodysend( // TODO 测试过了就把注释删咯 if cfg!(not(CURL_DISABLE_MIME)) { let mut hdr: *mut curl_slist = 0 as *mut curl_slist; - hdr =unsafe{ (*(*http).sendit).curlheaders}; + hdr = (*(*http).sendit).curlheaders; while !hdr.is_null() { - result = unsafe{Curl_dyn_addf( + result = Curl_dyn_addf( r, b"%s\r\n\0" as *const u8 as *const libc::c_char, (*hdr).data, - )}; + ); if result as u64 != 0 { return result; } - hdr = unsafe{(*hdr).next}; + hdr = (*hdr).next; } } // #[cfg(not(CURL_DISABLE_MIME))] @@ -3848,37 +3865,34 @@ pub extern "C" fn Curl_http_bodysend( // hdr = (*hdr).next; // } /* For really small posts we don't use Expect: headers at all, and for - the somewhat bigger ones we allow the app to disable it. Just make - sure that the expect100header is always set to the preferred value - here. */ + the somewhat bigger ones we allow the app to disable it. Just make + sure that the expect100header is always set to the preferred value + here. */ - ptr = unsafe{Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char)}; + ptr = Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char); if !ptr.is_null() { - unsafe{ (*data).state.set_expect100header(Curl_compareheader( + (*data).state.set_expect100header(Curl_compareheader( ptr, b"Expect:\0" as *const u8 as *const libc::c_char, b"100-continue\0" as *const u8 as *const libc::c_char, - ) as bit);} - - } else if unsafe{(*http).postsize > EXPECT_100_THRESHOLD - || (*http).postsize < 0 as i64} - { + ) as bit); + } else if (*http).postsize > EXPECT_100_THRESHOLD || (*http).postsize < 0 as i64 { /* make the request end in a true CRLF */ - result = unsafe{expect100(data, conn, r)}; + result = expect100(data, conn, r); if result as u64 != 0 { return result; } } else { - unsafe{(*data).state.set_expect100header(0 as bit);} + (*data).state.set_expect100header(0 as bit); } - result = unsafe{Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char)}; + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); if result as u64 != 0 { return result; } /* set the upload size to the progress meter */ - unsafe{ Curl_pgrsSetUploadSize(data, (*http).postsize);} - let ref mut fresh51 = unsafe{(*data).state.fread_func}; + Curl_pgrsSetUploadSize(data, (*http).postsize); + let ref mut fresh51 = (*data).state.fread_func; // TODO 这里也有条件编译 match () { #[cfg(any( @@ -3887,7 +3901,7 @@ pub extern "C" fn Curl_http_bodysend( not(CURL_DISABLE_IMAP) ))] _ => { - *fresh51 = unsafe{::std::mem::transmute::< + *fresh51 = ::std::mem::transmute::< Option< unsafe extern "C" fn( *mut libc::c_char, @@ -3905,7 +3919,7 @@ pub extern "C" fn Curl_http_bodysend( size_t, *mut libc::c_void, ) -> size_t, - ))}; + )); } _ => { // TODO @@ -3932,26 +3946,21 @@ pub extern "C" fn Curl_http_bodysend( // )); /* Read from mime structure. */ - unsafe{(*data).state.in_0 = (*http).sendit as *mut libc::c_void; - (*http).sending = HTTPSEND_BODY;} - + (*data).state.in_0 = (*http).sendit as *mut libc::c_void; + (*http).sending = HTTPSEND_BODY; + /* this sends the buffer and frees all the buffer resources */ - result =unsafe{ Curl_buffer_send( - r, - data, - &mut (*data).info.request_size, - 0 as curl_off_t, - 0, - )}; + result = + Curl_buffer_send(r, data, &mut (*data).info.request_size, 0 as curl_off_t, 0); if result as u64 != 0 { - unsafe{ Curl_failf( + Curl_failf( data, b"Failed sending POST request\0" as *const u8 as *const libc::c_char, - )}; + ); } else { /* prepare for transfer */ - unsafe{ Curl_setup_transfer( + Curl_setup_transfer( data, FIRSTSOCKET, -1 as curl_off_t, @@ -3961,7 +3970,7 @@ pub extern "C" fn Curl_http_bodysend( } else { -1 }, - );} + ); } if result as u64 != 0 { return result; @@ -3971,122 +3980,120 @@ pub extern "C" fn Curl_http_bodysend( HTTPREQ_POST => { /* this is the simple POST, using x-www-form-urlencoded style */ - if unsafe{((*conn).bits).authneg() != 0} { - unsafe{(*http).postsize = 0 as curl_off_t;} + if ((*conn).bits).authneg() != 0 { + (*http).postsize = 0 as curl_off_t; } else { /* the size of the post body */ - unsafe{(*http).postsize = (*data).state.infilesize;} + (*http).postsize = (*data).state.infilesize; } /* We only set Content-Length and allow a custom Content-Length if - we don't upload data chunked, as RFC2616 forbids us to set both - kinds of headers (Transfer-Encoding: chunked and Content-Length) */ - if unsafe{(*http).postsize != -1 as i64 + we don't upload data chunked, as RFC2616 forbids us to set both + kinds of headers (Transfer-Encoding: chunked and Content-Length) */ + if (*http).postsize != -1 as i64 && ((*data).req).upload_chunky() == 0 && (((*conn).bits).authneg() as i32 != 0 || (Curl_checkheaders( data, b"Content-Length\0" as *const u8 as *const libc::c_char, )) - .is_null())} + .is_null()) { /* we allow replacing this header if not during auth negotiation, - although it isn't very wise to actually set your own */ - result = unsafe{Curl_dyn_addf( + although it isn't very wise to actually set your own */ + result = Curl_dyn_addf( r, b"Content-Length: %ld\r\n\0" as *const u8 as *const libc::c_char, (*http).postsize, - )}; + ); if result as u64 != 0 { return result; } } - if unsafe{(Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char)) - .is_null()} + if (Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char)) + .is_null() { - result =unsafe{ Curl_dyn_add( + result = Curl_dyn_add( r, b"Content-Type: application/x-www-form-urlencoded\r\n\0" as *const u8 as *const libc::c_char, - )}; + ); if result as u64 != 0 { return result; } } /* For really small posts we don't use Expect: headers at all, and for - the somewhat bigger ones we allow the app to disable it. Just make - sure that the expect100header is always set to the preferred value - here. */ - ptr =unsafe{ Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char)}; - if !ptr.is_null() {unsafe{ + the somewhat bigger ones we allow the app to disable it. Just make + sure that the expect100header is always set to the preferred value + here. */ + ptr = Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char); + if !ptr.is_null() { (*data).state.set_expect100header(Curl_compareheader( ptr, b"Expect:\0" as *const u8 as *const libc::c_char, b"100-continue\0" as *const u8 as *const libc::c_char, - ) as bit);} - } else if unsafe{(*http).postsize > EXPECT_100_THRESHOLD - || (*http).postsize < 0 as i64} - { - result = unsafe{expect100(data, conn, r)}; + ) as bit); + } else if (*http).postsize > EXPECT_100_THRESHOLD || (*http).postsize < 0 as i64 { + result = expect100(data, conn, r); if result as u64 != 0 { return result; } } else { - unsafe{(*data).state.set_expect100header(0 as bit);} + (*data).state.set_expect100header(0 as bit); } // TODO 测试通过了就把match删咯 let flag: bool = if cfg!(not(USE_HYPER)) { - unsafe{!((*data).set.postfields).is_null()} + !((*data).set.postfields).is_null() } else { false }; if flag { - if unsafe{(*conn).httpversion as i32 != 20 + if (*conn).httpversion as i32 != 20 && ((*data).state).expect100header() == 0 - && (*http).postsize < (64 * 1024) as i64} + && (*http).postsize < (64 * 1024) as i64 { /* make the request end in a true CRLF */ - result = unsafe{Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char)}; + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); if result as u64 != 0 { return result; } - if unsafe{((*data).req).upload_chunky() == 0 }{ + if ((*data).req).upload_chunky() == 0 { result = - unsafe{Curl_dyn_addn(r, (*data).set.postfields, (*http).postsize as size_t)}; - included_body = unsafe{(*http).postsize}; + Curl_dyn_addn(r, (*data).set.postfields, (*http).postsize as size_t); + included_body = (*http).postsize; } else { - if unsafe{(*http).postsize != 0} { + if (*http).postsize != 0 { let mut chunk: [libc::c_char; 16] = [0; 16]; - unsafe{curl_msnprintf( + curl_msnprintf( chunk.as_mut_ptr(), ::std::mem::size_of::<[libc::c_char; 16]>() as u64, b"%x\r\n\0" as *const u8 as *const libc::c_char, (*http).postsize as i32, - );} - result = unsafe{Curl_dyn_add(r, chunk.as_mut_ptr())}; + ); + result = Curl_dyn_add(r, chunk.as_mut_ptr()); if result as u64 == 0 { - included_body = unsafe{((*http).postsize as u64) + included_body = ((*http).postsize as u64) .wrapping_add(strlen(chunk.as_mut_ptr())) - as curl_off_t}; - result =unsafe{Curl_dyn_addn( + as curl_off_t; + result = Curl_dyn_addn( r, (*data).set.postfields, (*http).postsize as size_t, - )}; + ); if result as u64 == 0 { - result = unsafe{Curl_dyn_add( + result = Curl_dyn_add( r, b"\r\n\0" as *const u8 as *const libc::c_char, - )}; + ); } - included_body += 2 as i64; + included_body += 2 as i32 as i64; } } if result as u64 == 0 { result = - unsafe{Curl_dyn_add(r, b"0\r\n\r\n\0" as *const u8 as *const libc::c_char)}; - included_body += 5 as i64; + Curl_dyn_add(r, b"0\r\n\r\n\0" as *const u8 as *const libc::c_char); + included_body += 5 as i32 as i64; } } if result as u64 != 0 { @@ -4094,9 +4101,9 @@ pub extern "C" fn Curl_http_bodysend( } /* set the upload size to the progress meter */ - unsafe{ Curl_pgrsSetUploadSize(data, (*http).postsize);} + Curl_pgrsSetUploadSize(data, (*http).postsize); } else { - unsafe{ (*http).postdata = (*data).set.postfields as *const libc::c_char; + (*http).postdata = (*data).set.postfields as *const libc::c_char; (*http).sending = HTTPSEND_BODY; (*data).state.fread_func = ::std::mem::transmute::< Option< @@ -4118,39 +4125,39 @@ pub extern "C" fn Curl_http_bodysend( ) -> size_t, )); (*data).state.in_0 = data as *mut libc::c_void; - Curl_pgrsSetUploadSize(data, (*http).postsize);} - result = unsafe{Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char)}; + Curl_pgrsSetUploadSize(data, (*http).postsize); + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); if result as u64 != 0 { return result; } } } else { /* make the request end in a true CRLF */ - result =unsafe{ Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char)}; + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); if result as u64 != 0 { return result; } - if unsafe{((*data).req).upload_chunky() as i32 != 0 && ((*conn).bits).authneg() as i32 != 0} + if ((*data).req).upload_chunky() as i32 != 0 && ((*conn).bits).authneg() as i32 != 0 { - result = unsafe{Curl_dyn_add( + result = Curl_dyn_add( r, b"0\r\n\r\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, - )}; + ); if result as u64 != 0 { return result; } - } else if unsafe{(*data).state.infilesize != 0 }{ - unsafe{ Curl_pgrsSetUploadSize( + } else if (*data).state.infilesize != 0 { + Curl_pgrsSetUploadSize( data, if (*http).postsize != 0 { (*http).postsize } else { - -1 as i64 + -1 as i64 }, - );} - if unsafe{((*conn).bits).authneg() == 0} { - unsafe{ (*http).postdata = - &mut (*http).postdata as *mut *const libc::c_char as *mut libc::c_char;} + ); + if ((*conn).bits).authneg() == 0 { + (*http).postdata = + &mut (*http).postdata as *mut *const libc::c_char as *mut libc::c_char; } } } @@ -4307,113 +4314,95 @@ pub extern "C" fn Curl_http_bodysend( // } /* this sends the buffer and frees all the buffer resources */ - result = unsafe{Curl_buffer_send( - r, - data, - &mut (*data).info.request_size, - included_body, - 0, - )}; + result = Curl_buffer_send(r, data, &mut (*data).info.request_size, included_body, 0); if result as u64 != 0 { - unsafe{ Curl_failf( + Curl_failf( data, b"Failed sending HTTP POST request\0" as *const u8 as *const libc::c_char, - );} + ); } else { - unsafe{Curl_setup_transfer( + Curl_setup_transfer( data, 0, -1 as curl_off_t, true, - if !((*http).postdata).is_null() { - 0 - } else { - -1 - }, - );} + if !((*http).postdata).is_null() { 0 } else { -1 }, + ); } } _ => { - result = unsafe{Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char)}; + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); if result as u64 != 0 { return result; } - result = unsafe{Curl_buffer_send( - r, - data, - &mut (*data).info.request_size, - 0 as curl_off_t, - 0, - )}; + result = Curl_buffer_send(r, data, &mut (*data).info.request_size, 0 as curl_off_t, 0); if result as u64 != 0 { - unsafe{ Curl_failf( + Curl_failf( data, b"Failed sending HTTP request\0" as *const u8 as *const libc::c_char, - );} + ); } else { - unsafe{Curl_setup_transfer( - data, - 0, - -1 as curl_off_t, - true, - -1, - );} + Curl_setup_transfer(data, 0, -1 as curl_off_t, true, -1); } } } +} return result; } #[cfg(not(CURL_DISABLE_COOKIES))] #[no_mangle] -pub extern "C" fn Curl_http_cookies( +pub extern "C" fn Curl_http_cookies( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut r: *mut dynbuf, ) -> CURLcode { let mut result: CURLcode = CURLE_OK; let mut addcookies: *mut libc::c_char = 0 as *mut libc::c_char; - if unsafe{!((*data).set.str_0[STRING_COOKIE as usize]).is_null() + if unsafe{!((*data).set.str_0[STRING_COOKIE as i32 as usize]).is_null() && (Curl_checkheaders(data, b"Cookie\0" as *const u8 as *const libc::c_char)).is_null()} { - addcookies = unsafe{(*data).set.str_0[STRING_COOKIE as usize]}; + addcookies = unsafe{(*data).set.str_0[STRING_COOKIE as i32 as usize]}; } if unsafe{!((*data).cookies).is_null() || !addcookies.is_null()} { let mut co: *mut Cookie = 0 as *mut Cookie; let mut count: i32 = 0 as i32; if unsafe{!((*data).cookies).is_null() && ((*data).state).cookie_engine() as i32 != 0 }{ - let mut host: *const libc::c_char = unsafe{if !((*data).state.aptr.cookiehost).is_null() { + unsafe{ + let mut host: *const libc::c_char = if !((*data).state.aptr.cookiehost).is_null() { (*data).state.aptr.cookiehost } else { (*conn).host.name - }}; + }; let secure_context: bool = - if unsafe{(*(*conn).handler).protocol & ((1 as i32) << 1 as i32) as u32 != 0 + if (*(*conn).handler).protocol & ((1 as i32) << 1 as i32) as u32 != 0 || Curl_strcasecompare(b"localhost\0" as *const u8 as *const libc::c_char, host) != 0 || strcmp(host, b"127.0.0.1\0" as *const u8 as *const libc::c_char) == 0 - || strcmp(host, b"[::1]\0" as *const u8 as *const libc::c_char) == 0} + || strcmp(host, b"[::1]\0" as *const u8 as *const libc::c_char) == 0 { 1 } else { 0 } != 0; - unsafe{ Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); co = Curl_cookie_getlist((*data).cookies, host, (*data).state.up.path, secure_context); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);} + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } } + unsafe{ if !co.is_null() { let mut store: *mut Cookie = co; /* now loop through all cookies that matched */ while !co.is_null() { - if unsafe{!((*co).value).is_null()} { + if !((*co).value).is_null() { if 0 as i32 == count { - result =unsafe{ Curl_dyn_add(r, b"Cookie: \0" as *const u8 as *const libc::c_char)}; + result = Curl_dyn_add(r, b"Cookie: \0" as *const u8 as *const libc::c_char); if result as u64 != 0 { break; } } - result = unsafe{Curl_dyn_addf( + result = Curl_dyn_addf( r, b"%s%s=%s\0" as *const u8 as *const libc::c_char, if count != 0 { @@ -4423,23 +4412,23 @@ pub extern "C" fn Curl_http_cookies( }, (*co).name, (*co).value, - )}; + ); if result as u64 != 0 { break; } count += 1; } - co = unsafe{(*co).next}; + co = (*co).next; } - unsafe{ Curl_cookie_freelist(store);} + Curl_cookie_freelist(store); } if !addcookies.is_null() && result as u64 == 0 { if count == 0 { - result = unsafe{Curl_dyn_add(r, b"Cookie: \0" as *const u8 as *const libc::c_char)}; + result = Curl_dyn_add(r, b"Cookie: \0" as *const u8 as *const libc::c_char); } if result as u64 == 0 { - result = unsafe{Curl_dyn_addf( + result = Curl_dyn_addf( r, b"%s%s\0" as *const u8 as *const libc::c_char, if count != 0 { @@ -4448,38 +4437,41 @@ pub extern "C" fn Curl_http_cookies( b"\0" as *const u8 as *const libc::c_char }, addcookies, - )}; + ); count += 1; } } if count != 0 && result as u64 == 0 { - result = unsafe{Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char)}; + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); } if result as u64 != 0 { return result; } } + } return result; } #[cfg(CURL_DISABLE_COOKIES)] #[no_mangle] -pub extern "C" fn Curl_http_cookies( +pub extern "C" fn Curl_http_cookies( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut r: *mut dynbuf, ) -> CURLcode { - return CURLE_OK; + unsafe{ + return CURLE_OK;} } #[no_mangle] -pub extern "C" fn Curl_http_range( +pub extern "C" fn Curl_http_range( mut data: *mut Curl_easy, mut httpreq: Curl_HttpReq, ) -> CURLcode { - if unsafe{((*data).state).use_range() != 0} { - if (httpreq as u32 == HTTPREQ_GET as u32 - || httpreq as u32 == HTTPREQ_HEAD as u32) - && unsafe{(Curl_checkheaders(data, b"Range\0" as *const u8 as *const libc::c_char)).is_null()} - {unsafe{ + unsafe{ + if ((*data).state).use_range() != 0 { + if (httpreq as u32 == HTTPREQ_GET as i32 as u32 + || httpreq as u32 == HTTPREQ_HEAD as i32 as u32) + && (Curl_checkheaders(data, b"Range\0" as *const u8 as *const libc::c_char)).is_null() + { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( (*data).state.aptr.rangeline as *mut libc::c_void, @@ -4493,12 +4485,12 @@ pub extern "C" fn Curl_http_range( (*data).state.aptr.rangeline = curl_maprintf( b"Range: bytes=%s\r\n\0" as *const u8 as *const libc::c_char, (*data).state.range, - );} - } else if (httpreq as u32 == HTTPREQ_POST as u32 - || httpreq as u32 == HTTPREQ_PUT as u32) - && unsafe{(Curl_checkheaders(data, b"Content-Range\0" as *const u8 as *const libc::c_char)) - .is_null()} - {unsafe{ + ); + } else if (httpreq as u32 == HTTPREQ_POST as i32 as u32 + || httpreq as u32 == HTTPREQ_PUT as i32 as u32) + && (Curl_checkheaders(data, b"Content-Range\0" as *const u8 as *const libc::c_char)) + .is_null() + { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( (*data).state.aptr.rangeline as *mut libc::c_void, @@ -4509,10 +4501,10 @@ pub extern "C" fn Curl_http_range( 2784 as i32, b"http.c\0" as *const u8 as *const libc::c_char, ); - if (*data).set.set_resume_from < 0 as i64 { + if (*data).set.set_resume_from < 0 as i32 as i64 { (*data).state.aptr.rangeline = curl_maprintf( b"Content-Range: bytes 0-%ld/%ld\r\n\0" as *const u8 as *const libc::c_char, - (*data).state.infilesize - 1 as i64, + (*data).state.infilesize - 1 as i32 as i64, (*data).state.infilesize, ); } else if (*data).state.resume_from != 0 { @@ -4521,7 +4513,7 @@ pub extern "C" fn Curl_http_range( (*data).state.aptr.rangeline = curl_maprintf( b"Content-Range: bytes %s%ld/%ld\r\n\0" as *const u8 as *const libc::c_char, (*data).state.range, - total_expected_size - 1 as i64, + total_expected_size - 1 as i32 as i64, total_expected_size, ); } else { @@ -4533,146 +4525,148 @@ pub extern "C" fn Curl_http_range( } if ((*data).state.aptr.rangeline).is_null() { return CURLE_OUT_OF_MEMORY; - }} + } } } - return CURLE_OK; + return CURLE_OK;} } #[no_mangle] -pub extern "C" fn Curl_http_resume( +pub extern "C" fn Curl_http_resume( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut httpreq: Curl_HttpReq, ) -> CURLcode { - if (HTTPREQ_POST as u32 == httpreq as u32 || HTTPREQ_PUT as u32 == httpreq as u32) - && unsafe{(*data).state.resume_from != 0} + unsafe{ + if (HTTPREQ_POST as i32 as u32 == httpreq as u32 || HTTPREQ_PUT as i32 as u32 == httpreq as u32) + && (*data).state.resume_from != 0 { - if unsafe{(*data).state.resume_from < 0 as i64 }{ - unsafe{ (*data).state.resume_from = 0 as curl_off_t;} + if (*data).state.resume_from < 0 as i32 as i64 { + (*data).state.resume_from = 0 as i32 as curl_off_t; } - if unsafe{(*data).state.resume_from != 0 && ((*data).state).this_is_a_follow() == 0} { + if (*data).state.resume_from != 0 && ((*data).state).this_is_a_follow() == 0 { let mut seekerr: i32 = 2 as i32; - if unsafe{((*conn).seek_func).is_some() }{ - unsafe{ Curl_set_in_callback(data, 1 as i32 != 0); + if ((*conn).seek_func).is_some() { + Curl_set_in_callback(data, 1 as i32 != 0); seekerr = ((*conn).seek_func).expect("non-null function pointer")( (*conn).seek_client, (*data).state.resume_from, 0 as i32, ); - Curl_set_in_callback(data, 0 as i32 != 0);} + Curl_set_in_callback(data, 0 as i32 != 0); } if seekerr != 0 as i32 { let mut passed: curl_off_t = 0 as i32 as curl_off_t; if seekerr != 2 as i32 { - unsafe{Curl_failf( + Curl_failf( data, b"Could not seek stream\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_READ_ERROR; } loop { let mut readthisamountnow: size_t = - if unsafe{(*data).state.resume_from - passed > (*data).set.buffer_size} { - unsafe{ (*data).set.buffer_size as size_t} + if (*data).state.resume_from - passed > (*data).set.buffer_size { + (*data).set.buffer_size as size_t } else { - unsafe{curlx_sotouz((*data).state.resume_from - passed)} + curlx_sotouz((*data).state.resume_from - passed) }; - let mut actuallyread: size_t = unsafe{((*data).state.fread_func) + let mut actuallyread: size_t = ((*data).state.fread_func) .expect("non-null function pointer")( (*data).state.buffer, - 1 as size_t, + 1 as i32 as size_t, readthisamountnow, (*data).state.in_0, - )}; - passed = (passed as u64).wrapping_add(actuallyread) as curl_off_t; - if actuallyread == 0 as u64 || actuallyread > readthisamountnow { - unsafe{ Curl_failf( + ); + passed = (passed as u64).wrapping_add(actuallyread) as curl_off_t as curl_off_t; + if actuallyread == 0 as i32 as u64 || actuallyread > readthisamountnow { + Curl_failf( data, b"Could only read %ld bytes from the input\0" as *const u8 as *const libc::c_char, passed, - );} + ); return CURLE_READ_ERROR; } - if unsafe{ !(passed < (*data).state.resume_from)} { + if !(passed < (*data).state.resume_from) { break; } } } - if unsafe{ (*data).state.infilesize > 0 as i64} { - unsafe{ (*data).state.infilesize -= (*data).state.resume_from;} - if unsafe{(*data).state.infilesize <= 0 as i64} { - unsafe{ Curl_failf( + if (*data).state.infilesize > 0 as i64 { + (*data).state.infilesize -= (*data).state.resume_from; + if (*data).state.infilesize <= 0 as i32 as i64 { + Curl_failf( data, b"File already completely uploaded\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_PARTIAL_FILE; } } } } - return CURLE_OK; + return CURLE_OK;} } #[no_mangle] -pub extern "C" fn Curl_http_firstwrite( +pub extern "C" fn Curl_http_firstwrite( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut done: *mut bool, ) -> CURLcode { - let mut k: *mut SingleRequest = unsafe{&mut (*data).req}; + let mut k: *mut SingleRequest =unsafe{ &mut (*data).req}; + unsafe{ #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{(*(*conn).handler).protocol + if (*(*conn).handler).protocol & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32 | (1 as i32) << 18 as i32) as u32 - != 0} + != 0 { } else { - unsafe{ __assert_fail( - b"conn->handler->protocol&(((1<<0)|(1<<1))|(1<<18))\0" as *const u8 - as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 2905 as u32, - (*::std::mem::transmute::< - &[u8; 81], - &[libc::c_char; 81], - >( - b"CURLcode Curl_http_firstwrite(struct Curl_easy *, struct connectdata *, _Bool *)\0", - )) - .as_ptr(), - );} - } - if unsafe{((*data).req).ignore_cl() != 0 }{ - let ref mut fresh64 = unsafe{(*k).maxdownload}; + __assert_fail( + b"conn->handler->protocol&(((1<<0)|(1<<1))|(1<<18))\0" as *const u8 + as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 2905 as i32 as u32, + (*::std::mem::transmute::< + &[u8; 81], + &[libc::c_char; 81], + >( + b"CURLcode Curl_http_firstwrite(struct Curl_easy *, struct connectdata *, _Bool *)\0", + )) + .as_ptr(), + ); + } + if ((*data).req).ignore_cl() != 0 { + let ref mut fresh64 = (*k).maxdownload; *fresh64 = -(1 as i32) as curl_off_t; - unsafe{ (*k).size = *fresh64;} - } else if unsafe{(*k).size != -(1 as i32) as i64 }{ - if unsafe{(*data).set.max_filesize != 0 && (*k).size > (*data).set.max_filesize} { - unsafe{ Curl_failf( + (*k).size = *fresh64; + } else if (*k).size != -(1 as i32) as i64 { + if (*data).set.max_filesize != 0 && (*k).size > (*data).set.max_filesize { + Curl_failf( data, b"Maximum file size exceeded\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_FILESIZE_EXCEEDED; } - unsafe{ Curl_pgrsSetDownloadSize(data, (*k).size);} + Curl_pgrsSetDownloadSize(data, (*k).size); } - if unsafe{!((*data).req.newurl).is_null() }{ - if unsafe{((*conn).bits).close() != 0} { - unsafe{(*k).keepon &= !((1 as i32) << 0 as i32); - *done = 1 as i32 != 0;} + if !((*data).req.newurl).is_null() { + if ((*conn).bits).close() != 0 { + (*k).keepon &= !((1 as i32) << 0 as i32); + *done = 1 as i32 != 0; return CURLE_OK; } - unsafe{(*k).set_ignorebody(1 as bit); + (*k).set_ignorebody(1 as i32 as bit); Curl_infof( data, b"Ignoring the response-body\0" as *const u8 as *const libc::c_char, - );} + ); } - if unsafe{(*data).state.resume_from != 0 + if (*data).state.resume_from != 0 && (*k).content_range() == 0 - && (*data).state.httpreq as u32 == HTTPREQ_GET as u32 - && (*k).ignorebody() == 0} + && (*data).state.httpreq as u32 == HTTPREQ_GET as i32 as u32 + && (*k).ignorebody() == 0 { - if unsafe{(*k).size == (*data).state.resume_from }{ - unsafe{ Curl_infof( + if (*k).size == (*data).state.resume_from { + Curl_infof( data, b"The entire document is already downloaded\0" as *const u8 as *const libc::c_char, ); @@ -4686,18 +4680,18 @@ pub extern "C" fn Curl_http_firstwrite( ); (*k).keepon &= !((1 as i32) << 0 as i32); *done = 1 as i32 != 0; - return CURLE_OK;} - }unsafe{ + return CURLE_OK; + } Curl_failf( data, b"HTTP server doesn't seem to support byte ranges. Cannot resume.\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_RANGE_ERROR; } - if unsafe{(*data).set.timecondition as u32 != 0 && ((*data).state.range).is_null()} { - if unsafe{!Curl_meets_timecondition(data, (*k).timeofdoc)} { - unsafe{*done = 1 as i32 != 0; + if (*data).set.timecondition as u32 != 0 && ((*data).state.range).is_null() { + if !Curl_meets_timecondition(data, (*k).timeofdoc) { + *done = 1 as i32 != 0; (*data).info.httpcode = 304 as i32; Curl_infof( data, @@ -4710,36 +4704,37 @@ pub extern "C" fn Curl_http_firstwrite( conn, 1 as i32, b"Simulated 304 handling\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_OK; } - } + }} return CURLE_OK; } #[cfg(HAVE_LIBZ)] #[no_mangle] -pub extern "C" fn Curl_transferencode(mut data: *mut Curl_easy) -> CURLcode { - if unsafe{(Curl_checkheaders(data, b"TE\0" as *const u8 as *const libc::c_char)).is_null() - && ((*data).set).http_transfer_encoding() as i32 != 0} +pub extern "C" fn Curl_transferencode(mut data: *mut Curl_easy) -> CURLcode { + unsafe{ + if (Curl_checkheaders(data, b"TE\0" as *const u8 as *const libc::c_char)).is_null() + && ((*data).set).http_transfer_encoding() as i32 != 0 { let mut cptr: *mut libc::c_char = - unsafe{Curl_checkheaders(data, b"Connection\0" as *const u8 as *const libc::c_char)}; + Curl_checkheaders(data, b"Connection\0" as *const u8 as *const libc::c_char); #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")((*data).state.aptr.te as *mut libc::c_void);} + Curl_cfree.expect("non-null function pointer")((*data).state.aptr.te as *mut libc::c_void); #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( + curl_dbg_free( (*data).state.aptr.te as *mut libc::c_void, 2990 as i32, b"http.c\0" as *const u8 as *const libc::c_char, ); - (*data).state.aptr.te = 0 as *mut libc::c_char;} + (*data).state.aptr.te = 0 as *mut libc::c_char; if !cptr.is_null() { cptr = Curl_copy_header_value(cptr); if cptr.is_null() { return CURLE_OUT_OF_MEMORY; } } - unsafe{ (*data).state.aptr.te = curl_maprintf( + (*data).state.aptr.te = curl_maprintf( b"Connection: %s%sTE\r\nTE: gzip\r\n\0" as *const u8 as *const libc::c_char, if !cptr.is_null() { cptr as *const libc::c_char @@ -4759,17 +4754,18 @@ pub extern "C" fn Curl_transferencode(mut data: *mut Curl_easy) -> CURLcode { cptr as *mut libc::c_void, 3002 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} - if unsafe{((*data).state.aptr.te).is_null()} { + ); + if ((*data).state.aptr.te).is_null() { return CURLE_OUT_OF_MEMORY; } - } + }} return CURLE_OK; } #[cfg(not(USE_HYPER))] #[no_mangle] -pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { - let mut conn: *mut connectdata = unsafe{(*data).conn}; +pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { + unsafe{ + let mut conn: *mut connectdata = (*data).conn; let mut result: CURLcode = CURLE_OK; let mut http: *mut HTTP = 0 as *mut HTTP; let mut httpreq: Curl_HttpReq = HTTPREQ_GET; @@ -4786,10 +4782,9 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C }; let mut altused: *mut libc::c_char = 0 as *mut libc::c_char; let mut p_accept: *const libc::c_char = 0 as *const libc::c_char; - unsafe{*done = 1 as i32 != 0;} - if unsafe{(*conn).transport as u32 }!= TRNSPRT_QUIC as u32 { - if unsafe{((*conn).httpversion as i32) < 20 as i32} { - unsafe{ + *done = 1 as i32 != 0; + if (*conn).transport as u32 != TRNSPRT_QUIC as i32 as u32 { + if ((*conn).httpversion as i32) < 20 as i32 { match (*conn).negnpn { 3 => { (*conn).httpversion = 20 as i32 as u8; @@ -4819,11 +4814,11 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C data, b"HTTP/2 over clean TCP\0" as *const u8 as *const libc::c_char, ); - (*conn).httpversion = 20 as u8; + (*conn).httpversion = 20 as i32 as u8; result = Curl_http2_switched( data, 0 as *const libc::c_char, - 0 as size_t, + 0 as i32 as size_t, ); if result as u64 != 0 { return result; @@ -4831,49 +4826,48 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C } } } - }} + } } else { - result = unsafe{Curl_http2_setup(data, conn)}; + result = Curl_http2_setup(data, conn); if result as u64 != 0 { return result; } } } - http =unsafe{ (*data).req.p.http}; + http = (*data).req.p.http; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] if !http.is_null() { } else { - unsafe{__assert_fail( + __assert_fail( b"http\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, - 3079 as u32, + 3079 as i32 as u32, (*::std::mem::transmute::<&[u8; 48], &[libc::c_char; 48]>( b"CURLcode Curl_http(struct Curl_easy *, _Bool *)\0", )) .as_ptr(), - );} + ); } - result = unsafe{Curl_http_host(data, conn)}; + result = Curl_http_host(data, conn); if result as u64 != 0 { return result; } - result = unsafe{Curl_http_useragent(data)}; + result = Curl_http_useragent(data); if result as u64 != 0 { return result; } - unsafe{Curl_http_method(data, conn, &mut request, &mut httpreq);} + Curl_http_method(data, conn, &mut request, &mut httpreq); let mut pq: *mut libc::c_char = 0 as *mut libc::c_char; - if unsafe{!((*data).state.up.query).is_null() }{ - pq = unsafe{curl_maprintf( + if !((*data).state.up.query).is_null() { + pq = curl_maprintf( b"%s?%s\0" as *const u8 as *const libc::c_char, (*data).state.up.path, (*data).state.up.query, - )}; + ); if pq.is_null() { return CURLE_OUT_OF_MEMORY; } } - unsafe{ result = Curl_http_output_auth( data, conn, @@ -4893,10 +4887,10 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C pq as *mut libc::c_void, 3101 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); if result as u64 != 0 { return result; - }unsafe{ + } #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")((*data).state.aptr.ref_0 as *mut libc::c_void); #[cfg(CURLDEBUG)] @@ -4905,25 +4899,25 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C 3106 as i32, b"http.c\0" as *const u8 as *const libc::c_char, ); - (*data).state.aptr.ref_0 = 0 as *mut libc::c_char;} - if unsafe{!((*data).state.referer).is_null() - && (Curl_checkheaders(data, b"Referer\0" as *const u8 as *const libc::c_char)).is_null()} + (*data).state.aptr.ref_0 = 0 as *mut libc::c_char; + if !((*data).state.referer).is_null() + && (Curl_checkheaders(data, b"Referer\0" as *const u8 as *const libc::c_char)).is_null() { - unsafe{ (*data).state.aptr.ref_0 = curl_maprintf( + (*data).state.aptr.ref_0 = curl_maprintf( b"Referer: %s\r\n\0" as *const u8 as *const libc::c_char, (*data).state.referer, - );} - if unsafe{((*data).state.aptr.ref_0).is_null()} { + ); + if ((*data).state.aptr.ref_0).is_null() { return CURLE_OUT_OF_MEMORY; } } - if unsafe{(Curl_checkheaders( + if (Curl_checkheaders( data, b"Accept-Encoding\0" as *const u8 as *const libc::c_char, )) .is_null() - && !((*data).set.str_0[STRING_ENCODING as usize]).is_null()} - {unsafe{ + && !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null() + { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( (*data).state.aptr.accept_encoding as *mut libc::c_void, @@ -4937,13 +4931,12 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C (*data).state.aptr.accept_encoding = 0 as *mut libc::c_char; (*data).state.aptr.accept_encoding = curl_maprintf( b"Accept-Encoding: %s\r\n\0" as *const u8 as *const libc::c_char, - (*data).set.str_0[STRING_ENCODING as usize], + (*data).set.str_0[STRING_ENCODING as i32 as usize], ); if ((*data).state.aptr.accept_encoding).is_null() { return CURLE_OUT_OF_MEMORY; - }} + } } else { - unsafe{ #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( (*data).state.aptr.accept_encoding as *mut libc::c_void, @@ -4954,13 +4947,13 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C 3122 as i32, b"http.c\0" as *const u8 as *const libc::c_char, ); - (*data).state.aptr.accept_encoding = 0 as *mut libc::c_char;} + (*data).state.aptr.accept_encoding = 0 as *mut libc::c_char; } // TODO 测试过了就把注释删咯 match () { #[cfg(HAVE_LIBZ)] _ => { - result = unsafe{Curl_transferencode(data)}; + result = Curl_transferencode(data); if result as u64 != 0 { return result; } @@ -4974,55 +4967,55 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C // return result; // } // } - result = unsafe{Curl_http_body(data, conn, httpreq, &mut te)}; + result = Curl_http_body(data, conn, httpreq, &mut te); if result as u64 != 0 { return result; } p_accept = - if unsafe{!(Curl_checkheaders(data, b"Accept\0" as *const u8 as *const libc::c_char)).is_null()} { + if !(Curl_checkheaders(data, b"Accept\0" as *const u8 as *const libc::c_char)).is_null() { 0 as *const libc::c_char } else { b"Accept: */*\r\n\0" as *const u8 as *const libc::c_char }; - result = unsafe{Curl_http_resume(data, conn, httpreq)}; + result = Curl_http_resume(data, conn, httpreq); if result as u64 != 0 { return result; } - result = unsafe{Curl_http_range(data, httpreq)}; + result = Curl_http_range(data, httpreq); if result as u64 != 0 { return result; } - httpstring = unsafe{get_http_string(data, conn)}; - unsafe{Curl_dyn_init(&mut req, (1024 as i32 * 1024 as i32) as size_t); - Curl_dyn_reset(&mut (*data).state.headerb);} - result = unsafe{Curl_dyn_addf( + httpstring = get_http_string(data, conn); + Curl_dyn_init(&mut req, (1024 as i32 * 1024 as i32) as size_t); + Curl_dyn_reset(&mut (*data).state.headerb); + result = Curl_dyn_addf( &mut req as *mut dynbuf, b"%s \0" as *const u8 as *const libc::c_char, request, - )}; + ); if result as u64 == 0 { - result = unsafe{Curl_http_target(data, conn, &mut req)}; + result = Curl_http_target(data, conn, &mut req); } if result as u64 != 0 { - unsafe{Curl_dyn_free(&mut req);} + Curl_dyn_free(&mut req); return result; } #[cfg(not(CURL_DISABLE_ALTSVC))] - if unsafe{((*conn).bits).altused() as i32 != 0} - && unsafe{(Curl_checkheaders(data, b"Alt-Used\0" as *const u8 as *const libc::c_char)).is_null()} + if ((*conn).bits).altused() as i32 != 0 + && (Curl_checkheaders(data, b"Alt-Used\0" as *const u8 as *const libc::c_char)).is_null() { - altused = unsafe{curl_maprintf( + altused = curl_maprintf( b"Alt-Used: %s:%d\r\n\0" as *const u8 as *const libc::c_char, (*conn).conn_to_host.name, (*conn).conn_to_port, - )}; + ); if altused.is_null() { - unsafe{Curl_dyn_free(&mut req);} + Curl_dyn_free(&mut req); return CURLE_OUT_OF_MEMORY; } } #[cfg(not(CURL_DISABLE_PROXY))] - let flag2: bool = unsafe{((*conn).bits).httpproxy() as i32 != 0 + let flag2: bool = ((*conn).bits).httpproxy() as i32 != 0 && ((*conn).bits).tunnel_proxy() == 0 && (Curl_checkheaders( data, @@ -5034,10 +5027,10 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C conn, b"Proxy-Connection\0" as *const u8 as *const libc::c_char, )) - .is_null()}; + .is_null(); #[cfg(CURL_DISABLE_PROXY)] let flag2: bool = false; - result = unsafe{Curl_dyn_addf( + result = Curl_dyn_addf( &mut req as *mut dynbuf, b" HTTP/%s\r\n%s%s%s%s%s%s%s%s%s%s%s%s\0" as *const u8 as *const libc::c_char, httpstring, @@ -5061,8 +5054,8 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C } else { b"\0" as *const u8 as *const libc::c_char }, - if !((*data).set.str_0[STRING_USERAGENT as usize]).is_null() - && *(*data).set.str_0[STRING_USERAGENT as usize] as i32 != 0 + if !((*data).set.str_0[STRING_USERAGENT as i32 as usize]).is_null() + && *(*data).set.str_0[STRING_USERAGENT as i32 as usize] as i32 != 0 && !((*data).state.aptr.uagent).is_null() { (*data).state.aptr.uagent as *const libc::c_char @@ -5079,8 +5072,8 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C } else { b"\0" as *const u8 as *const libc::c_char }, - if !((*data).set.str_0[STRING_ENCODING as usize]).is_null() - && *(*data).set.str_0[STRING_ENCODING as usize] as i32 != 0 + if !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null() + && *(*data).set.str_0[STRING_ENCODING as i32 as usize] as i32 != 0 && !((*data).state.aptr.accept_encoding).is_null() { (*data).state.aptr.accept_encoding as *const libc::c_char @@ -5103,8 +5096,7 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C } else { b"\0" as *const u8 as *const libc::c_char }, - )}; - unsafe{ + ); #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")((*data).state.aptr.userpwd as *mut libc::c_void); #[cfg(CURLDEBUG)] @@ -5132,54 +5124,54 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C altused as *mut libc::c_void, 3226 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); if result as u64 != 0 { - unsafe{Curl_dyn_free(&mut req);} + Curl_dyn_free(&mut req); return result; } - if unsafe{(*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 == 0 + if (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 == 0 && (*conn).httpversion as i32 != 20 as i32 - && (*data).state.httpwant as i32 == CURL_HTTP_VERSION_2_0 as i32} + && (*data).state.httpwant as i32 == CURL_HTTP_VERSION_2_0 as i32 { - result = unsafe{Curl_http2_request_upgrade(&mut req, data)}; + result = Curl_http2_request_upgrade(&mut req, data); if result as u64 != 0 { - unsafe{Curl_dyn_free(&mut req);} + Curl_dyn_free(&mut req); return result; } } - result = unsafe{Curl_http_cookies(data, conn, &mut req)}; + result = Curl_http_cookies(data, conn, &mut req); if result as u64 == 0 { - result = unsafe{Curl_add_timecondition(data, &mut req)}; + result = Curl_add_timecondition(data, &mut req); } if result as u64 == 0 { - result = unsafe{Curl_add_custom_headers(data, 0 as i32 != 0, &mut req)}; + result = Curl_add_custom_headers(data, 0 as i32 != 0, &mut req); } if result as u64 == 0 { - unsafe{(*http).postdata = 0 as *const libc::c_char;} - if httpreq as u32 == HTTPREQ_GET as u32 - || httpreq as u32 == HTTPREQ_HEAD as u32 + (*http).postdata = 0 as *const libc::c_char; + if httpreq as u32 == HTTPREQ_GET as i32 as u32 + || httpreq as u32 == HTTPREQ_HEAD as i32 as u32 { - unsafe{ Curl_pgrsSetUploadSize(data, 0 as curl_off_t);} + Curl_pgrsSetUploadSize(data, 0 as i32 as curl_off_t); } - result = unsafe{Curl_http_bodysend(data, conn, &mut req, httpreq)}; + result = Curl_http_bodysend(data, conn, &mut req, httpreq); } if result as u64 != 0 { - unsafe{ Curl_dyn_free(&mut req);} + Curl_dyn_free(&mut req); return result; } - if unsafe{(*http).postsize > -(1 as i32) as i64 + if (*http).postsize > -(1 as i32) as i64 && (*http).postsize <= (*data).req.writebytecount - && (*http).sending as u32 != HTTPSEND_REQUEST as i32 as u32} + && (*http).sending as u32 != HTTPSEND_REQUEST as i32 as u32 { - unsafe{ (*data).req.set_upload_done(1 as i32 as bit);} + (*data).req.set_upload_done(1 as i32 as bit); } - if unsafe{(*data).req.writebytecount != 0 }{ - unsafe{ Curl_pgrsSetUploadCounter(data, (*data).req.writebytecount);} - if unsafe{Curl_pgrsUpdate(data) != 0} { + if (*data).req.writebytecount != 0 { + Curl_pgrsSetUploadCounter(data, (*data).req.writebytecount); + if Curl_pgrsUpdate(data) != 0 { result = CURLE_ABORTED_BY_CALLBACK; } - if unsafe{(*http).postsize == 0} { - unsafe{ Curl_infof( + if (*http).postsize == 0 { + Curl_infof( data, b"upload completely sent off: %ld out of %ld bytes\0" as *const u8 as *const libc::c_char, @@ -5189,76 +5181,80 @@ pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> C (*data).req.set_upload_done(1 as i32 as bit); (*data).req.keepon &= !((1 as i32) << 1 as i32); (*data).req.exp100 = EXP100_SEND_DATA; - Curl_expire_done(data, EXPIRE_100_TIMEOUT);} + Curl_expire_done(data, EXPIRE_100_TIMEOUT); } } - if unsafe{(*conn).httpversion as i32 == 20 as i32 && ((*data).req).upload_chunky() as i32 != 0} { - unsafe{ (*data).req.set_upload_chunky(0 as bit);} + if (*conn).httpversion as i32 == 20 as i32 && ((*data).req).upload_chunky() as i32 != 0 { + (*data).req.set_upload_chunky(0 as i32 as bit); } return result; } - extern "C" fn checkprefixmax( +} +extern "C" fn checkprefixmax( mut prefix: *const libc::c_char, mut buffer: *const libc::c_char, mut len: size_t, ) -> bool { - let mut ch: size_t = if unsafe{strlen(prefix) < len} { - unsafe{strlen(prefix)} + let mut ch: size_t = unsafe{if strlen(prefix) < len { + strlen(prefix) } else { len - }; + }}; return unsafe{curl_strnequal(prefix, buffer, ch) != 0}; } - extern "C" fn checkhttpprefix( +extern "C" fn checkhttpprefix( mut data: *mut Curl_easy, mut s: *const libc::c_char, mut len: size_t, ) -> statusline { - let mut head: *mut curl_slist = unsafe{(*data).set.http200aliases}; + let mut head: *mut curl_slist =unsafe{ (*data).set.http200aliases}; let mut rc: statusline = STATUS_BAD; - let mut onmatch: statusline = (if len >= 5 as u64 { + let mut onmatch: statusline = (if len >= 5 as i32 as u64 { STATUS_DONE as i32 } else { STATUS_UNKNOWN as i32 }) as statusline; while !head.is_null() { - if unsafe{checkprefixmax((*head).data, s, len)} { + unsafe{ + if checkprefixmax((*head).data, s, len) { rc = onmatch; break; } else { - head = unsafe{(*head).next}; + head = (*head).next; } } - if rc as u32 != STATUS_DONE as u32 - && unsafe{checkprefixmax(b"HTTP/\0" as *const u8 as *const libc::c_char, s, len) as i32 != 0} + } + if rc as u32 != STATUS_DONE as i32 as u32 + && checkprefixmax(b"HTTP/\0" as *const u8 as *const libc::c_char, s, len) as i32 != 0 { rc = onmatch; } return rc; } #[cfg(not(CURL_DISABLE_RSTP))] - extern "C" fn checkrtspprefix( +extern "C" fn checkrtspprefix( mut data: *mut Curl_easy, mut s: *const libc::c_char, mut len: size_t, ) -> statusline { let mut result: statusline = STATUS_BAD; - let mut onmatch: statusline = (if len >= 5 as u64 { + let mut onmatch: statusline = (if len >= 5 as i32 as u64 { STATUS_DONE as i32 } else { STATUS_UNKNOWN as i32 }) as statusline; - if unsafe{checkprefixmax(b"RTSP/\0" as *const u8 as *const libc::c_char, s, len)} { + if checkprefixmax(b"RTSP/\0" as *const u8 as *const libc::c_char, s, len) { result = onmatch; } return result; } - extern "C" fn checkprotoprefix( +extern "C" fn checkprotoprefix( mut data: *mut Curl_easy, mut conn: *mut connectdata, mut s: *const libc::c_char, mut len: size_t, -) -> statusline {unsafe{ +) -> statusline { + unsafe{ #[cfg(not(CURL_DISABLE_RSTP))] if (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 { return checkrtspprefix(data, s, len); @@ -5272,45 +5268,46 @@ pub extern "C" fn Curl_http_header( mut headp: *mut libc::c_char, ) -> CURLcode { let mut result: CURLcode = CURLE_OK; - let mut k: *mut SingleRequest = unsafe{&mut (*data).req}; + let mut k: *mut SingleRequest =unsafe{ &mut (*data).req}; + unsafe{ #[cfg(not(CURL_DISABLE_PROXY))] - let flag1: bool = unsafe{(*conn).httpversion as i32 == 10 as i32 + let flag1: bool = (*conn).httpversion as i32 == 10 as i32 && ((*conn).bits).httpproxy() as i32 != 0 && Curl_compareheader( headp, b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, b"keep-alive\0" as *const u8 as *const libc::c_char, ) as i32 - != 0}; + != 0; #[cfg(CURL_DISABLE_PROXY)] let flag1: bool = false; #[cfg(not(CURL_DISABLE_PROXY))] - let flag2: bool = unsafe{(*conn).httpversion as i32 == 11 as i32 + let flag2: bool = (*conn).httpversion as i32 == 11 as i32 && ((*conn).bits).httpproxy() as i32 != 0 && Curl_compareheader( headp, b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, b"close\0" as *const u8 as *const libc::c_char, ) as i32 - != 0}; + != 0; #[cfg(CURL_DISABLE_PROXY)] let flag2: bool = false; #[cfg(not(CURL_DISABLE_COOKIES))] - let flag3: bool = unsafe{!((*data).cookies).is_null() + let flag3: bool = !((*data).cookies).is_null() && ((*data).state).cookie_engine() as i32 != 0 && curl_strnequal( b"Set-Cookie:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Set-Cookie:\0" as *const u8 as *const libc::c_char), - ) != 0}; + ) != 0; #[cfg(CURL_DISABLE_COOKIES)] let flag3: bool = false; #[cfg(USE_SPNEGO)] - let flag4: bool =unsafe{ curl_strnequal( + let flag4: bool = curl_strnequal( b"Persistent-Auth:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Persistent-Auth:\0" as *const u8 as *const libc::c_char), - ) != 0}; + ) != 0; #[cfg(not(USE_SPNEGO))] let flag4: bool = false; // let flag4: bool = if cfg!(USE_SPNEGO) { @@ -5323,62 +5320,63 @@ pub extern "C" fn Curl_http_header( // false // }; #[cfg(not(CURL_DISABLE_HSTS))] - let flag5: bool = unsafe{!((*data).hsts).is_null() + let flag5: bool = !((*data).hsts).is_null() && curl_strnequal( b"Strict-Transport-Security:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Strict-Transport-Security:\0" as *const u8 as *const libc::c_char), ) != 0 - && (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0}; + && (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0; #[cfg(CURL_DISABLE_HSTS)] let flag5: bool = false; - let flag6: bool =unsafe{ if cfg!(all(not(CURL_DISABLE_ALTSVC), not(CURLDEBUG))) { - !((*data).asi).is_null() - && curl_strnequal( - b"Alt-Svc:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char), - ) != 0 - && ((*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 || 0 as i32 != 0) - } else if cfg!(all(not(CURL_DISABLE_ALTSVC), CURLDEBUG)) { - !((*data).asi).is_null() - && curl_strnequal( - b"Alt-Svc:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char), - ) != 0 - && ((*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 - || !(getenv(b"CURL_ALTSVC_HTTP\0" as *const u8 as *const libc::c_char)).is_null()) - } else { - false - }}; - if unsafe{(*k).http_bodyless() == 0 + #[cfg(all(not(CURL_DISABLE_ALTSVC), not(CURLDEBUG)))] + let flag6: bool = !((*data).asi).is_null() + && curl_strnequal( + b"Alt-Svc:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char), + ) != 0 + && ((*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 || 0 as i32 != 0); + + #[cfg(all(not(CURL_DISABLE_ALTSVC), CURLDEBUG))] + let flag6: bool = !((*data).asi).is_null() + && curl_strnequal( + b"Alt-Svc:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char), + ) != 0 + && ((*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 + || !(getenv(b"CURL_ALTSVC_HTTP\0" as *const u8 as *const libc::c_char)).is_null()); + #[cfg(CURL_DISABLE_ALTSVC)] + let flag6: bool = false; + + if (*k).http_bodyless() == 0 && ((*data).set).ignorecl() == 0 && curl_strnequal( b"Content-Length:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char), - ) != 0} + ) != 0 { let mut contentlength: curl_off_t = 0; - let mut offt: CURLofft = unsafe{curlx_strtoofft( + let mut offt: CURLofft = curlx_strtoofft( headp.offset(strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char) as isize), 0 as *mut *mut libc::c_char, 10 as i32, &mut contentlength, - )}; - if offt as u32 == CURL_OFFT_OK as u32 { - unsafe{ (*k).size = contentlength; - (*k).maxdownload = (*k).size;} - } else if offt as u32 == CURL_OFFT_FLOW as u32 { - if unsafe{(*data).set.max_filesize != 0} { - unsafe{ Curl_failf( + ); + if offt as u32 == CURL_OFFT_OK as i32 as u32 { + (*k).size = contentlength; + (*k).maxdownload = (*k).size; + } else if offt as u32 == CURL_OFFT_FLOW as i32 as u32 { + if (*data).set.max_filesize != 0 { + Curl_failf( data, b"Maximum file size exceeded\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_FILESIZE_EXCEEDED; } - unsafe{ #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 2 as i32); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] Curl_conncontrol( @@ -5389,35 +5387,35 @@ pub extern "C" fn Curl_http_header( Curl_infof( data, b"Overflow Content-Length: value!\0" as *const u8 as *const libc::c_char, - );} + ); } else { - unsafe{Curl_failf( + Curl_failf( data, b"Invalid Content-Length: value\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_WEIRD_SERVER_REPLY; } - } else if unsafe{curl_strnequal( + } else if curl_strnequal( b"Content-Type:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), - ) != 0} + ) != 0 { - let mut contenttype: *mut libc::c_char =unsafe{ Curl_copy_header_value(headp)}; + let mut contenttype: *mut libc::c_char = Curl_copy_header_value(headp); if contenttype.is_null() { return CURLE_OUT_OF_MEMORY; } - if unsafe{*contenttype == 0} { - unsafe{#[cfg(not(CURLDEBUG))] + if *contenttype == 0 { + #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(contenttype as *mut libc::c_void); #[cfg(CURLDEBUG)] curl_dbg_free( contenttype as *mut libc::c_void, 3445 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); } else { - unsafe{#[cfg(not(CURLDEBUG))] + #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( (*data).info.contenttype as *mut libc::c_void, ); @@ -5428,10 +5426,10 @@ pub extern "C" fn Curl_http_header( b"http.c\0" as *const u8 as *const libc::c_char, ); (*data).info.contenttype = 0 as *mut libc::c_char; - (*data).info.contenttype = contenttype;} + (*data).info.contenttype = contenttype; } } else if flag1 { - unsafe{#[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 0 as i32); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] Curl_conncontrol( @@ -5442,9 +5440,9 @@ pub extern "C" fn Curl_http_header( Curl_infof( data, b"HTTP/1.0 proxy connection set to keep alive!\0" as *const u8 as *const libc::c_char, - );} + ); } else if flag2 { - unsafe{#[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 1 as i32); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] Curl_conncontrol( @@ -5455,16 +5453,16 @@ pub extern "C" fn Curl_http_header( Curl_infof( data, b"HTTP/1.1 proxy connection set close!\0" as *const u8 as *const libc::c_char, - );} - } else if unsafe{(*conn).httpversion as i32 == 10 as i32 + ); + } else if (*conn).httpversion as i32 == 10 as i32 && Curl_compareheader( headp, b"Connection:\0" as *const u8 as *const libc::c_char, b"keep-alive\0" as *const u8 as *const libc::c_char, ) as i32 - != 0} + != 0 { - unsafe{#[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 0 as i32); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] Curl_conncontrol( @@ -5475,12 +5473,12 @@ pub extern "C" fn Curl_http_header( Curl_infof( data, b"HTTP/1.0 connection set to keep alive!\0" as *const u8 as *const libc::c_char, - );} - } else if unsafe{Curl_compareheader( + ); + } else if Curl_compareheader( headp, b"Connection:\0" as *const u8 as *const libc::c_char, b"close\0" as *const u8 as *const libc::c_char, - ) }{unsafe{ + ) { #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 2 as i32); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] @@ -5488,26 +5486,26 @@ pub extern "C" fn Curl_http_header( conn, 2 as i32, b"Connection: close used\0" as *const u8 as *const libc::c_char, - );} - } else if unsafe{(*k).http_bodyless() == 0 + ); + } else if (*k).http_bodyless() == 0 && curl_strnequal( b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char), - ) != 0} + ) != 0 { - result =unsafe{ Curl_build_unencoding_stack( + result = Curl_build_unencoding_stack( data, headp.offset( strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char) as isize, ), 1 as i32, - )}; + ); if result as u64 != 0 { return result; } - if unsafe{(*k).chunk() == 0} { - unsafe{ #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + if (*k).chunk() == 0 { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 1 as i32); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] Curl_conncontrol( @@ -5515,94 +5513,94 @@ pub extern "C" fn Curl_http_header( 1 as i32, b"HTTP/1.1 transfer-encoding without chunks\0" as *const u8 as *const libc::c_char, ); - (*k).set_ignore_cl(1 as bit);} + (*k).set_ignore_cl(1 as i32 as bit); } - } else if unsafe{(*k).http_bodyless() == 0 + } else if (*k).http_bodyless() == 0 && curl_strnequal( b"Content-Encoding:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Content-Encoding:\0" as *const u8 as *const libc::c_char), ) != 0 - && !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null()} + && !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null() { - result = unsafe{Curl_build_unencoding_stack( + result = Curl_build_unencoding_stack( data, headp.offset( strlen(b"Content-Encoding:\0" as *const u8 as *const libc::c_char) as isize, ), 0 as i32, - )}; + ); if result as u64 != 0 { return result; } - } else if unsafe{curl_strnequal( + } else if curl_strnequal( b"Retry-After:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Retry-After:\0" as *const u8 as *const libc::c_char), - ) != 0} + ) != 0 { let mut retry_after: curl_off_t = 0 as i32 as curl_off_t; - let mut date: time_t = unsafe{Curl_getdate_capped( + let mut date: time_t = Curl_getdate_capped( headp.offset(strlen(b"Retry-After:\0" as *const u8 as *const libc::c_char) as isize), - )}; + ); if -(1 as i32) as i64 == date { - unsafe{curlx_strtoofft( + curlx_strtoofft( headp .offset(strlen(b"Retry-After:\0" as *const u8 as *const libc::c_char) as isize), 0 as *mut *mut libc::c_char, 10 as i32, &mut retry_after, - )}; + ); } else { - unsafe{retry_after = date - time(0 as *mut time_t);} + retry_after = date - time(0 as *mut time_t); } - unsafe{(*data).info.retry_after = retry_after;} - } else if unsafe{(*k).http_bodyless() == 0 + (*data).info.retry_after = retry_after; + } else if (*k).http_bodyless() == 0 && curl_strnequal( b"Content-Range:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Content-Range:\0" as *const u8 as *const libc::c_char), - ) != 0} + ) != 0 { let mut ptr: *mut libc::c_char = - unsafe{headp.offset(strlen(b"Content-Range:\0" as *const u8 as *const libc::c_char) as isize)}; - while unsafe{*ptr as i32 != 0 && Curl_isdigit(*ptr as u8 as i32) == 0 && *ptr as i32 != '*' as i32} + headp.offset(strlen(b"Content-Range:\0" as *const u8 as *const libc::c_char) as isize); + while *ptr as i32 != 0 && Curl_isdigit(*ptr as u8 as i32) == 0 && *ptr as i32 != '*' as i32 { - ptr = unsafe{ptr.offset(1)}; + ptr = ptr.offset(1); } - if unsafe{Curl_isdigit(*ptr as i32) != 0} { - if unsafe{curlx_strtoofft( + if Curl_isdigit(*ptr as u8 as i32) != 0 { + if curlx_strtoofft( ptr, 0 as *mut *mut libc::c_char, 10 as i32, &mut (*k).offset, ) as u64 - == 0} + == 0 { - if unsafe{(*data).state.resume_from == (*k).offset} { - unsafe{(*k).set_content_range(1 as bit);} + if (*data).state.resume_from == (*k).offset { + (*k).set_content_range(1 as i32 as bit); } } } else { - unsafe{ (*data).state.resume_from = 0 as curl_off_t;} + (*data).state.resume_from = 0 as i32 as curl_off_t; } } else if flag3 { - let mut host: *const libc::c_char = unsafe{if !((*data).state.aptr.cookiehost).is_null() { + let mut host: *const libc::c_char = if !((*data).state.aptr.cookiehost).is_null() { (*data).state.aptr.cookiehost } else { (*conn).host.name - }}; - let secure_context: bool = if unsafe{(*(*conn).handler).protocol & ((1 as i32) << 1 as i32) as u32 + }; + let secure_context: bool = if (*(*conn).handler).protocol & ((1 as i32) << 1 as i32) as u32 != 0 || Curl_strcasecompare(b"localhost\0" as *const u8 as *const libc::c_char, host) != 0 || strcmp(host, b"127.0.0.1\0" as *const u8 as *const libc::c_char) == 0 - || strcmp(host, b"[::1]\0" as *const u8 as *const libc::c_char) == 0} + || strcmp(host, b"[::1]\0" as *const u8 as *const libc::c_char) == 0 { 1 as i32 } else { 0 as i32 } != 0; - unsafe{Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); Curl_cookie_add( data, (*data).cookies, @@ -5613,22 +5611,22 @@ pub extern "C" fn Curl_http_header( (*data).state.up.path, secure_context, ); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);} - } else if unsafe{(*k).http_bodyless() == 0 + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } else if (*k).http_bodyless() == 0 && curl_strnequal( b"Last-Modified:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Last-Modified:\0" as *const u8 as *const libc::c_char), ) != 0 - && ((*data).set.timecondition as u32 != 0 || ((*data).set).get_filetime() as i32 != 0)} + && ((*data).set.timecondition as u32 != 0 || ((*data).set).get_filetime() as i32 != 0) { - unsafe{(*k).timeofdoc = Curl_getdate_capped( + (*k).timeofdoc = Curl_getdate_capped( headp.offset(strlen(b"Last-Modified:\0" as *const u8 as *const libc::c_char) as isize), ); if ((*data).set).get_filetime() != 0 { (*data).info.filetime = (*k).timeofdoc; - }} - } else if unsafe{curl_strnequal( + } + } else if curl_strnequal( b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char, headp, strlen(b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char), @@ -5639,19 +5637,18 @@ pub extern "C" fn Curl_http_header( headp, strlen(b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char), ) != 0 - && 407 as i32 == (*k).httpcode} + && 407 as i32 == (*k).httpcode { - let mut proxy: bool = if unsafe{(*k).httpcode == 407 as i32} { + let mut proxy: bool = if (*k).httpcode == 407 as i32 { 1 as i32 } else { 0 as i32 } != 0; - let mut auth: *mut libc::c_char = unsafe{Curl_copy_header_value(headp)}; + let mut auth: *mut libc::c_char = Curl_copy_header_value(headp); if auth.is_null() { return CURLE_OUT_OF_MEMORY; } - result = unsafe{Curl_http_input_auth(data, proxy, auth)}; - unsafe{ + result = Curl_http_input_auth(data, proxy, auth); #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(auth as *mut libc::c_void); #[cfg(CURLDEBUG)] @@ -5659,14 +5656,14 @@ pub extern "C" fn Curl_http_header( auth as *mut libc::c_void, 3616 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); if result as u64 != 0 { return result; } } else if flag4 { match () { #[cfg(USE_SPNEGO)] - _ => {unsafe{ + _ => { let mut negdata: *mut negotiatedata = &mut (*conn).negotiate; let mut authp: *mut auth = &mut (*data).state.authhost; if (*authp).picked == (1 as i32 as u64) << 2 as i32 { @@ -5697,7 +5694,7 @@ pub extern "C" fn Curl_http_header( Curl_cfree.expect("non-null function pointer")( persistentauth as *mut libc::c_void, ); - }} + } } #[cfg(not(USE_SPNEGO))] _ => {} @@ -5735,20 +5732,20 @@ pub extern "C" fn Curl_http_header( // "non-null function pointer", // )(persistentauth as *mut libc::c_void); // } - } else if unsafe{(*k).httpcode >= 300 as i32 + } else if (*k).httpcode >= 300 as i32 && (*k).httpcode < 400 as i32 && curl_strnequal( b"Location:\0" as *const u8 as *const libc::c_char, headp, strlen(b"Location:\0" as *const u8 as *const libc::c_char), ) != 0 - && ((*data).req.location).is_null()} + && ((*data).req.location).is_null() { - let mut location: *mut libc::c_char = unsafe{Curl_copy_header_value(headp)}; + let mut location: *mut libc::c_char = Curl_copy_header_value(headp); if location.is_null() { return CURLE_OUT_OF_MEMORY; } - if unsafe{*location == 0} {unsafe{ + if *location == 0 { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(location as *mut libc::c_void); #[cfg(CURLDEBUG)] @@ -5756,45 +5753,45 @@ pub extern "C" fn Curl_http_header( location as *mut libc::c_void, 3647 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); } else { - unsafe{ (*data).req.location = location;} - if unsafe{((*data).set).http_follow_location() != 0} { - unsafe{#[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + (*data).req.location = location; + if ((*data).set).http_follow_location() != 0 { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] if ((*data).req.newurl).is_null() { } else { __assert_fail( - b"!data->req.newurl\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 3652 as u32, - (*::std::mem::transmute::< - &[u8; 76], - &[libc::c_char; 76], - >( - b"CURLcode Curl_http_header(struct Curl_easy *, struct connectdata *, char *)\0", - )) - .as_ptr(), - ); - }} + b"!data->req.newurl\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 3652 as i32 as u32, + (*::std::mem::transmute::< + &[u8; 76], + &[libc::c_char; 76], + >( + b"CURLcode Curl_http_header(struct Curl_easy *, struct connectdata *, char *)\0", + )) + .as_ptr(), + ); + } match () { #[cfg(not(CURLDEBUG))] - _ => {unsafe{ + _ => { (*data).req.newurl = Curl_cstrdup.expect("non-null function pointer")((*data).req.location); - }} + } #[cfg(CURLDEBUG)] - _ => {unsafe{ + _ => { (*data).req.newurl = curl_dbg_strdup( (*data).req.location, 3653 as i32, b"http.c\0" as *const u8 as *const libc::c_char, - );} + ); } } - if unsafe{ ((*data).req.newurl).is_null()} { + if ((*data).req.newurl).is_null() { return CURLE_OUT_OF_MEMORY; } - result = unsafe{http_perhapsrewind(data, conn)}; + result = http_perhapsrewind(data, conn); if result as u64 != 0 { return result; } @@ -5804,54 +5801,63 @@ pub extern "C" fn Curl_http_header( match () { #[cfg(not(CURL_DISABLE_HSTS))] _ => { - let mut check: CURLcode = unsafe{Curl_hsts_parse( + let mut check: CURLcode = Curl_hsts_parse( (*data).hsts, (*data).state.up.hostname, headp.offset(strlen( b"Strict-Transport-Security:\0" as *const u8 as *const libc::c_char, ) as isize), - )}; + ); if check as u64 != 0 { - unsafe{Curl_infof( + Curl_infof( data, b"Illegal STS header skipped\0" as *const u8 as *const libc::c_char, - )}; - } else {unsafe{ + ); + } else { #[cfg(DEBUGBUILD)] Curl_infof( data, b"Parsed STS header fine (%zu entries)\0" as *const u8 as *const libc::c_char, (*(*data).hsts).list.size, - );} + ); } } #[cfg(CURL_DISABLE_HSTS)] _ => {} } } else if flag6 { - let mut id: alpnid = (if unsafe{(*conn).httpversion as i32 == 20 as i32} { + let mut id: alpnid = (if (*conn).httpversion as i32 == 20 as i32 { ALPN_h2 as i32 } else { ALPN_h1 as i32 }) as alpnid; - result = unsafe{Curl_altsvc_parse( - data, - (*data).asi, - headp.offset(strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char) as isize), - id, - (*conn).host.name, - curlx_uitous((*conn).remote_port as u32), - )}; + match () { + #[cfg(not(CURL_DISABLE_ALTSVC))] + _ => { + result = Curl_altsvc_parse( + data, + (*data).asi, + headp + .offset(strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char) as isize), + id, + (*conn).host.name, + curlx_uitous((*conn).remote_port as u32), + ); + } + _ => {} + } + if result as u64 != 0 { return result; } - } else if unsafe{(*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0} { - result = unsafe{Curl_rtsp_parseheader(data, headp)}; + } else if (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 { + result = Curl_rtsp_parseheader(data, headp); if result as u64 != 0 { return result; } } +} return CURLE_OK; } #[no_mangle] @@ -5859,8 +5865,9 @@ pub extern "C" fn Curl_http_statusline( mut data: *mut Curl_easy, mut conn: *mut connectdata, ) -> CURLcode { - let mut k: *mut SingleRequest = unsafe{ &mut (*data).req}; - unsafe{(*data).info.httpcode = (*k).httpcode; + let mut k: *mut SingleRequest =unsafe{ &mut (*data).req}; + unsafe{ + (*data).info.httpcode = (*k).httpcode; (*data).info.httpversion = (*conn).httpversion as i32; if (*data).state.httpversion == 0 || (*data).state.httpversion as i32 > (*conn).httpversion as i32 @@ -5868,10 +5875,10 @@ pub extern "C" fn Curl_http_statusline( (*data).state.httpversion = (*conn).httpversion; } if (*data).state.resume_from != 0 - && (*data).state.httpreq as u32 == HTTPREQ_GET as u32 + && (*data).state.httpreq as u32 == HTTPREQ_GET as i32 as u32 && (*k).httpcode == 416 as i32 { - (*k).set_ignorebody(1 as bit); + (*k).set_ignorebody(1 as i32 as bit); } if (*conn).httpversion as i32 == 10 as i32 { Curl_infof( @@ -5903,13 +5910,13 @@ pub extern "C" fn Curl_http_statusline( ); } (*k).set_http_bodyless( - ((*k).httpcode >= 100 as i32 && (*k).httpcode < 200 as i32) as bit, - );} + ((*k).httpcode >= 100 as i32 && (*k).httpcode < 200 as i32) as i32 as bit, + ); let mut current_block_25: u64; - match unsafe{(*k).httpcode} { + match (*k).httpcode { 304 => { - if unsafe{(*data).set.timecondition as u64 != 0} { - unsafe{(*data).info.set_timecond(1 as bit);} + if (*data).set.timecondition as u64 != 0 { + (*data).info.set_timecond(1 as i32 as bit); } current_block_25 = 14741359113768901450; } @@ -5922,12 +5929,13 @@ pub extern "C" fn Curl_http_statusline( } match current_block_25 { 14741359113768901450 => { - unsafe{ (*k).size = 0 as curl_off_t; - (*k).maxdownload = 0 as curl_off_t; - (*k).set_http_bodyless(1 as bit);} + (*k).size = 0 as i32 as curl_off_t; + (*k).maxdownload = 0 as i32 as curl_off_t; + (*k).set_http_bodyless(1 as i32 as bit); } _ => {} } +} return CURLE_OK; } @@ -5943,12 +5951,12 @@ pub extern "C" fn Curl_http_readwrite_headers( ) -> CURLcode { let mut result: CURLcode = CURLE_OK; let mut k: *mut SingleRequest =unsafe{ &mut (*data).req}; - let mut onread: ssize_t = unsafe{*nread}; + let mut onread: ssize_t =unsafe{ *nread}; let mut ostr: *mut libc::c_char = unsafe{(*k).str_0}; let mut headp: *mut libc::c_char = 0 as *mut libc::c_char; let mut str_start: *mut libc::c_char = 0 as *mut libc::c_char; let mut end_ptr: *mut libc::c_char = 0 as *mut libc::c_char; - + unsafe{ /* header line within buffer loop */ loop { let mut rest_length: size_t = 0; @@ -5956,37 +5964,37 @@ pub extern "C" fn Curl_http_readwrite_headers( let mut writetype: i32 = 0; /* str_start is start of line within buf */ - str_start = unsafe{(*k).str_0}; + str_start = (*k).str_0; /* data is in network encoding so use 0x0a instead of '\n' */ - end_ptr =unsafe{ memchr(str_start as *const libc::c_void, 0xa as i32, *nread as u64)} + end_ptr = memchr(str_start as *const libc::c_void, 0xa as i32, *nread as u64) as *mut libc::c_char; if end_ptr.is_null() { /* Not a complete header line within buffer, append the data to the end of the headerbuff. */ - result = unsafe{Curl_dyn_addn( + result = Curl_dyn_addn( &mut (*data).state.headerb, str_start as *const libc::c_void, *nread as size_t, - )}; + ); if result as u64 != 0 { return result; } - if unsafe{!((*k).headerline == 0) }{ + if !((*k).headerline == 0) { /* check if this looks like a protocol header */ break; } - let mut st: statusline = unsafe{checkprotoprefix( + let mut st: statusline = checkprotoprefix( data, conn, Curl_dyn_ptr(&mut (*data).state.headerb), Curl_dyn_len(&mut (*data).state.headerb), - )}; - if !(st as u32 == STATUS_BAD as u32) { + ); + if !(st as u32 == STATUS_BAD as i32 as u32) { break; } - unsafe{(*k).set_header(0 as bit); + (*k).set_header(0 as i32 as bit); (*k).badheader = HEADER_ALLBAD; #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 2 as i32); @@ -5995,37 +6003,37 @@ pub extern "C" fn Curl_http_readwrite_headers( conn, 2 as i32, b"bad HTTP: No end-of-message indicator\0" as *const u8 as *const libc::c_char, - );} - if unsafe{ ((*data).set).http09_allowed() == 0 }{ - unsafe{Curl_failf( + ); + if ((*data).set).http09_allowed() == 0 { + Curl_failf( data, b"Received HTTP/0.9 when not allowed\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_UNSUPPORTED_PROTOCOL; } break; } else { - rest_length = unsafe{(end_ptr.offset_from((*k).str_0) as i64 + 1 as i32 as i64) as size_t}; - unsafe{*nread -= rest_length as ssize_t; + rest_length = (end_ptr.offset_from((*k).str_0) as i64 + 1 as i32 as i64) as size_t; + *nread -= rest_length as ssize_t; (*k).str_0 = end_ptr.offset(1 as isize); - full_length = ((*k).str_0).offset_from(str_start) as size_t; + full_length = ((*k).str_0).offset_from(str_start) as i64 as size_t; result = Curl_dyn_addn( &mut (*data).state.headerb, str_start as *const libc::c_void, full_length, - );} + ); if result as u64 != 0 { return result; } - if unsafe{(*k).headerline == 0} { - let mut st_0: statusline = unsafe{checkprotoprefix( + if (*k).headerline == 0 { + let mut st_0: statusline = checkprotoprefix( data, conn, Curl_dyn_ptr(&mut (*data).state.headerb), Curl_dyn_len(&mut (*data).state.headerb), - )}; - if st_0 as u32 == STATUS_BAD as u32 { - unsafe{ #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + ); + if st_0 as u32 == STATUS_BAD as i32 as u32 { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 2 as i32); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] Curl_conncontrol( @@ -6042,7 +6050,7 @@ pub extern "C" fn Curl_http_readwrite_headers( ); return CURLE_UNSUPPORTED_PROTOCOL; } - (*k).set_header(0 as bit); + (*k).set_header(0 as i32 as bit); if *nread != 0 { (*k).badheader = HEADER_PARTHEADER; } else { @@ -6052,12 +6060,11 @@ pub extern "C" fn Curl_http_readwrite_headers( return CURLE_OK; } break; - }} + } } - headp = unsafe{Curl_dyn_ptr(&mut (*data).state.headerb)}; - if unsafe{0xa as i32 == *headp as i32 || 0xd as i32 == *headp as i32 }{ + headp = Curl_dyn_ptr(&mut (*data).state.headerb); + if 0xa as i32 == *headp as i32 || 0xd as i32 == *headp as i32 { let mut headerlen: size_t = 0; - unsafe{ #[cfg(not(CURL_DOES_CONVERSIONS))] if '\r' as i32 == *headp as i32 { headp = headp.offset(1); @@ -6065,49 +6072,49 @@ pub extern "C" fn Curl_http_readwrite_headers( #[cfg(not(CURL_DOES_CONVERSIONS))] if '\n' as i32 == *headp as i32 { headp = headp.offset(1); - }} - if unsafe{ 100 as i32 <= (*k).httpcode && 199 as i32 >= (*k).httpcode} { - unsafe{match (*k).httpcode { + } + if 100 as i32 <= (*k).httpcode && 199 as i32 >= (*k).httpcode { + match (*k).httpcode { 100 => { - (*k).set_header(1 as bit); + (*k).set_header(1 as i32 as bit); (*k).headerline = 0 as i32; - if (*k).exp100 as u32 > EXP100_SEND_DATA as u32 { + if (*k).exp100 as u32 > EXP100_SEND_DATA as i32 as u32 { (*k).exp100 = EXP100_SEND_DATA; (*k).keepon |= (1 as i32) << 1 as i32; Curl_expire_done(data, EXPIRE_100_TIMEOUT); } } 101 => { - if (*k).upgr101 as u32 == UPGR101_REQUESTED as u32 { + if (*k).upgr101 as u32 == UPGR101_REQUESTED as i32 as u32 { Curl_infof( data, b"Received 101\0" as *const u8 as *const libc::c_char, ); (*k).upgr101 = UPGR101_RECEIVED; - (*k).set_header(1 as bit); + (*k).set_header(1 as i32 as bit); (*k).headerline = 0 as i32; result = Curl_http2_switched(data, (*k).str_0, *nread as size_t); if result as u64 != 0 { return result; } - *nread = 0 as ssize_t; + *nread = 0 as i32 as ssize_t; } else { - (*k).set_header(0 as bit); + (*k).set_header(0 as i32 as bit); } } _ => { - (*k).set_header(1 as bit); + (*k).set_header(1 as i32 as bit); (*k).headerline = 0 as i32; } - }} - } else {unsafe{ - (*k).set_header(0 as bit); + } + } else { + (*k).set_header(0 as i32 as bit); if (*k).size == -(1 as i32) as i64 && (*k).chunk() == 0 && ((*conn).bits).close() == 0 && (*conn).httpversion as i32 == 11 as i32 && (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 == 0 - && (*data).state.httpreq as u32 != HTTPREQ_HEAD as u32 + && (*data).state.httpreq as u32 != HTTPREQ_HEAD as i32 as u32 { Curl_infof( data, @@ -6123,29 +6130,28 @@ pub extern "C" fn Curl_http_readwrite_headers( b"HTTP: No end-of-message indicator\0" as *const u8 as *const libc::c_char, ); - }} + } } - unsafe{ #[cfg(USE_NTLM)] if ((*conn).bits).close() as i32 != 0 && ((*data).req.httpcode == 401 as i32 - && (*conn).http_ntlm_state as u32 == NTLMSTATE_TYPE2 as u32 + && (*conn).http_ntlm_state as u32 == NTLMSTATE_TYPE2 as i32 as u32 || (*data).req.httpcode == 407 as i32 - && (*conn).proxy_ntlm_state as u32 == NTLMSTATE_TYPE2 as u32) + && (*conn).proxy_ntlm_state as u32 == NTLMSTATE_TYPE2 as i32 as u32) { Curl_infof( data, b"Connection closure while negotiating auth (HTTP 1.0?)\0" as *const u8 as *const libc::c_char, ); - (*data).state.set_authproblem(1 as bit); + (*data).state.set_authproblem(1 as i32 as bit); } #[cfg(USE_SPNEGO)] if ((*conn).bits).close() as i32 != 0 && ((*data).req.httpcode == 401 as i32 - && (*conn).http_negotiate_state as u32 == GSS_AUTHRECV as u32 + && (*conn).http_negotiate_state as u32 == GSS_AUTHRECV as i32 as u32 || (*data).req.httpcode == 407 as i32 - && (*conn).proxy_negotiate_state as u32 == GSS_AUTHRECV as u32) + && (*conn).proxy_negotiate_state as u32 == GSS_AUTHRECV as i32 as u32) { Curl_infof( data, @@ -6153,56 +6159,56 @@ pub extern "C" fn Curl_http_readwrite_headers( as *const libc::c_char, ); let ref mut fresh89 = (*data).state; - (*fresh89).set_authproblem(1 as bit); + (*fresh89).set_authproblem(1 as i32 as bit); } #[cfg(USE_SPNEGO)] - if (*conn).http_negotiate_state as u32 == GSS_AUTHDONE as u32 + if (*conn).http_negotiate_state as u32 == GSS_AUTHDONE as i32 as u32 && (*data).req.httpcode != 401 as i32 { (*conn).http_negotiate_state = GSS_AUTHSUCC; } #[cfg(USE_SPNEGO)] - if (*conn).proxy_negotiate_state as u32 == GSS_AUTHDONE as u32 + if (*conn).proxy_negotiate_state as u32 == GSS_AUTHDONE as i32 as u32 && (*data).req.httpcode != 407 as i32 { (*conn).proxy_negotiate_state = GSS_AUTHSUCC; - }} + } writetype = (1 as i32) << 1 as i32; - if unsafe{((*data).set).include_header() != 0 }{ + if ((*data).set).include_header() != 0 { writetype |= (1 as i32) << 0 as i32; } - headerlen =unsafe{ Curl_dyn_len(&mut (*data).state.headerb)}; - result = unsafe{Curl_client_write( + headerlen = Curl_dyn_len(&mut (*data).state.headerb); + result = Curl_client_write( data, writetype, Curl_dyn_ptr(&mut (*data).state.headerb), headerlen, - )}; + ); if result as u64 != 0 { return result; } - unsafe{ (*data).info.header_size += headerlen as i64; - (*data).req.headerbytecount += headerlen as i64;} - if unsafe{http_should_fail(data)} { - unsafe{ Curl_failf( + (*data).info.header_size += headerlen as i64; + (*data).req.headerbytecount += headerlen as i64; + if http_should_fail(data) { + Curl_failf( data, b"The requested URL returned error: %d\0" as *const u8 as *const libc::c_char, (*k).httpcode, - )}; + ); return CURLE_HTTP_RETURNED_ERROR; } - unsafe{(*data).req.deductheadercount = + (*data).req.deductheadercount = if 100 as i32 <= (*k).httpcode && 199 as i32 >= (*k).httpcode { (*data).req.headerbytecount } else { - 0 as i64 - };} - result = unsafe{Curl_http_auth_act(data)}; + 0 as i32 as i64 + }; + result = Curl_http_auth_act(data); if result as u64 != 0 { return result; } - if unsafe{(*k).httpcode >= 300 as i32} {unsafe{ + if (*k).httpcode >= 300 as i32 { if ((*conn).bits).authneg() == 0 && ((*conn).bits).close() == 0 && ((*conn).bits).rewindaftersend() == 0 @@ -6224,17 +6230,17 @@ pub extern "C" fn Curl_http_readwrite_headers( if ((*data).req.newurl).is_null() { } else { __assert_fail( - b"!data->req.newurl\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 4084 as u32, - (*::std::mem::transmute::< - &[u8; 99], - &[libc::c_char; 99], - >( - b"CURLcode Curl_http_readwrite_headers(struct Curl_easy *, struct connectdata *, ssize_t *, _Bool *)\0", - )) - .as_ptr(), - ); + b"!data->req.newurl\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 4084 as i32 as u32, + (*::std::mem::transmute::< + &[u8; 99], + &[libc::c_char; 99], + >( + b"CURLcode Curl_http_readwrite_headers(struct Curl_easy *, struct connectdata *, ssize_t *, _Bool *)\0", + )) + .as_ptr(), + ); } match () { #[cfg(not(CURLDEBUG))] @@ -6289,7 +6295,7 @@ pub extern "C" fn Curl_http_readwrite_headers( if result as u64 != 0 { return result; } - (*k).set_upload_done(1 as bit); + (*k).set_upload_done(1 as i32 as bit); if ((*data).state).expect100header() != 0 { (*k).exp100 = EXP100_FAILED; } @@ -6306,18 +6312,18 @@ pub extern "C" fn Curl_http_readwrite_headers( as *const libc::c_char, ); (*k).keepon |= (1 as i32) << 1 as i32; - }} + } } // 解决clippy错误 - if unsafe{(*k).header() == 0} { + if (*k).header() == 0 { // TODO 待测试 #[cfg(not(CURL_DISABLE_RSTP))] - let flag7: bool = unsafe{((*data).set).opt_no_body() != 0 + let flag7: bool = ((*data).set).opt_no_body() != 0 || (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 - && (*data).set.rtspreq as u32 == RTSPREQ_DESCRIBE as u32 - && (*k).size <= -(1 as i32) as i64}; + && (*data).set.rtspreq as u32 == RTSPREQ_DESCRIBE as i32 as u32 + && (*k).size <= -(1 as i32) as i64; #[cfg(CURL_DISABLE_RSTP)] - let flag7: bool = unsafe{((*data).set).opt_no_body() != 0}; + let flag7: bool = ((*data).set).opt_no_body() != 0; // let flag7: bool = if cfg!(not(CURL_DISABLE_RSTP)) { // ((*data).set).opt_no_body() != 0 // || (*(*conn).handler).protocol @@ -6330,7 +6336,7 @@ pub extern "C" fn Curl_http_readwrite_headers( // ((*data).set).opt_no_body() != 0 // }; if flag7 { - unsafe{ *stop_reading = 1 as i32 != 0;} + *stop_reading = 1 as i32 != 0; // } else if (*(*conn).handler).protocol // & ((1 as i32) << 18 as i32) as u32 // != 0 @@ -6339,51 +6345,51 @@ pub extern "C" fn Curl_http_readwrite_headers( // && (*k).size <= -(1 as i32) as i64 // { // *stop_reading = 1 as i32 != 0; - } else if unsafe{(*k).chunk() != 0} { - unsafe{ let ref mut fresh89 = (*k).size; + } else if (*k).chunk() != 0 { + let ref mut fresh89 = (*k).size; *fresh89 = -(1 as i32) as curl_off_t; - (*k).maxdownload = *fresh89;} + (*k).maxdownload = *fresh89; } - if -(1 as i32) as i64 != unsafe{(*k).size} { - unsafe{ Curl_pgrsSetDownloadSize(data, (*k).size); - (*k).maxdownload = (*k).size;} + if -(1 as i32) as i64 != (*k).size { + Curl_pgrsSetDownloadSize(data, (*k).size); + (*k).maxdownload = (*k).size; } #[cfg(USE_NGHTTP2)] - let flag8: bool = unsafe{0 as i64 == (*k).maxdownload + let flag8: bool = 0 as i32 as i64 == (*k).maxdownload && !((*(*conn).handler).protocol & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32) as u32 != 0 - && (*conn).httpversion as i32 == 20 as i32)}; + && (*conn).httpversion as i32 == 20 as i32); #[cfg(not(USE_NGHTTP2))] - let flag8: bool = 0 as i64 ==unsafe{ (*k).maxdownload}; + let flag8: bool = 0 as i32 as i64 == (*k).maxdownload; if flag8 { - unsafe{ *stop_reading = 1 as i32 != 0;} + *stop_reading = 1 as i32 != 0; } - if unsafe{*stop_reading} { - unsafe{ (*k).keepon &= !((1 as i32) << 0 as i32);} + if *stop_reading { + (*k).keepon &= !((1 as i32) << 0 as i32); } - unsafe{Curl_debug(data, CURLINFO_HEADER_IN, str_start, headerlen);} + Curl_debug(data, CURLINFO_HEADER_IN, str_start, headerlen); break; } else { - unsafe{ Curl_dyn_reset(&mut (*data).state.headerb);} + Curl_dyn_reset(&mut (*data).state.headerb); } } else { - let ref mut fresh90 = unsafe{(*k).headerline}; + let ref mut fresh90 = (*k).headerline; let fresh91 = *fresh90; *fresh90 = *fresh90 + 1; if fresh91 == 0 { let mut httpversion_major: i32 = 0; let mut rtspversion_major: i32 = 0; let mut nc: i32 = 0 as i32; - if unsafe{(*(*conn).handler).protocol} + if (*(*conn).handler).protocol & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32) as u32 != 0 { let mut separator: libc::c_char = 0; let mut twoorthree: [libc::c_char; 2] = [0; 2]; let mut httpversion: i32 = 0 as i32; - let mut digit4: libc::c_char = 0 as libc::c_char; - nc = unsafe{sscanf( + let mut digit4: libc::c_char = 0 as i32 as libc::c_char; + nc = sscanf( headp, b" HTTP/%1d.%1d%c%3d%c\0" as *const u8 as *const libc::c_char, &mut httpversion_major as *mut i32, @@ -6391,164 +6397,165 @@ pub extern "C" fn Curl_http_readwrite_headers( &mut separator as *mut libc::c_char, &mut (*k).httpcode as *mut i32, &mut digit4 as *mut libc::c_char, - )}; + ); if nc == 1 as i32 && httpversion_major >= 2 as i32 && 2 as i32 - == unsafe{sscanf( + == sscanf( headp, b" HTTP/%1[23] %d\0" as *const u8 as *const libc::c_char, twoorthree.as_mut_ptr(), &mut (*k).httpcode as *mut i32, - )} + ) { - unsafe{(*conn).httpversion = 0 as u8;} + (*conn).httpversion = 0 as i32 as u8; nc = 4 as i32; - separator = ' ' as libc::c_char; - } else if unsafe{Curl_isdigit(digit4 as i32) != 0} { - unsafe{ Curl_failf( + separator = ' ' as i32 as libc::c_char; + } else if Curl_isdigit(digit4 as u8 as i32) != 0 { + Curl_failf( data, b"Unsupported response code in HTTP response\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_UNSUPPORTED_PROTOCOL; } if nc >= 4 as i32 && ' ' as i32 == separator as i32 { httpversion += 10 as i32 * httpversion_major; match httpversion { 10 | 11 => { - unsafe{(*conn).httpversion = httpversion as u8;} + (*conn).httpversion = httpversion as u8; } #[cfg(any(USE_NGHTTP2, USE_HYPER))] 20 => { - unsafe{(*conn).httpversion = httpversion as u8;} + (*conn).httpversion = httpversion as u8; } #[cfg(ENABLE_QUIC)] 30 => { - unsafe{(*conn).httpversion = httpversion as u8;} + (*conn).httpversion = httpversion as u8; } _ => { - unsafe{Curl_failf( + Curl_failf( data, b"Unsupported HTTP version (%u.%d) in response\0" as *const u8 as *const libc::c_char, httpversion / 10 as i32, httpversion % 10 as i32, - );} + ); return CURLE_UNSUPPORTED_PROTOCOL; } } - if unsafe{(*k).upgr101 as u32 == UPGR101_RECEIVED as u32} { - if unsafe{(*conn).httpversion as i32 != 20 as i32} { - unsafe{Curl_infof( + if (*k).upgr101 as u32 == UPGR101_RECEIVED as i32 as u32 { + if (*conn).httpversion as i32 != 20 as i32 { + Curl_infof( data, b"Lying server, not serving HTTP/2\0" as *const u8 as *const libc::c_char, - );} + ); } } - if unsafe{((*conn).httpversion as i32) < 20 as i32} { - unsafe{ (*(*conn).bundle).multiuse = -(1 as i32); + if ((*conn).httpversion as i32) < 20 as i32 { + (*(*conn).bundle).multiuse = -(1 as i32); Curl_infof( data, b"Mark bundle as not supporting multiuse\0" as *const u8 as *const libc::c_char, - );} + ); } } else if nc == 0 { - nc = unsafe{sscanf( + nc = sscanf( headp, b" HTTP %3d\0" as *const u8 as *const libc::c_char, &mut (*k).httpcode as *mut i32, - )}; - unsafe{(*conn).httpversion = 10 as u8;} + ); + (*conn).httpversion = 10 as i32 as u8; if nc == 0 { - let mut check: statusline = unsafe{checkhttpprefix( + let mut check: statusline = checkhttpprefix( data, Curl_dyn_ptr(&mut (*data).state.headerb), Curl_dyn_len(&mut (*data).state.headerb), - )}; - if check as u32 == STATUS_DONE as u32 { + ); + if check as u32 == STATUS_DONE as i32 as u32 { nc = 1 as i32; - unsafe{(*k).httpcode = 200 as i32; - (*conn).httpversion = 10 as u8;} + (*k).httpcode = 200 as i32; + (*conn).httpversion = 10 as i32 as u8; } } } else { - unsafe{Curl_failf( + Curl_failf( data, b"Unsupported HTTP version in response\0" as *const u8 as *const libc::c_char, - );} + ); return CURLE_UNSUPPORTED_PROTOCOL; } - } else if unsafe{(*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0} { + } else if (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 { let mut separator_0: libc::c_char = 0; let mut rtspversion: i32 = 0; - nc = unsafe{sscanf( + nc = sscanf( headp, b" RTSP/%1d.%1d%c%3d\0" as *const u8 as *const libc::c_char, &mut rtspversion_major as *mut i32, &mut rtspversion as *mut i32, &mut separator_0 as *mut libc::c_char, &mut (*k).httpcode as *mut i32, - )}; + ); if nc == 4 as i32 && ' ' as i32 == separator_0 as i32 { - unsafe{ (*conn).httpversion = 11 as u8;} + (*conn).httpversion = 11 as i32 as u8; } else { nc = 0 as i32; } } if nc != 0 { - result = unsafe{Curl_http_statusline(data, conn)}; + result = Curl_http_statusline(data, conn); if result as u64 != 0 { return result; } } else { - unsafe{ (*k).set_header(0 as bit);} + (*k).set_header(0 as i32 as bit); break; } } - result = CURLE_OK as CURLcode; + result = CURLE_OK as i32 as CURLcode; if result as u64 != 0 { return result; } - result = unsafe{Curl_http_header(data, conn, headp)}; + result = Curl_http_header(data, conn, headp); if result as u64 != 0 { return result; } writetype = (1 as i32) << 1 as i32; - if unsafe{((*data).set).include_header() != 0} { + if ((*data).set).include_header() != 0 { writetype |= (1 as i32) << 0 as i32; } - unsafe{Curl_debug( + Curl_debug( data, CURLINFO_HEADER_IN, headp, Curl_dyn_len(&mut (*data).state.headerb), - );} - result = unsafe{Curl_client_write( + ); + result = Curl_client_write( data, writetype, headp, Curl_dyn_len(&mut (*data).state.headerb), - )}; + ); if result as u64 != 0 { return result; } - unsafe{(*data).info.header_size = ((*data).info.header_size as u64) + (*data).info.header_size = ((*data).info.header_size as u64) .wrapping_add(Curl_dyn_len(&mut (*data).state.headerb)) - as curl_off_t; + as curl_off_t as curl_off_t; (*data).req.headerbytecount = ((*data).req.headerbytecount as u64) .wrapping_add(Curl_dyn_len(&mut (*data).state.headerb)) - as curl_off_t; - Curl_dyn_reset(&mut (*data).state.headerb);} + as curl_off_t as curl_off_t; + Curl_dyn_reset(&mut (*data).state.headerb); } - if unsafe{!(*(*k).str_0 != 0)} { + if !(*(*k).str_0 != 0) { break; } } } +} return CURLE_OK; } diff --git a/rust/rust_project/src/http2.rs b/rust/rust_project/src/http2.rs index abd75d6..0d654fa 100644 --- a/rust/rust_project/src/http2.rs +++ b/rust/rust_project/src/http2.rs @@ -83,14 +83,14 @@ fn HEADER_OVERFLOW(nva: nghttp2_nv) -> bool { pub extern "C" fn Curl_http2_init_state(mut state: *mut UrlState) { unsafe { (*state).stream_weight = NGHTTP2_DEFAULT_WEIGHT; -} + } } #[cfg(USE_NGHTTP2)] #[no_mangle] pub extern "C" fn Curl_http2_init_userset(mut set: *mut UserDefined) { unsafe { (*set).stream_weight = NGHTTP2_DEFAULT_WEIGHT; -} + } } #[cfg(USE_NGHTTP2)] @@ -119,44 +119,43 @@ extern "C" fn http2_getsock( #[cfg(USE_NGHTTP2)] extern "C" fn http2_stream_free(http: *mut HTTP) { - if !http.is_null() { - unsafe {Curl_dyn_free( &mut (*http).header_recvbuf)}; - while unsafe { (*http).push_headers_used } > 0 { - unsafe { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( + unsafe { Curl_dyn_free(&mut (*http).header_recvbuf) }; + while unsafe { (*http).push_headers_used } > 0 { + unsafe { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( *((*http).push_headers) .offset(((*http).push_headers_used).wrapping_sub(1) as isize) as *mut libc::c_void, + ); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + *((*http).push_headers).offset( + ((*http).push_headers_used).wrapping_sub(1 as libc::c_int as libc::c_ulong) + as isize, + ) as *mut libc::c_void, + 127 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ); + (*http).push_headers_used = (*http).push_headers_used.wrapping_sub(1); + } + } + unsafe { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*http).push_headers as *mut libc::c_void, ); - #[cfg(CURLDEBUG)] curl_dbg_free( - *((*http).push_headers) - .offset( - ((*http).push_headers_used) - .wrapping_sub(1 as libc::c_int as libc::c_ulong) as isize, - ) as *mut libc::c_void, - 127 as libc::c_int, + (*http).push_headers as *mut libc::c_void, + 129 as libc::c_int, b"http2.c\0" as *const u8 as *const libc::c_char, ); - (*http).push_headers_used = (*http).push_headers_used.wrapping_sub(1) ;} + (*http).push_headers = 0 as *mut *mut i8; } - unsafe { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*http).push_headers as *mut libc::c_void , - ); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*http).push_headers as *mut libc::c_void, - 129 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ); - (*http).push_headers = 0 as *mut *mut i8; } } } #[cfg(USE_NGHTTP2)] @@ -167,19 +166,19 @@ extern "C" fn http2_disconnect( ) -> CURLcode { unsafe { let c: *mut http_conn = &mut (*conn).proto.httpc; - nghttp2_session_del((*c).h2); - #[cfg(not(CURLDEBUG))] + nghttp2_session_del((*c).h2); + #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")((*c).inbuf as *mut libc::c_void); - #[cfg(CURLDEBUG)] + #[cfg(CURLDEBUG)] curl_dbg_free( (*c).inbuf as *mut libc::c_void, 152 as libc::c_int, b"http2.c\0" as *const u8 as *const libc::c_char, ); (*c).inbuf = 0 as *mut i8; - return CURLE_OK; -} + return CURLE_OK; + } } #[cfg(USE_NGHTTP2)] @@ -187,9 +186,9 @@ extern "C" fn http2_connisdead(data: *mut Curl_easy, conn: *mut connectdata) -> unsafe { let mut sval: i32 = 0; let mut dead: bool = true; - if ((*conn).bits).close() != 0 { + if ((*conn).bits).close() != 0 { return true; - } + } sval = Curl_socket_check((*conn).sock[FIRSTSOCKET], -1, -1, 0 as timediff_t); if sval == 0 { /* timeout */ @@ -199,47 +198,47 @@ extern "C" fn http2_connisdead(data: *mut Curl_easy, conn: *mut connectdata) -> dead = true; } else if sval & CURL_CSELECT_IN != 0 { /* readable with no error. could still be closed */ - dead = !Curl_connalive(conn); - if !dead { + dead = !Curl_connalive(conn); + if !dead { /* This happens before we've sent off a request and the connection is not in use by any other transfer, there shouldn't be any data here, only "protocol frames" */ - let mut result: CURLcode = CURLE_OK; - let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; + let mut result: CURLcode = CURLE_OK; + let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; let mut nread: ssize_t = -1; - if ((*httpc).recv_underlying).is_some() { + if ((*httpc).recv_underlying).is_some() { /* if called "too early", this pointer isn't setup yet! */ nread = ((*httpc).recv_underlying).expect("non-null function pointer")( - data, + data, FIRSTSOCKET as i32, - (*httpc).inbuf, + (*httpc).inbuf, H2_BUFSIZE, - &mut result, - ); - } + &mut result, + ); + } if nread != -1 { - Curl_infof( - data, + Curl_infof( + data, b"%d bytes stray data read before trying h2 connection\0" as *const u8 as *const i8, nread, - ); + ); (*httpc).nread_inbuf = 0; - (*httpc).inbuflen = nread as size_t; + (*httpc).inbuflen = nread as size_t; if h2_process_pending_input(data, httpc, &mut result) < 0 { /* immediate error, considered dead */ dead = true; - } - } else { + } + } else { /* the read failed so let's say this is dead anyway */ dead = true; + } } } + return dead; } - return dead; -} } /* @@ -249,27 +248,27 @@ extern "C" fn http2_connisdead(data: *mut Curl_easy, conn: *mut connectdata) -> extern "C" fn set_transfer(c: *mut http_conn, data: *mut Curl_easy) { unsafe { (*c).trnsfr = data; -} + } } #[cfg(USE_NGHTTP2)] extern "C" fn get_transfer(mut c: *mut http_conn) -> *mut Curl_easy { unsafe { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !c.is_null() && !((*c).trnsfr).is_null() {} else { - __assert_fail( - b"c && c->trnsfr\0" as *const u8 as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 230 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 51], - &[libc::c_char; 51], - >(b"struct Curl_easy *get_transfer(struct http_conn *)\0")) + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !c.is_null() && !((*c).trnsfr).is_null() { + } else { + __assert_fail( + b"c && c->trnsfr\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 230 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 51], &[libc::c_char; 51]>( + b"struct Curl_easy *get_transfer(struct http_conn *)\0", + )) .as_ptr(), - ); + ); + } + return (*c).trnsfr; } - return (*c).trnsfr; -} } #[cfg(USE_NGHTTP2)] @@ -285,45 +284,45 @@ extern "C" fn http2_conncheck( unsafe { if checks_to_perform & CONNCHECK_ISDEAD != 0 { - if http2_connisdead(data, conn) { + if http2_connisdead(data, conn) { ret_val |= CONNRESULT_DEAD; + } } - } if checks_to_perform & CONNCHECK_KEEPALIVE != 0 { let now: curltime = Curl_now(); let elapsed: timediff_t = Curl_timediff(now, (*conn).keepalive); - if elapsed > (*data).set.upkeep_interval_ms { + if elapsed > (*data).set.upkeep_interval_ms { /* Perform an HTTP/2 PING */ rc = nghttp2_submit_ping((*c).h2, 0 as uint8_t, ZERO_NULL); - if rc == 0 { + if rc == 0 { /* Successfully added a PING frame to the session. Need to flag this so the frame is sent. */ send_frames = true; - } else { + } else { + Curl_failf( + data, + b"nghttp2_submit_ping() failed: %s(%d)\0" as *const u8 as *const i8, + nghttp2_strerror(rc), + rc, + ); + } + (*conn).keepalive = now; + } + } + if send_frames { + set_transfer(c, data); /* set the transfer */ + rc = nghttp2_session_send((*c).h2); + if rc != 0 { Curl_failf( data, - b"nghttp2_submit_ping() failed: %s(%d)\0" as *const u8 as *const i8, + b"nghttp2_session_send() failed: %s(%d)\0" as *const u8 as *const i8, nghttp2_strerror(rc), rc, ); } - (*conn).keepalive = now; - } - } - if send_frames { - set_transfer(c, data); /* set the transfer */ - rc = nghttp2_session_send((*c).h2); - if rc != 0 { - Curl_failf( - data, - b"nghttp2_session_send() failed: %s(%d)\0" as *const u8 as *const i8, - nghttp2_strerror(rc), - rc, - ); } + return ret_val; } - return ret_val; -} } /* called from http_setup_conn */ @@ -331,7 +330,7 @@ extern "C" fn http2_conncheck( #[no_mangle] pub extern "C" fn Curl_http2_setup_req(data: *mut Curl_easy) { unsafe { - let mut http: *mut HTTP = (*data).req.p.http; + let mut http: *mut HTTP = (*data).req.p.http; (*http).bodystarted = false; (*http).status_code = -1; (*http).pausedata = 0 as *const uint8_t; @@ -342,7 +341,7 @@ pub extern "C" fn Curl_http2_setup_req(data: *mut Curl_easy) { (*http).len = 0; (*http).memlen = 0; (*http).error = NGHTTP2_NO_ERROR; -} + } } /* called from http_setup_conn */ @@ -351,7 +350,7 @@ pub extern "C" fn Curl_http2_setup_req(data: *mut Curl_easy) { pub extern "C" fn Curl_http2_setup_conn(mut conn: *mut connectdata) { unsafe { (*conn).proto.httpc.settings.max_concurrent_streams = DEFAULT_MAX_CONCURRENT_STREAMS; -} + } } /* @@ -364,49 +363,49 @@ static mut Curl_handler_http2: Curl_handler = Curl_handler { /* scheme */ scheme: b"HTTP\0" as *const u8 as *const i8, /* setup_connection */ - setup_connection: None, + setup_connection: None, /* do_it */ do_it: Some(Curl_http as unsafe extern "C" fn(*mut Curl_easy, *mut bool) -> CURLcode), /* done */ done: Some(Curl_http_done as unsafe extern "C" fn(*mut Curl_easy, CURLcode, bool) -> CURLcode), /* do_more */ - do_more: None, + do_more: None, /* connect_it */ - connect_it: None, + connect_it: None, /* connecting */ - connecting: None, + connecting: None, /* doing */ - doing: None, + doing: None, /* proto_getsock */ - proto_getsock: Some( - http2_getsock + proto_getsock: Some( + http2_getsock as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, *mut curl_socket_t) -> i32, - ), + ), /* doing_getsock */ - doing_getsock: Some( - http2_getsock + doing_getsock: Some( + http2_getsock as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, *mut curl_socket_t) -> i32, - ), + ), /* domore_getsock */ - domore_getsock: None, + domore_getsock: None, /* perform_getsock */ - perform_getsock: Some( - http2_getsock + perform_getsock: Some( + http2_getsock as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, *mut curl_socket_t) -> i32, - ), + ), /* disconnect */ - disconnect: Some( - http2_disconnect + disconnect: Some( + http2_disconnect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, bool) -> CURLcode, - ), + ), /* readwrite */ - readwrite: None, + readwrite: None, /* connection_check */ - connection_check: Some( + connection_check: Some( http2_conncheck as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, u32) -> u32, - ), + ), /* attach connection */ - attach: None, + attach: None, /* defport */ defport: PORT_HTTP, /* protocol */ @@ -415,56 +414,56 @@ static mut Curl_handler_http2: Curl_handler = Curl_handler { family: CURLPROTO_HTTP, /* flags */ flags: PROTOPT_STREAM, - }; +}; #[cfg(USE_NGHTTP2)] static mut Curl_handler_http2_ssl: Curl_handler = Curl_handler { /* scheme */ scheme: b"HTTPS\0" as *const u8 as *const i8, /* setup_connection */ - setup_connection: None, + setup_connection: None, /* do_it */ do_it: Some(Curl_http as unsafe extern "C" fn(*mut Curl_easy, *mut bool) -> CURLcode), /* done */ done: Some(Curl_http_done as unsafe extern "C" fn(*mut Curl_easy, CURLcode, bool) -> CURLcode), /* do_more */ - do_more: None, + do_more: None, /* connect_it */ - connect_it: None, + connect_it: None, /* connecting */ - connecting: None, + connecting: None, /* doing */ - doing: None, + doing: None, /* proto_getsock */ - proto_getsock: Some( - http2_getsock + proto_getsock: Some( + http2_getsock as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, *mut curl_socket_t) -> i32, - ), + ), /* doing_getsock */ - doing_getsock: Some( - http2_getsock + doing_getsock: Some( + http2_getsock as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, *mut curl_socket_t) -> i32, - ), + ), /* domore_getsock */ - domore_getsock: None, + domore_getsock: None, /* perform_getsock */ - perform_getsock: Some( - http2_getsock + perform_getsock: Some( + http2_getsock as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, *mut curl_socket_t) -> i32, - ), + ), /* disconnect */ - disconnect: Some( - http2_disconnect + disconnect: Some( + http2_disconnect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, bool) -> CURLcode, - ), + ), /* readwrite */ - readwrite: None, + readwrite: None, /* connection_check */ - connection_check: Some( + connection_check: Some( http2_conncheck as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, u32) -> u32, - ), + ), /* attach connection */ - attach: None, + attach: None, /* defport */ defport: PORT_HTTP, /* protocol */ @@ -473,7 +472,7 @@ static mut Curl_handler_http2_ssl: Curl_handler = Curl_handler { family: CURLPROTO_HTTP, /* flags */ flags: PROTOPT_SSL | PROTOPT_STREAM, - }; +}; /* * Store nghttp2 version info in this buffer. @@ -483,13 +482,13 @@ static mut Curl_handler_http2_ssl: Curl_handler = Curl_handler { pub extern "C" fn Curl_http2_ver(p: *mut i8, len: size_t) { unsafe { let h2: *mut nghttp2_info = nghttp2_version(0); - curl_msnprintf( - p, - len, + curl_msnprintf( + p, + len, b"nghttp2/%s\0" as *const u8 as *const i8, - (*h2).version_str, - ); -} + (*h2).version_str, + ); + } } /* @@ -509,11 +508,11 @@ extern "C" fn send_callback( let conn: *mut connectdata = userp as *mut connectdata; let c: *mut http_conn = &mut (*conn).proto.httpc; let data: *mut Curl_easy = get_transfer(c); - let mut written: ssize_t = 0; - let mut result: CURLcode = CURLE_OK; - if ((*c).send_underlying).is_none() { + let mut written: ssize_t = 0; + let mut result: CURLcode = CURLE_OK; + if ((*c).send_underlying).is_none() { return NGHTTP2_ERR_CALLBACK_FAILURE as ssize_t; - } + } written = ((*c).send_underlying).expect("non-null function pointer")( data, FIRSTSOCKET as i32, @@ -523,19 +522,19 @@ extern "C" fn send_callback( ); if result == CURLE_AGAIN { return NGHTTP2_ERR_WOULDBLOCK as ssize_t; - } + } if written == -1 { - Curl_failf( - data, + Curl_failf( + data, b"Failed sending HTTP2 data\0" as *const u8 as *const i8, - ); + ); return NGHTTP2_ERR_CALLBACK_FAILURE as ssize_t; - } - if written == 0 { + } + if written == 0 { return NGHTTP2_ERR_WOULDBLOCK as ssize_t; + } + return written; } - return written; -} } /* @@ -549,14 +548,14 @@ pub extern "C" fn curl_pushheader_bynum(h: *mut curl_pushheaders, num: size_t) - detect rubbish input fast(er). */ if h.is_null() || !GOOD_EASY_HANDLE((*h).data) { return 0 as *mut i8; - } else { + } else { let stream: *mut HTTP = (*(*h).data).req.p.http; - if num < (*stream).push_headers_used { - return *((*stream).push_headers).offset(num as isize); + if num < (*stream).push_headers_used { + return *((*stream).push_headers).offset(num as isize); + } } - } return 0 as *mut i8; -} + } } /* @@ -572,36 +571,36 @@ pub extern "C" fn curl_pushheader_byname(h: *mut curl_pushheaders, header: *cons the header, but header == ":" must be rejected. If we have ':' in the middle of header, it could be matched in middle of the value, this is because we do prefix match.*/ - if h.is_null() + if h.is_null() || !(!((*h).data).is_null() && GOOD_EASY_HANDLE((*h).data)) || header.is_null() || *header.offset(0) == 0 || strcmp(header, b":\0" as *const u8 as *const i8) == 0 || !(strchr(header.offset(1), ':' as i32)).is_null() - { + { return 0 as *mut i8; - } else { + } else { let stream: *mut HTTP = (*(*h).data).req.p.http; let len: size_t = strlen(header); - let mut i: size_t = 0; + let mut i: size_t = 0; i = 0 as size_t; - while i < (*stream).push_headers_used { - if strncmp(header, *((*stream).push_headers).offset(i as isize), len) == 0 { + while i < (*stream).push_headers_used { + if strncmp(header, *((*stream).push_headers).offset(i as isize), len) == 0 { /* sub-match, make sure that it is followed by a colon */ - if !(*(*((*stream).push_headers).offset(i as isize)).offset(len as isize) + if !(*(*((*stream).push_headers).offset(i as isize)).offset(len as isize) as i32 != ':' as i32) - { - return &mut *(*((*stream).push_headers).offset(i as isize)) + { + return &mut *(*((*stream).push_headers).offset(i as isize)) .offset(len.wrapping_add(1 as u64) as isize) as *mut i8; + } } + i = i.wrapping_add(1); } - i = i.wrapping_add(1); } - } return 0 as *mut i8; -} + } } /* @@ -614,19 +613,18 @@ extern "C" fn drained_transfer(mut data: *mut Curl_easy, httpc: *mut http_conn) ((*httpc).drain_total as u64).wrapping_sub((*data).state.drain) as size_t; (*data).state.drain = 0; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*httpc).drain_total >= (*data).state.drain {} else { - __assert_fail( - b"httpc->drain_total >= data->state.drain\0" as *const u8 - as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 464 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 62], - &[libc::c_char; 62], - >(b"void drained_transfer(struct Curl_easy *, struct http_conn *)\0")) + if (*httpc).drain_total >= (*data).state.drain { + } else { + __assert_fail( + b"httpc->drain_total >= data->state.drain\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 464 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 62], &[libc::c_char; 62]>( + b"void drained_transfer(struct Curl_easy *, struct http_conn *)\0", + )) .as_ptr(), - ); - } + ); + } } } @@ -639,72 +637,71 @@ extern "C" fn drain_this(data: *mut Curl_easy, httpc: *mut http_conn) { (*data).state.drain = (*data).state.drain.wrapping_add(1); (*httpc).drain_total = (*httpc).drain_total.wrapping_add(1); #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*httpc).drain_total >= (*data).state.drain {} else { + if (*httpc).drain_total >= (*data).state.drain { + } else { __assert_fail( - b"httpc->drain_total >= data->state.drain\0" as *const u8 - as *const libc::c_char, + b"httpc->drain_total >= data->state.drain\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 477 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 56], - &[libc::c_char; 56], - >(b"void drain_this(struct Curl_easy *, struct http_conn *)\0")) - .as_ptr(), + (*::std::mem::transmute::<&[u8; 56], &[libc::c_char; 56]>( + b"void drain_this(struct Curl_easy *, struct http_conn *)\0", + )) + .as_ptr(), ); }; -} + } } #[cfg(USE_NGHTTP2)] extern "C" fn duphandle(data: *mut Curl_easy) -> *mut Curl_easy { unsafe { - let mut second: *mut Curl_easy = curl_easy_duphandle(data); - if !second.is_null() { - /* setup the request struct */ - #[cfg(not(CURLDEBUG))] - let http: *mut HTTP = Curl_ccalloc.expect("non-null function pointer")( - 1, - ::std::mem::size_of::() as u64, - ) as *mut HTTP; - #[cfg(CURLDEBUG)] - let mut http: *mut HTTP = curl_dbg_calloc( - 1 as libc::c_int as size_t, - ::std::mem::size_of::() as libc::c_ulong, - 485 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ) as *mut HTTP; - if http.is_null() { - Curl_close(&mut second); - } else { + let mut second: *mut Curl_easy = curl_easy_duphandle(data); + if !second.is_null() { + /* setup the request struct */ + #[cfg(not(CURLDEBUG))] + let http: *mut HTTP = Curl_ccalloc.expect("non-null function pointer")( + 1, + ::std::mem::size_of::() as u64, + ) as *mut HTTP; + #[cfg(CURLDEBUG)] + let mut http: *mut HTTP = curl_dbg_calloc( + 1 as libc::c_int as size_t, + ::std::mem::size_of::() as libc::c_ulong, + 485 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ) as *mut HTTP; + if http.is_null() { + Curl_close(&mut second); + } else { (*second).req.p.http = http; Curl_dyn_init(&mut (*http).header_recvbuf, DYN_H2_HEADERS); - Curl_http2_setup_req(second); - (*second).state.stream_weight = (*data).state.stream_weight; + Curl_http2_setup_req(second); + (*second).state.stream_weight = (*data).state.stream_weight; + } } + return second; } - return second; -} } #[cfg(USE_NGHTTP2)] extern "C" fn set_transfer_url(data: *mut Curl_easy, hp: *mut curl_pushheaders) -> i32 { unsafe { - let mut current_block: u64; + let mut current_block: u64; let mut v: *const i8 = 0 as *const i8; let u: *mut CURLU = curl_url(); - let mut uc: CURLUcode = CURLUE_OK; + let mut uc: CURLUcode = CURLUE_OK; let mut url: *mut i8 = 0 as *mut i8; let mut rc: i32 = 0; v = curl_pushheader_byname(hp, b":scheme\0" as *const u8 as *const i8); 'fail: loop { - if !v.is_null() { + if !v.is_null() { uc = curl_url_set(u, CURLUPART_SCHEME, v, 0); if uc != 0 { rc = 1; break 'fail; - } - } + } + } v = curl_pushheader_byname(hp, b":authority\0" as *const u8 as *const i8); if !v.is_null() { uc = curl_url_set(u, CURLUPART_HOST, v, 0); @@ -714,39 +711,39 @@ extern "C" fn set_transfer_url(data: *mut Curl_easy, hp: *mut curl_pushheaders) } } v = curl_pushheader_byname(hp, b":path\0" as *const u8 as *const i8); - if !v.is_null() { + if !v.is_null() { uc = curl_url_set(u, CURLUPART_PATH, v, 0); if uc != 0 { rc = 3; break 'fail; - } - } + } + } uc = curl_url_get(u, CURLUPART_URL, &mut url, 0); if uc != 0 { rc = 4; - } + } break 'fail; - } + } - curl_url_cleanup(u); - if rc != 0 { - return rc; - } - if ((*data).state).url_alloc() != 0 { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")((*data).state.url as *mut libc::c_void); + curl_url_cleanup(u); + if rc != 0 { + return rc; + } + if ((*data).state).url_alloc() != 0 { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")((*data).state.url as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.url as *mut libc::c_void, - 544 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ); - } + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.url as *mut libc::c_void, + 544 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ); + } ((*data).state).set_url_alloc(1 as bit); (*data).state.url = url; return 0; -} + } } #[cfg(USE_NGHTTP2)] @@ -758,32 +755,32 @@ extern "C" fn push_promise( unsafe { let mut rv: i32 = 0; /* one of the CURL_PUSH_* defines */ 'fail: loop { - if ((*(*data).multi).push_cb).is_some() { - let mut stream: *mut HTTP = 0 as *mut HTTP; - let mut newstream: *mut HTTP = 0 as *mut HTTP; - let mut heads: curl_pushheaders = curl_pushheaders { - data: 0 as *mut Curl_easy, - frame: 0 as *const nghttp2_push_promise, - }; - let mut rc: CURLMcode = CURLM_OK; - let mut httpc: *mut http_conn = 0 as *mut http_conn; - let mut i: size_t = 0; + if ((*(*data).multi).push_cb).is_some() { + let mut stream: *mut HTTP = 0 as *mut HTTP; + let mut newstream: *mut HTTP = 0 as *mut HTTP; + let mut heads: curl_pushheaders = curl_pushheaders { + data: 0 as *mut Curl_easy, + frame: 0 as *const nghttp2_push_promise, + }; + let mut rc: CURLMcode = CURLM_OK; + let mut httpc: *mut http_conn = 0 as *mut http_conn; + let mut i: size_t = 0; /* clone the parent */ - let mut newhandle: *mut Curl_easy = duphandle(data); - if newhandle.is_null() { - Curl_infof( - data, + let mut newhandle: *mut Curl_easy = duphandle(data); + if newhandle.is_null() { + Curl_infof( + data, b"failed to duplicate handle\0" as *const u8 as *const i8, - ); + ); rv = CURL_PUSH_DENY; /* FAIL HARD */ break 'fail; } - heads.data = data; - heads.frame = frame; - stream = (*data).req.p.http; - if stream.is_null() { + heads.data = data; + heads.frame = frame; + stream = (*data).req.p.http; + if stream.is_null() { Curl_failf(data, b"Internal NULL stream!\0" as *const u8 as *const i8); - Curl_close(&mut newhandle); + Curl_close(&mut newhandle); rv = CURL_PUSH_DENY; break 'fail; } @@ -795,46 +792,46 @@ extern "C" fn push_promise( } Curl_set_in_callback(data, 1 != 0); rv = ((*(*data).multi).push_cb).expect("non-null function pointer")( - data, - newhandle, - (*stream).push_headers_used, - &mut heads, - (*(*data).multi).push_userp, - ); + data, + newhandle, + (*stream).push_headers_used, + &mut heads, + (*(*data).multi).push_userp, + ); Curl_set_in_callback(data, 0 != 0); /* free the headers again */ i = 0; - while i < (*stream).push_headers_used { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - *((*stream).push_headers).offset(i as isize) as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - *((*stream).push_headers).offset(i as isize) - as *mut libc::c_void, - 600 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ); - i = i.wrapping_add(1); - } + while i < (*stream).push_headers_used { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( - (*stream).push_headers as *mut libc::c_void, + *((*stream).push_headers).offset(i as isize) as *mut libc::c_void, ); - #[cfg(CURLDEBUG)] + #[cfg(CURLDEBUG)] curl_dbg_free( - (*stream).push_headers as *mut libc::c_void, - 601 as libc::c_int, + *((*stream).push_headers).offset(i as isize) as *mut libc::c_void, + 600 as libc::c_int, b"http2.c\0" as *const u8 as *const libc::c_char, ); - (*stream).push_headers = 0 as *mut *mut i8; + i = i.wrapping_add(1); + } + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*stream).push_headers as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*stream).push_headers as *mut libc::c_void, + 601 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ); + (*stream).push_headers = 0 as *mut *mut i8; (*stream).push_headers_used = 0; - if rv != 0 { + if rv != 0 { /* denied, kill off the new handle again */ #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if rv > 0 as libc::c_int && rv <= 2 as libc::c_int {} else { - __assert_fail( + if rv > 0 as libc::c_int && rv <= 2 as libc::c_int { + } else { + __assert_fail( b"(rv > 0) && (rv <= 2)\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, @@ -847,47 +844,47 @@ extern "C" fn push_promise( )) .as_ptr(), ); - } - http2_stream_free((*newhandle).req.p.http); + } + http2_stream_free((*newhandle).req.p.http); (*newhandle).req.p.http = 0 as *mut HTTP; - Curl_close(&mut newhandle); + Curl_close(&mut newhandle); break 'fail; } - newstream = (*newhandle).req.p.http; - (*newstream).stream_id = (*frame).promised_stream_id; + newstream = (*newhandle).req.p.http; + (*newstream).stream_id = (*frame).promised_stream_id; (*newhandle).req.maxdownload = -1 as curl_off_t; (*newhandle).req.size = -1 as curl_off_t; /* approved, add to the multi handle and immediately switch to PERFORM state with the given connection !*/ - rc = Curl_multi_add_perform((*data).multi, newhandle, conn); - if rc as u64 != 0 { - Curl_infof( - data, + rc = Curl_multi_add_perform((*data).multi, newhandle, conn); + if rc as u64 != 0 { + Curl_infof( + data, b"failed to add handle to multi\0" as *const u8 as *const i8, - ); - http2_stream_free((*newhandle).req.p.http); + ); + http2_stream_free((*newhandle).req.p.http); (*newhandle).req.p.http = 0 as *mut HTTP; - Curl_close(&mut newhandle); + Curl_close(&mut newhandle); rv = CURL_PUSH_DENY; break 'fail; } - httpc = &mut (*conn).proto.httpc; - rv = nghttp2_session_set_stream_user_data( - (*httpc).h2, - (*frame).promised_stream_id, - newhandle as *mut libc::c_void, - ); + httpc = &mut (*conn).proto.httpc; + rv = nghttp2_session_set_stream_user_data( + (*httpc).h2, + (*frame).promised_stream_id, + newhandle as *mut libc::c_void, + ); - if rv != 0 { - Curl_infof( - data, + if rv != 0 { + Curl_infof( + data, b"failed to set user_data for stream %d\0" as *const u8 as *const i8, - (*frame).promised_stream_id, - ); - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + (*frame).promised_stream_id, + ); + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] __assert_fail( b"0\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, @@ -905,14 +902,14 @@ extern "C" fn push_promise( } Curl_dyn_init(&mut (*newstream).header_recvbuf, DYN_H2_HEADERS as size_t); Curl_dyn_init(&mut (*newstream).trailer_recvbuf, DYN_H2_TRAILERS as size_t); - } else { + } else { rv = CURL_PUSH_DENY; - } + } break 'fail; - } + } return rv; - } - } + } +} /* * multi_connchanged() is called to tell that there is a connection in @@ -925,8 +922,8 @@ extern "C" fn push_promise( extern "C" fn multi_connchanged(mut multi: *mut Curl_multi) { unsafe { (*multi).recheckstate = true; - } - } + } +} #[cfg(USE_NGHTTP2)] extern "C" fn on_frame_recv( @@ -936,63 +933,63 @@ extern "C" fn on_frame_recv( ) -> i32 { unsafe { let conn: *mut connectdata = userp as *mut connectdata; - let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; - let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; - let mut stream: *mut HTTP = 0 as *mut HTTP; + let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; + let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; + let mut stream: *mut HTTP = 0 as *mut HTTP; let data: *mut Curl_easy = get_transfer(httpc); let mut rv: i32 = 0; - let mut left: size_t = 0; - let mut ncopy: size_t = 0; + let mut left: size_t = 0; + let mut ncopy: size_t = 0; let stream_id: int32_t = (*frame).hd.stream_id; - let mut result: CURLcode = CURLE_OK; + let mut result: CURLcode = CURLE_OK; - if stream_id == 0 { + if stream_id == 0 { /* stream ID zero is for connection-oriented stuff */ if (*frame).hd.type_0 as i32 == NGHTTP2_SETTINGS as i32 { let max_conn: uint32_t = (*httpc).settings.max_concurrent_streams; (*httpc).settings.max_concurrent_streams = nghttp2_session_get_remote_settings( - session, - NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, - ); + session, + NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, + ); (*httpc).settings.enable_push = nghttp2_session_get_remote_settings(session, NGHTTP2_SETTINGS_ENABLE_PUSH) != 0; - if max_conn != (*httpc).settings.max_concurrent_streams { - Curl_infof( - data, + if max_conn != (*httpc).settings.max_concurrent_streams { + Curl_infof( + data, b"Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\0" as *const u8 as *const i8, - (*httpc).settings.max_concurrent_streams, - ); - multi_connchanged((*data).multi); + (*httpc).settings.max_concurrent_streams, + ); + multi_connchanged((*data).multi); + } } - } return 0; - } - data_s = nghttp2_session_get_stream_user_data(session, stream_id) as *mut Curl_easy; - if data_s.is_null() { + } + data_s = nghttp2_session_get_stream_user_data(session, stream_id) as *mut Curl_easy; + if data_s.is_null() { return 0; - } - stream = (*data_s).req.p.http; - if stream.is_null() { + } + stream = (*data_s).req.p.http; + if stream.is_null() { return NGHTTP2_ERR_CALLBACK_FAILURE; - } + } match (*frame).hd.type_0 { NGHTTP2_DATA => { /* If body started on this stream, then receiving DATA is illegal. */ - if !(*stream).bodystarted { - rv = nghttp2_submit_rst_stream( - session, + if !(*stream).bodystarted { + rv = nghttp2_submit_rst_stream( + session, NGHTTP2_FLAG_NONE as uint8_t, - stream_id, + stream_id, NGHTTP2_PROTOCOL_ERROR as uint32_t, - ); - if nghttp2_is_fatal(rv) != 0 { + ); + if nghttp2_is_fatal(rv) != 0 { return NGHTTP2_ERR_CALLBACK_FAILURE; + } } } - } NGHTTP2_HEADERS => { - if !(*stream).bodystarted { + if !(*stream).bodystarted { /* Only valid HEADERS after body started is trailer HEADERS. We buffer them in on_header callback. */ @@ -1001,38 +998,39 @@ extern "C" fn on_frame_recv( without status code having been set. */ if (*stream).status_code == -1 { return NGHTTP2_ERR_CALLBACK_FAILURE; - } + } /* Only final status code signals the end of header */ if (*stream).status_code / 100 != 1 { (*stream).bodystarted = true; (*stream).status_code = -1; - } + } - result = Curl_dyn_add( - &mut (*stream).header_recvbuf, + result = Curl_dyn_add( + &mut (*stream).header_recvbuf, b"\r\n\0" as *const u8 as *const i8, - ); + ); - if result as u64 != 0 { + if result as u64 != 0 { return NGHTTP2_ERR_CALLBACK_FAILURE; - } - left = (Curl_dyn_len(&mut (*stream).header_recvbuf)) - .wrapping_sub((*stream).nread_header_recvbuf); + } + left = (Curl_dyn_len(&mut (*stream).header_recvbuf)) + .wrapping_sub((*stream).nread_header_recvbuf); ncopy = CURLMIN((*stream).len, left); - memcpy( + memcpy( &mut *((*stream).mem).offset((*stream).memlen as isize) as *mut i8 as *mut libc::c_void, - (Curl_dyn_ptr(&mut (*stream).header_recvbuf)) - .offset((*stream).nread_header_recvbuf as isize) - as *const libc::c_void, - ncopy, - ); + (Curl_dyn_ptr(&mut (*stream).header_recvbuf)) + .offset((*stream).nread_header_recvbuf as isize) + as *const libc::c_void, + ncopy, + ); (*stream).nread_header_recvbuf = ((*stream).nread_header_recvbuf).wrapping_add(ncopy) as size_t; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !((*stream).mem).is_null() {} else { - __assert_fail( + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !((*stream).mem).is_null() { + } else { + __assert_fail( b"stream->mem\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 766 as libc::c_int as libc::c_uint, @@ -1044,22 +1042,23 @@ extern "C" fn on_frame_recv( )) .as_ptr(), ); - } + } (*stream).len = ((*stream).len).wrapping_sub(ncopy) as size_t; (*stream).memlen = ((*stream).memlen).wrapping_add(ncopy) as size_t; - drain_this(data_s, httpc); - if get_transfer(httpc) != data_s { + drain_this(data_s, httpc); + if get_transfer(httpc) != data_s { Curl_expire(data_s, 0 as timediff_t, EXPIRE_RUN_NOW); + } } } - } NGHTTP2_PUSH_PROMISE => { - rv = push_promise(data_s, conn, &(*frame).push_promise); - if rv != 0 { - let mut h2: i32 = 0; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if rv > 0 as libc::c_int && rv <= 2 as libc::c_int {} else { - __assert_fail( + rv = push_promise(data_s, conn, &(*frame).push_promise); + if rv != 0 { + let mut h2: i32 = 0; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if rv > 0 as libc::c_int && rv <= 2 as libc::c_int { + } else { + __assert_fail( b"(rv > 0) && (rv <= 2)\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 782 as libc::c_int as libc::c_uint, @@ -1071,32 +1070,32 @@ extern "C" fn on_frame_recv( )) .as_ptr(), ); - } - h2 = nghttp2_submit_rst_stream( - session, + } + h2 = nghttp2_submit_rst_stream( + session, NGHTTP2_FLAG_NONE as uint8_t, - (*frame).push_promise.promised_stream_id, + (*frame).push_promise.promised_stream_id, NGHTTP2_CANCEL as uint32_t, - ); - if nghttp2_is_fatal(h2) != 0 { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } else { - if rv == 2 { - #[cfg(DEBUGBUILD)] - Curl_infof( - data_s, - b"Fail the parent stream (too)\0" as *const u8 - as *const libc::c_char, - ); + ); + if nghttp2_is_fatal(h2) != 0 { return NGHTTP2_ERR_CALLBACK_FAILURE; + } else { + if rv == 2 { + #[cfg(DEBUGBUILD)] + Curl_infof( + data_s, + b"Fail the parent stream (too)\0" as *const u8 + as *const libc::c_char, + ); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } } } } + _ => {} } - _ => {} - } return 0; -} + } } #[cfg(USE_NGHTTP2)] @@ -1109,13 +1108,14 @@ extern "C" fn on_data_chunk_recv( userp: *mut libc::c_void, ) -> i32 { unsafe { - let mut stream: *mut HTTP = 0 as *mut HTTP; - let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; - let mut nread: size_t = 0; + let mut stream: *mut HTTP = 0 as *mut HTTP; + let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; + let mut nread: size_t = 0; let conn: *mut connectdata = userp as *mut connectdata; let httpc: *mut http_conn = &mut (*conn).proto.httpc; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if stream_id != 0 {} else { + if stream_id != 0 { + } else { __assert_fail( b"stream_id\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, @@ -1130,53 +1130,53 @@ extern "C" fn on_data_chunk_recv( ); } /* get the stream from the hash based on Stream ID */ - data_s = nghttp2_session_get_stream_user_data(session, stream_id) as *mut Curl_easy; - if data_s.is_null() { + data_s = nghttp2_session_get_stream_user_data(session, stream_id) as *mut Curl_easy; + if data_s.is_null() { /* Receiving a Stream ID not in the hash should not happen, this is an internal error more than anything else! */ return NGHTTP2_ERR_CALLBACK_FAILURE; - } + } - stream = (*data_s).req.p.http; - if stream.is_null() { + stream = (*data_s).req.p.http; + if stream.is_null() { return NGHTTP2_ERR_CALLBACK_FAILURE; - } + } nread = CURLMIN((*stream).len, len); - memcpy( + memcpy( &mut *((*stream).mem).offset((*stream).memlen as isize) as *mut i8 as *mut libc::c_void, - mem as *const libc::c_void, - nread, - ); + mem as *const libc::c_void, + nread, + ); (*stream).len = ((*stream).len as u64).wrapping_sub(nread) as size_t; (*stream).memlen = ((*stream).memlen as u64).wrapping_add(nread) as size_t; - drain_this(data_s, &mut (*conn).proto.httpc); + drain_this(data_s, &mut (*conn).proto.httpc); /* if we receive data for another handle, wake that up */ - if get_transfer(httpc) != data_s { + if get_transfer(httpc) != data_s { Curl_expire(data_s, 0 as timediff_t, EXPIRE_RUN_NOW); - } + } - if nread < len { + if nread < len { (*stream).pausedata = mem.offset(nread as isize); - (*stream).pauselen = len.wrapping_sub(nread); - (*(*data_s).conn).proto.httpc.pause_stream_id = stream_id; + (*stream).pauselen = len.wrapping_sub(nread); + (*(*data_s).conn).proto.httpc.pause_stream_id = stream_id; return NGHTTP2_ERR_PAUSE; - } + } /* pause execution of nghttp2 if we received data for another handle in order to process them first. */ - if get_transfer(httpc) != data_s { - (*(*data_s).conn).proto.httpc.pause_stream_id = stream_id; + if get_transfer(httpc) != data_s { + (*(*data_s).conn).proto.httpc.pause_stream_id = stream_id; return NGHTTP2_ERR_PAUSE; - } + } return 0; -} + } } #[cfg(USE_NGHTTP2)] extern "C" fn on_stream_close( @@ -1186,61 +1186,58 @@ extern "C" fn on_stream_close( userp: *mut libc::c_void, ) -> i32 { unsafe { - let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; - let mut stream: *mut HTTP = 0 as *mut HTTP; + let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; + let mut stream: *mut HTTP = 0 as *mut HTTP; let conn: *mut connectdata = userp as *mut connectdata; let mut rv: i32 = 0; - if stream_id != 0 { - let mut httpc: *mut http_conn = 0 as *mut http_conn; + if stream_id != 0 { + let mut httpc: *mut http_conn = 0 as *mut http_conn; /* get the stream from the hash based on Stream ID, stream ID zero is for connection-oriented stuff */ data_s = nghttp2_session_get_stream_user_data(session, stream_id) as *mut Curl_easy; - if data_s.is_null() { + if data_s.is_null() { /* We could get stream ID not in the hash. For example, if we decided to reject stream (e.g., PUSH_PROMISE). */ return 0; - } - stream = (*data_s).req.p.http; - if stream.is_null() { + } + stream = (*data_s).req.p.http; + if stream.is_null() { return NGHTTP2_ERR_CALLBACK_FAILURE; - } + } (*stream).closed = true; - httpc = &mut (*conn).proto.httpc; - drain_this(data_s, httpc); + httpc = &mut (*conn).proto.httpc; + drain_this(data_s, httpc); Curl_expire(data_s, 0 as timediff_t, EXPIRE_RUN_NOW); - (*stream).error = error_code; + (*stream).error = error_code; /* remove the entry from the hash as the stream is now gone */ rv = nghttp2_session_set_stream_user_data(session, stream_id, 0 as *mut libc::c_void); - if rv != 0 { - Curl_infof( - data_s, + if rv != 0 { + Curl_infof( + data_s, b"http/2: failed to clear user_data for stream %d!\0" as *const u8 as *const i8, - stream_id, - ); - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - __assert_fail( - b"0\0" as *const u8 as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 904 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 66], - &[libc::c_char; 66], - >( - b"int on_stream_close(nghttp2_session *, int32_t, uint32_t, void *)\0", - )) + stream_id, + ); + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + __assert_fail( + b"0\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 904 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 66], &[libc::c_char; 66]>( + b"int on_stream_close(nghttp2_session *, int32_t, uint32_t, void *)\0", + )) .as_ptr(), - ); - } - if stream_id == (*httpc).pause_stream_id { + ); + } + if stream_id == (*httpc).pause_stream_id { (*httpc).pause_stream_id = 0; - } + } (*stream).stream_id = 0; - } + } return 0; -} + } } #[cfg(USE_NGHTTP2)] @@ -1250,26 +1247,26 @@ extern "C" fn on_begin_headers( userp: *mut libc::c_void, ) -> i32 { unsafe { - let mut stream: *mut HTTP = 0 as *mut HTTP; - let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; + let mut stream: *mut HTTP = 0 as *mut HTTP; + let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; data_s = nghttp2_session_get_stream_user_data(session, (*frame).hd.stream_id) as *mut Curl_easy; - if data_s.is_null() { + if data_s.is_null() { return 0; - } + } if (*frame).hd.type_0 != NGHTTP2_HEADERS { return 0; - } + } - stream = (*data_s).req.p.http; - if stream.is_null() || !(*stream).bodystarted { + stream = (*data_s).req.p.http; + if stream.is_null() || !(*stream).bodystarted { return 0; - } + } return 0; -} } +} /* Decode HTTP status code. Returns -1 if no valid status code was decoded. */ @@ -1295,11 +1292,11 @@ extern "C" fn decode_status_code(value: *const uint8_t, len: size_t) -> i32 { res *= 10; res += c as i32 - '0' as i32; - i += 1; - } + i += 1; + } - return res; -} + return res; + } } /* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */ @@ -1315,16 +1312,17 @@ extern "C" fn on_header( userp: *mut libc::c_void, ) -> i32 { unsafe { - let mut stream: *mut HTTP = 0 as *mut HTTP; - let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; + let mut stream: *mut HTTP = 0 as *mut HTTP; + let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; let stream_id: int32_t = (*frame).hd.stream_id; let conn: *mut connectdata = userp as *mut connectdata; let httpc: *mut http_conn = &mut (*conn).proto.httpc; - let mut result: CURLcode = CURLE_OK; - /* get the stream from the hash based on Stream ID */ - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if stream_id != 0 {} else { - __assert_fail( + let mut result: CURLcode = CURLE_OK; + /* get the stream from the hash based on Stream ID */ + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if stream_id != 0 { + } else { + __assert_fail( b"stream_id\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 984 as libc::c_int as libc::c_uint, @@ -1336,19 +1334,19 @@ extern "C" fn on_header( )) .as_ptr(), ); - } - data_s = nghttp2_session_get_stream_user_data(session, stream_id) as *mut Curl_easy; - if data_s.is_null() { + } + data_s = nghttp2_session_get_stream_user_data(session, stream_id) as *mut Curl_easy; + if data_s.is_null() { /* Receiving a Stream ID not in the hash should not happen, this is an internal error more than anything else! */ return NGHTTP2_ERR_CALLBACK_FAILURE; - } + } - stream = (*data_s).req.p.http; - if stream.is_null() { + stream = (*data_s).req.p.http; + if stream.is_null() { Curl_failf(data_s, b"Internal NULL stream!\0" as *const u8 as *const i8); return NGHTTP2_ERR_CALLBACK_FAILURE; - } + } /* Store received PUSH_PROMISE headers to be used when the subsequent PUSH_PROMISE callback comes */ @@ -1359,129 +1357,131 @@ extern "C" fn on_header( let mut rc: i32 = 0; let check: *mut i8 = curl_maprintf( b"%s:%d\0" as *const u8 as *const i8, - (*conn).host.name, - (*conn).remote_port, - ); - if check.is_null() { + (*conn).host.name, + (*conn).remote_port, + ); + if check.is_null() { /* no memory */ return NGHTTP2_ERR_CALLBACK_FAILURE; - } + } if Curl_strcasecompare(check, value as *const i8) == 0 - && ((*conn).remote_port != (*(*conn).given).defport + && ((*conn).remote_port != (*(*conn).given).defport || Curl_strcasecompare((*conn).host.name, value as *const i8) == 0) - { - nghttp2_submit_rst_stream( - session, + { + nghttp2_submit_rst_stream( + session, NGHTTP2_FLAG_NONE as uint8_t, - stream_id, + stream_id, NGHTTP2_PROTOCOL_ERROR as uint32_t, - ); + ); /* This is push is not for the same authority that was asked for in * the URL. RFC 7540 section 8.2 says: "A client MUST treat a * PUSH_PROMISE for which the server is not authoritative as a stream * error of type PROTOCOL_ERROR." */ rc = NGHTTP2_ERR_CALLBACK_FAILURE; - } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(check as *mut libc::c_void); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - check as *mut libc::c_void, - 1023 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ); - if rc != 0 { - return rc; - } - } - - if ((*stream).push_headers).is_null() { - (*stream).push_headers_alloc = 10 as size_t; - match () { - #[cfg(not(CURLDEBUG))] - _ => { - (*stream).push_headers = Curl_cmalloc.expect("non-null function pointer")( - ((*stream).push_headers_alloc) - .wrapping_mul(::std::mem::size_of::<*mut i8>() as u64), - ) as *mut *mut i8; } + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(check as *mut libc::c_void); + #[cfg(CURLDEBUG)] - _ => { - (*stream).push_headers = curl_dbg_malloc( - ((*stream).push_headers_alloc) - .wrapping_mul( - ::std::mem::size_of::<*mut libc::c_char>() as libc::c_ulong, - ), - 1031 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ) as *mut *mut libc::c_char; + curl_dbg_free( + check as *mut libc::c_void, + 1023 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ); + if rc != 0 { + return rc; } } - - + if ((*stream).push_headers).is_null() { + (*stream).push_headers_alloc = 10 as size_t; + match () { + #[cfg(not(CURLDEBUG))] + _ => { + (*stream).push_headers = Curl_cmalloc.expect("non-null function pointer")( + ((*stream).push_headers_alloc) + .wrapping_mul(::std::mem::size_of::<*mut i8>() as u64), + ) as *mut *mut i8; + } + #[cfg(CURLDEBUG)] + _ => { + (*stream).push_headers = curl_dbg_malloc( + ((*stream).push_headers_alloc).wrapping_mul(::std::mem::size_of::< + *mut libc::c_char, + >( + ) + as libc::c_ulong), + 1031 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ) + as *mut *mut libc::c_char; + } + } + + if ((*stream).push_headers).is_null() { return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - } + } (*stream).push_headers_used = 0 as size_t; - } else if (*stream).push_headers_used == (*stream).push_headers_alloc { + } else if (*stream).push_headers_used == (*stream).push_headers_alloc { let mut headp: *mut *mut i8 = 0 as *mut *mut i8; (*stream).push_headers_alloc = ((*stream).push_headers_alloc as u64) .wrapping_mul(2 as u64) as size_t as size_t; - headp = Curl_saferealloc( - (*stream).push_headers as *mut libc::c_void, - ((*stream).push_headers_alloc) + headp = Curl_saferealloc( + (*stream).push_headers as *mut libc::c_void, + ((*stream).push_headers_alloc) .wrapping_mul(::std::mem::size_of::<*mut i8>() as u64), ) as *mut *mut i8; - if headp.is_null() { + if headp.is_null() { (*stream).push_headers = 0 as *mut *mut i8; return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - } + } (*stream).push_headers = headp; - } + } h = curl_maprintf(b"%s:%s\0" as *const u8 as *const i8, name, value); - if !h.is_null() { - let ref mut fresh25 = (*stream).push_headers_used; - let fresh26 = *fresh25; - *fresh25 = (*fresh25).wrapping_add(1); + if !h.is_null() { + let ref mut fresh25 = (*stream).push_headers_used; + let fresh26 = *fresh25; + *fresh25 = (*fresh25).wrapping_add(1); *((*stream).push_headers).offset(fresh26 as isize) = h; - } + } return 0; - } + } - if (*stream).bodystarted { + if (*stream).bodystarted { /* This is a trailer */ - result = Curl_dyn_addf( - &mut (*stream).trailer_recvbuf as *mut dynbuf, + result = Curl_dyn_addf( + &mut (*stream).trailer_recvbuf as *mut dynbuf, b"%.*s: %.*s\r\n\0" as *const u8 as *const i8, - namelen, - name, - valuelen, - value, - ); - if result as u64 != 0 { + namelen, + name, + valuelen, + value, + ); + if result as u64 != 0 { return NGHTTP2_ERR_CALLBACK_FAILURE; - } + } return 0; - } + } if namelen == (::std::mem::size_of::<[i8; 8]>() as u64).wrapping_sub(1 as u64) - && memcmp( + && memcmp( b":status\0" as *const u8 as *const i8 as *const libc::c_void, - name as *const libc::c_void, - namelen, + name as *const libc::c_void, + namelen, ) == 0 - { + { /* nghttp2 guarantees :status is received first and only once, and value is 3 digits status code, and decode_status_code always succeeds. */ - (*stream).status_code = decode_status_code(value, valuelen); - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*stream).status_code != -(1 as libc::c_int) {} else { - __assert_fail( + (*stream).status_code = decode_status_code(value, valuelen); + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*stream).status_code != -(1 as libc::c_int) { + } else { + __assert_fail( b"stream->status_code != -1\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 1073 as libc::c_int as libc::c_uint, @@ -1493,14 +1493,55 @@ extern "C" fn on_header( )) .as_ptr(), ); + } + result = Curl_dyn_add( + &mut (*stream).header_recvbuf, + b"HTTP/2 \0" as *const u8 as *const i8, + ); + + if result as u64 != 0 { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + result = Curl_dyn_addn( + &mut (*stream).header_recvbuf, + value as *const libc::c_void, + valuelen, + ); + if result as u64 != 0 { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + /* the space character after the status code is mandatory */ + result = Curl_dyn_add( + &mut (*stream).header_recvbuf, + b" \r\n\0" as *const u8 as *const i8, + ); + if result as u64 != 0 { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + /* if we receive data for another handle, wake that up */ + if get_transfer(httpc) != data_s { + Curl_expire(data_s, 0 as timediff_t, EXPIRE_RUN_NOW); + } + return 0; + } + + /* nghttp2 guarantees that namelen > 0, and :status was already + received, and this is not pseudo-header field . */ + /* convert to a HTTP1-style header */ + result = Curl_dyn_addn( + &mut (*stream).header_recvbuf, + name as *const libc::c_void, + namelen, + ); + if result as u64 != 0 { + return NGHTTP2_ERR_CALLBACK_FAILURE; } result = Curl_dyn_add( &mut (*stream).header_recvbuf, - b"HTTP/2 \0" as *const u8 as *const i8, + b": \0" as *const u8 as *const i8, ); - if result as u64 != 0 { - return NGHTTP2_ERR_CALLBACK_FAILURE; + return NGHTTP2_ERR_CALLBACK_FAILURE; } result = Curl_dyn_addn( &mut (*stream).header_recvbuf, @@ -1508,62 +1549,21 @@ extern "C" fn on_header( valuelen, ); if result as u64 != 0 { - return NGHTTP2_ERR_CALLBACK_FAILURE; + return NGHTTP2_ERR_CALLBACK_FAILURE; } - /* the space character after the status code is mandatory */ result = Curl_dyn_add( &mut (*stream).header_recvbuf, - b" \r\n\0" as *const u8 as *const i8, + b"\r\n\0" as *const u8 as *const i8, ); if result as u64 != 0 { - return NGHTTP2_ERR_CALLBACK_FAILURE; + return NGHTTP2_ERR_CALLBACK_FAILURE; } - /* if we receive data for another handle, wake that up */ + /* if we receive data for another handle, wake that up */ if get_transfer(httpc) != data_s { - Curl_expire(data_s, 0 as timediff_t, EXPIRE_RUN_NOW); + Curl_expire(data_s, 0 as timediff_t, EXPIRE_RUN_NOW); } - return 0; + return 0; } - - /* nghttp2 guarantees that namelen > 0, and :status was already - received, and this is not pseudo-header field . */ - /* convert to a HTTP1-style header */ - result = Curl_dyn_addn( - &mut (*stream).header_recvbuf, - name as *const libc::c_void, - namelen, - ); - if result as u64 != 0 { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - result = Curl_dyn_add( - &mut (*stream).header_recvbuf, - b": \0" as *const u8 as *const i8, - ); - if result as u64 != 0 { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - result = Curl_dyn_addn( - &mut (*stream).header_recvbuf, - value as *const libc::c_void, - valuelen, - ); - if result as u64 != 0 { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - result = Curl_dyn_add( - &mut (*stream).header_recvbuf, - b"\r\n\0" as *const u8 as *const i8, - ); - if result as u64 != 0 { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - /* if we receive data for another handle, wake that up */ - if get_transfer(httpc) != data_s { - Curl_expire(data_s, 0 as timediff_t, EXPIRE_RUN_NOW); - } - return 0; -} } #[cfg(USE_NGHTTP2)] extern "C" fn data_source_read_callback( @@ -1576,51 +1576,51 @@ extern "C" fn data_source_read_callback( userp: *mut libc::c_void, ) -> ssize_t { unsafe { - let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; - let mut stream: *mut HTTP = 0 as *mut HTTP; - let mut nread: size_t = 0; + let mut data_s: *mut Curl_easy = 0 as *mut Curl_easy; + let mut stream: *mut HTTP = 0 as *mut HTTP; + let mut nread: size_t = 0; - if stream_id != 0 { + if stream_id != 0 { /* get the stream from the hash based on Stream ID, stream ID zero is for connection-oriented stuff */ data_s = nghttp2_session_get_stream_user_data(session, stream_id) as *mut Curl_easy; - if data_s.is_null() { + if data_s.is_null() { /* Receiving a Stream ID not in the hash should not happen, this is an internal error more than anything else! */ return NGHTTP2_ERR_CALLBACK_FAILURE as ssize_t; - } - stream = (*data_s).req.p.http; - if stream.is_null() { + } + stream = (*data_s).req.p.http; + if stream.is_null() { return NGHTTP2_ERR_CALLBACK_FAILURE as ssize_t; - } - } else { + } + } else { return NGHTTP2_ERR_INVALID_ARGUMENT as ssize_t; - } + } nread = CURLMIN((*stream).upload_len, length); if nread > 0 { - memcpy( - buf as *mut libc::c_void, - (*stream).upload_mem as *const libc::c_void, - nread, - ); + memcpy( + buf as *mut libc::c_void, + (*stream).upload_mem as *const libc::c_void, + nread, + ); (*stream).upload_mem = (*stream).upload_mem.offset(nread as isize); (*stream).upload_len = ((*stream).upload_len as u64).wrapping_sub(nread) as size_t as size_t; if (*data_s).state.infilesize != -1 { (*stream).upload_left = ((*stream).upload_left as u64).wrapping_sub(nread) as curl_off_t as curl_off_t; + } } - } if (*stream).upload_left == 0 as i64 { *data_flags = NGHTTP2_DATA_FLAG_EOF as uint32_t; } else if nread == 0 as u64 { return NGHTTP2_ERR_DEFERRED as ssize_t; - } + } - return nread as ssize_t; -} + return nread as ssize_t; + } } #[cfg(all(USE_NGHTTP2, not(CURL_DISABLE_VERBOSE_STRINGS)))] extern "C" fn error_callback( @@ -1655,112 +1655,109 @@ extern "C" fn populate_settings(data: *mut Curl_easy, mut httpc: *mut http_conn) #[no_mangle] pub extern "C" fn Curl_http2_done(data: *mut Curl_easy, premature: bool) { unsafe { - let mut http: *mut HTTP = (*data).req.p.http; - let mut httpc: *mut http_conn = &mut (*(*data).conn).proto.httpc; + let mut http: *mut HTTP = (*data).req.p.http; + let mut httpc: *mut http_conn = &mut (*(*data).conn).proto.httpc; /* there might be allocated resources done before this got the 'h2' pointer setup */ - Curl_dyn_free(&mut (*http).header_recvbuf); - Curl_dyn_free(&mut (*http).trailer_recvbuf); - if !((*http).push_headers).is_null() { - while (*http).push_headers_used > 0 as libc::c_int as libc::c_ulong { + Curl_dyn_free(&mut (*http).header_recvbuf); + Curl_dyn_free(&mut (*http).trailer_recvbuf); + if !((*http).push_headers).is_null() { + while (*http).push_headers_used > 0 as libc::c_int as libc::c_ulong { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + *((*http).push_headers) + .offset(((*http).push_headers_used).wrapping_sub(1) as isize) + as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + *((*http).push_headers).offset( + ((*http).push_headers_used).wrapping_sub(1 as libc::c_int as libc::c_ulong) + as isize, + ) as *mut libc::c_void, + 1212 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ); + (*http).push_headers_used = (*http).push_headers_used.wrapping_sub(1); + } #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( - *((*http).push_headers) - .offset(((*http).push_headers_used).wrapping_sub(1) as isize) - as *mut libc::c_void, + (*http).push_headers as *mut libc::c_void, ); - #[cfg(CURLDEBUG)] + + #[cfg(CURLDEBUG)] curl_dbg_free( - *((*http).push_headers) - .offset( - ((*http).push_headers_used) - .wrapping_sub(1 as libc::c_int as libc::c_ulong) as isize, - ) as *mut libc::c_void, - 1212 as libc::c_int, + (*http).push_headers as *mut libc::c_void, + 1214 as libc::c_int, b"http2.c\0" as *const u8 as *const libc::c_char, ); - (*http).push_headers_used = (*http).push_headers_used.wrapping_sub(1); + (*http).push_headers = 0 as *mut *mut i8; } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*http).push_headers as *mut libc::c_void, - ); - - - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*http).push_headers as *mut libc::c_void, - 1214 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ); - (*http).push_headers = 0 as *mut *mut i8; - } /* not HTTP/2 ? */ if (*(*(*data).conn).handler).protocol & ((1) << 0 | (1) << 1) as u32 == 0 - || ((*httpc).h2).is_null() - { - return; - } + || ((*httpc).h2).is_null() + { + return; + } - if premature { + if premature { /* RST_STREAM */ set_transfer(httpc, data); /* set the transfer */ - if nghttp2_submit_rst_stream( - (*httpc).h2, + if nghttp2_submit_rst_stream( + (*httpc).h2, NGHTTP2_FLAG_NONE as uint8_t, - (*http).stream_id, + (*http).stream_id, NGHTTP2_STREAM_CLOSED as uint32_t, - ) == 0 - { - nghttp2_session_send((*httpc).h2); - } + ) == 0 + { + nghttp2_session_send((*httpc).h2); + } - if (*http).stream_id == (*httpc).pause_stream_id { - Curl_infof( - data, + if (*http).stream_id == (*httpc).pause_stream_id { + Curl_infof( + data, b"stopped the pause stream!\0" as *const u8 as *const i8, - ); + ); (*httpc).pause_stream_id = 0; + } } - } - if (*data).state.drain != 0 { - drained_transfer(data, httpc); - } + if (*data).state.drain != 0 { + drained_transfer(data, httpc); + } /* -1 means unassigned and 0 means cleared */ if (*http).stream_id > 0 { let rv: i32 = nghttp2_session_set_stream_user_data( - (*httpc).h2, - (*http).stream_id, - 0 as *mut libc::c_void, - ); - - if rv != 0 { - Curl_infof( - data, - b"http/2: failed to clear user_data for stream %d!\0" as *const u8 as *const i8, + (*httpc).h2, (*http).stream_id, + 0 as *mut libc::c_void, ); - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - __assert_fail( - b"0\0" as *const u8 as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 1245 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 48], - &[libc::c_char; 48], - >(b"void Curl_http2_done(struct Curl_easy *, _Bool)\0")) + + if rv != 0 { + Curl_infof( + data, + b"http/2: failed to clear user_data for stream %d!\0" as *const u8 as *const i8, + (*http).stream_id, + ); + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + __assert_fail( + b"0\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 1245 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 48], &[libc::c_char; 48]>( + b"void Curl_http2_done(struct Curl_easy *, _Bool)\0", + )) .as_ptr(), - ); - } - set_transfer(httpc, 0 as *mut Curl_easy); + ); + } + set_transfer(httpc, 0 as *mut Curl_easy); (*http).stream_id = 0; + } } } -} /* * Initialize nghttp2 for a Curl connection @@ -1768,156 +1765,157 @@ pub extern "C" fn Curl_http2_done(data: *mut Curl_easy, premature: bool) { #[cfg(USE_NGHTTP2)] extern "C" fn http2_init(data: *mut Curl_easy, conn: *mut connectdata) -> CURLcode { unsafe { - if ((*conn).proto.httpc.h2).is_null() { + if ((*conn).proto.httpc.h2).is_null() { let mut rc: i32 = 0; let mut callbacks: *mut nghttp2_session_callbacks = 0 as *mut nghttp2_session_callbacks; - - match () { - #[cfg(not(CURLDEBUG))] - _ => { - (*conn).proto.httpc.inbuf = - Curl_cmalloc.expect("non-null function pointer")(H2_BUFSIZE as size_t) as *mut i8; + + match () { + #[cfg(not(CURLDEBUG))] + _ => { + (*conn).proto.httpc.inbuf = + Curl_cmalloc.expect("non-null function pointer")(H2_BUFSIZE as size_t) + as *mut i8; + } + #[cfg(CURLDEBUG)] + _ => { + (*conn).proto.httpc.inbuf = curl_dbg_malloc( + 32768 as libc::c_int as size_t, + 1261 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ) as *mut libc::c_char; + } } - #[cfg(CURLDEBUG)] - _ => { - (*conn).proto.httpc.inbuf = curl_dbg_malloc( - 32768 as libc::c_int as size_t, - 1261 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char; + + if ((*conn).proto.httpc.inbuf).is_null() { + return CURLE_OUT_OF_MEMORY; /* most likely at least */ } - } - - if ((*conn).proto.httpc.inbuf).is_null() { - return CURLE_OUT_OF_MEMORY; /* most likely at least */ - } - rc = nghttp2_session_callbacks_new(&mut callbacks); + rc = nghttp2_session_callbacks_new(&mut callbacks); /* nghttp2_send_callback */ - if rc != 0 { - Curl_failf( - data, + if rc != 0 { + Curl_failf( + data, b"Couldn't initialize nghttp2 callbacks!\0" as *const u8 as *const i8, - ); - return CURLE_OUT_OF_MEMORY; - } + ); + return CURLE_OUT_OF_MEMORY; + } /* nghttp2_on_frame_recv_callback */ - nghttp2_session_callbacks_set_send_callback( - callbacks, - Some( - send_callback + nghttp2_session_callbacks_set_send_callback( + callbacks, + Some( + send_callback as extern "C" fn( - *mut nghttp2_session, - *const uint8_t, - size_t, + *mut nghttp2_session, + *const uint8_t, + size_t, i32, - *mut libc::c_void, - ) -> ssize_t, - ), - ); + *mut libc::c_void, + ) -> ssize_t, + ), + ); /* nghttp2_on_data_chunk_recv_callback */ - nghttp2_session_callbacks_set_on_frame_recv_callback( - callbacks, - Some( - on_frame_recv + nghttp2_session_callbacks_set_on_frame_recv_callback( + callbacks, + Some( + on_frame_recv as extern "C" fn( - *mut nghttp2_session, - *const nghttp2_frame, - *mut libc::c_void, + *mut nghttp2_session, + *const nghttp2_frame, + *mut libc::c_void, ) -> i32, - ), - ); + ), + ); /* nghttp2_on_stream_close_callback */ - nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - callbacks, - Some( - on_data_chunk_recv + nghttp2_session_callbacks_set_on_data_chunk_recv_callback( + callbacks, + Some( + on_data_chunk_recv as extern "C" fn( - *mut nghttp2_session, - uint8_t, - int32_t, - *const uint8_t, - size_t, - *mut libc::c_void, + *mut nghttp2_session, + uint8_t, + int32_t, + *const uint8_t, + size_t, + *mut libc::c_void, ) -> i32, - ), - ); + ), + ); /* nghttp2_on_begin_headers_callback */ - nghttp2_session_callbacks_set_on_stream_close_callback( - callbacks, - Some( - on_stream_close + nghttp2_session_callbacks_set_on_stream_close_callback( + callbacks, + Some( + on_stream_close as extern "C" fn( - *mut nghttp2_session, - int32_t, - uint32_t, - *mut libc::c_void, + *mut nghttp2_session, + int32_t, + uint32_t, + *mut libc::c_void, ) -> i32, - ), - ); + ), + ); /* nghttp2_on_header_callback */ - nghttp2_session_callbacks_set_on_begin_headers_callback( - callbacks, - Some( - on_begin_headers + nghttp2_session_callbacks_set_on_begin_headers_callback( + callbacks, + Some( + on_begin_headers as extern "C" fn( - *mut nghttp2_session, - *const nghttp2_frame, - *mut libc::c_void, + *mut nghttp2_session, + *const nghttp2_frame, + *mut libc::c_void, ) -> i32, - ), - ); + ), + ); - nghttp2_session_callbacks_set_on_header_callback( - callbacks, - Some( - on_header + nghttp2_session_callbacks_set_on_header_callback( + callbacks, + Some( + on_header as extern "C" fn( - *mut nghttp2_session, - *const nghttp2_frame, - *const uint8_t, - size_t, - *const uint8_t, - size_t, - uint8_t, - *mut libc::c_void, + *mut nghttp2_session, + *const nghttp2_frame, + *const uint8_t, + size_t, + *const uint8_t, + size_t, + uint8_t, + *mut libc::c_void, ) -> i32, - ), - ); + ), + ); #[cfg(CURL_DISABLE_VERBOSE_STRINGS)] - nghttp2_session_callbacks_set_error_callback( - callbacks, - Some( - error_callback + nghttp2_session_callbacks_set_error_callback( + callbacks, + Some( + error_callback as extern "C" fn( - *mut nghttp2_session, + *mut nghttp2_session, *const i8, - size_t, - *mut libc::c_void, + size_t, + *mut libc::c_void, ) -> i32, - ), - ); + ), + ); /* The nghttp2 session is not yet setup, do it */ - rc = nghttp2_session_client_new( - &mut (*conn).proto.httpc.h2, - callbacks, - conn as *mut libc::c_void, - ); + rc = nghttp2_session_client_new( + &mut (*conn).proto.httpc.h2, + callbacks, + conn as *mut libc::c_void, + ); - nghttp2_session_callbacks_del(callbacks); + nghttp2_session_callbacks_del(callbacks); - if rc != 0 { - Curl_failf( - data, + if rc != 0 { + Curl_failf( + data, b"Couldn't initialize nghttp2!\0" as *const u8 as *const i8, - ); + ); return CURLE_OUT_OF_MEMORY; /* most likely at least */ + } } + return CURLE_OK; } - return CURLE_OK; -} } /* @@ -1927,68 +1925,68 @@ extern "C" fn http2_init(data: *mut Curl_easy, conn: *mut connectdata) -> CURLco #[no_mangle] pub extern "C" fn Curl_http2_request_upgrade(req: *mut dynbuf, data: *mut Curl_easy) -> CURLcode { unsafe { - let mut result: CURLcode = CURLE_OK; - let mut binlen: ssize_t = 0; + let mut result: CURLcode = CURLE_OK; + let mut binlen: ssize_t = 0; let mut base64: *mut i8 = 0 as *mut i8; - let mut blen: size_t = 0; - let mut conn: *mut connectdata = (*data).conn; - let mut k: *mut SingleRequest = &mut (*data).req; + let mut blen: size_t = 0; + let mut conn: *mut connectdata = (*data).conn; + let mut k: *mut SingleRequest = &mut (*data).req; let binsettings: *mut uint8_t = ((*conn).proto.httpc.binsettings).as_mut_ptr(); let httpc: *mut http_conn = &mut (*conn).proto.httpc; - populate_settings(data, httpc); + populate_settings(data, httpc); /* this returns number of bytes it wrote */ - binlen = nghttp2_pack_settings_payload( - binsettings, + binlen = nghttp2_pack_settings_payload( + binsettings, 80 as size_t, - ((*httpc).local_settings).as_mut_ptr(), - (*httpc).local_settings_num, - ); + ((*httpc).local_settings).as_mut_ptr(), + (*httpc).local_settings_num, + ); if binlen <= 0 { - Curl_failf( - data, + Curl_failf( + data, b"nghttp2 unexpectedly failed on pack_settings_payload\0" as *const u8 as *const i8, - ); - Curl_dyn_free(req); - return CURLE_FAILED_INIT; - } - (*conn).proto.httpc.binlen = binlen as size_t; + ); + Curl_dyn_free(req); + return CURLE_FAILED_INIT; + } + (*conn).proto.httpc.binlen = binlen as size_t; - result = Curl_base64url_encode( - data, + result = Curl_base64url_encode( + data, binsettings as *const i8, - binlen as size_t, - &mut base64, - &mut blen, - ); + binlen as size_t, + &mut base64, + &mut blen, + ); if result != 0 { - Curl_dyn_free(req); - return result; - } + Curl_dyn_free(req); + return result; + } - result = Curl_dyn_addf( - req, - b"Connection: Upgrade, HTTP2-Settings\r\nUpgrade: %s\r\nHTTP2-Settings: %s\r\n\0" + result = Curl_dyn_addf( + req, + b"Connection: Upgrade, HTTP2-Settings\r\nUpgrade: %s\r\nHTTP2-Settings: %s\r\n\0" as *const u8 as *const i8, b"h2c\0" as *const u8 as *const i8, - base64, - ); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(base64 as *mut libc::c_void); + base64, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(base64 as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - base64 as *mut libc::c_void, - 1344 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ); - (*k).upgr101 = UPGR101_REQUESTED; + #[cfg(CURLDEBUG)] + curl_dbg_free( + base64 as *mut libc::c_void, + 1344 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ); + (*k).upgr101 = UPGR101_REQUESTED; - return result; -} + return result; + } } /* @@ -1998,9 +1996,9 @@ pub extern "C" fn Curl_http2_request_upgrade(req: *mut dynbuf, data: *mut Curl_e extern "C" fn should_close_session(httpc: *mut http_conn) -> i32 { unsafe { return ((*httpc).drain_total == 0 - && nghttp2_session_want_read((*httpc).h2) == 0 + && nghttp2_session_want_read((*httpc).h2) == 0 && nghttp2_session_want_write((*httpc).h2) == 0) as i32; -} + } } /* @@ -2016,76 +2014,76 @@ extern "C" fn h2_process_pending_input( err: *mut CURLcode, ) -> i32 { unsafe { - let mut nread: ssize_t = 0; + let mut nread: ssize_t = 0; let mut inbuf: *mut i8 = 0 as *mut i8; - let mut rv: ssize_t = 0; + let mut rv: ssize_t = 0; - nread = ((*httpc).inbuflen).wrapping_sub((*httpc).nread_inbuf) as ssize_t; - inbuf = ((*httpc).inbuf).offset((*httpc).nread_inbuf as isize); + nread = ((*httpc).inbuflen).wrapping_sub((*httpc).nread_inbuf) as ssize_t; + inbuf = ((*httpc).inbuf).offset((*httpc).nread_inbuf as isize); set_transfer(httpc, data); /* set the transfer */ - rv = nghttp2_session_mem_recv((*httpc).h2, inbuf as *const uint8_t, nread as size_t); + rv = nghttp2_session_mem_recv((*httpc).h2, inbuf as *const uint8_t, nread as size_t); if rv < 0 { - Curl_failf( - data, - b"h2_process_pending_input: nghttp2_session_mem_recv() returned %zd:%s\0" + Curl_failf( + data, + b"h2_process_pending_input: nghttp2_session_mem_recv() returned %zd:%s\0" as *const u8 as *const i8, - rv, + rv, nghttp2_strerror(rv as i32), - ); - *err = CURLE_RECV_ERROR; + ); + *err = CURLE_RECV_ERROR; return -1; - } + } - if nread == rv { + if nread == rv { (*httpc).inbuflen = 0; (*httpc).nread_inbuf = 0; - } else { + } else { (*httpc).nread_inbuf = ((*httpc).nread_inbuf as u64).wrapping_add(rv as u64) as size_t; - } + } - rv = h2_session_send(data, (*httpc).h2) as ssize_t; - if rv != 0 { - *err = CURLE_SEND_ERROR; + rv = h2_session_send(data, (*httpc).h2) as ssize_t; + if rv != 0 { + *err = CURLE_SEND_ERROR; return -1; - } + } - /* No more requests are allowed in the current session, so + /* No more requests are allowed in the current session, so the connection may not be reused. This is set when a GOAWAY frame has been received or when the limit of stream identifiers has been reached. */ - if nghttp2_session_check_request_allowed((*httpc).h2) == 0 as libc::c_int { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol((*data).conn, 1); - - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - (*data).conn, - 1 as libc::c_int, - b"http/2: No new requests allowed\0" as *const u8 as *const libc::c_char, - ); - } - - if should_close_session(httpc) != 0 { - let stream: *mut HTTP = (*data).req.p.http; - if (*stream).error != 0 { - *err = CURLE_HTTP2; - } else { + if nghttp2_session_check_request_allowed((*httpc).h2) == 0 as libc::c_int { #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] -/* not an error per se, but should still close the connection */ -Curl_conncontrol((*data).conn, 1); -#[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol((*data).conn, 1); + + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] Curl_conncontrol( (*data).conn, 1 as libc::c_int, - b"GOAWAY received\0" as *const u8 as *const libc::c_char, + b"http/2: No new requests allowed\0" as *const u8 as *const libc::c_char, ); - *err = CURLE_OK; } + + if should_close_session(httpc) != 0 { + let stream: *mut HTTP = (*data).req.p.http; + if (*stream).error != 0 { + *err = CURLE_HTTP2; + } else { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + /* not an error per se, but should still close the connection */ + Curl_conncontrol((*data).conn, 1); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + (*data).conn, + 1 as libc::c_int, + b"GOAWAY received\0" as *const u8 as *const libc::c_char, + ); + *err = CURLE_OK; + } return -1; - } + } return 0; -} + } } /* @@ -2098,46 +2096,46 @@ pub extern "C" fn Curl_http2_done_sending( conn: *mut connectdata, ) -> CURLcode { unsafe { - let mut result: CURLcode = CURLE_OK; + let mut result: CURLcode = CURLE_OK; - if (*conn).handler == &Curl_handler_http2_ssl as *const Curl_handler - || (*conn).handler == &Curl_handler_http2 as *const Curl_handler - { + if (*conn).handler == &Curl_handler_http2_ssl as *const Curl_handler + || (*conn).handler == &Curl_handler_http2 as *const Curl_handler + { /* make sure this is only attempted for HTTP/2 transfers */ - let mut stream: *mut HTTP = (*data).req.p.http; + let mut stream: *mut HTTP = (*data).req.p.http; let httpc: *mut http_conn = &mut (*conn).proto.httpc; let h2: *mut nghttp2_session = (*httpc).h2; - if (*stream).upload_left != 0 { + if (*stream).upload_left != 0 { /* If the stream still thinks there's data left to upload. */ (*stream).upload_left = 0 as curl_off_t; /* resume sending here to trigger the callback to get called again so that it can signal EOF to nghttp2 */ - nghttp2_session_resume_data(h2, (*stream).stream_id); - h2_process_pending_input(data, httpc, &mut result); - } + nghttp2_session_resume_data(h2, (*stream).stream_id); + h2_process_pending_input(data, httpc, &mut result); + } /* If nghttp2 still has pending frames unsent */ - if nghttp2_session_want_write(h2) != 0 { - let mut k: *mut SingleRequest = &mut (*data).req; + if nghttp2_session_want_write(h2) != 0 { + let mut k: *mut SingleRequest = &mut (*data).req; let mut rv: i32 = 0; /* and attempt to send the pending frames */ - rv = h2_session_send(data, h2); - if rv != 0 { - result = CURLE_SEND_ERROR; - } + rv = h2_session_send(data, h2); + if rv != 0 { + result = CURLE_SEND_ERROR; + } - if nghttp2_session_want_write(h2) != 0 { + if nghttp2_session_want_write(h2) != 0 { /* re-set KEEP_SEND to make sure we are called again */ (*k).keepon |= KEEP_SEND; + } } } + return result; } - return result; -} } #[cfg(USE_NGHTTP2)] @@ -2148,22 +2146,23 @@ extern "C" fn http2_handle_stream_close( err: *mut CURLcode, ) -> ssize_t { unsafe { - let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; + let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; - if (*httpc).pause_stream_id == (*stream).stream_id { + if (*httpc).pause_stream_id == (*stream).stream_id { (*httpc).pause_stream_id = 0; - } + } - drained_transfer(data, httpc); + drained_transfer(data, httpc); if (*httpc).pause_stream_id == 0 { if h2_process_pending_input(data, httpc, err) != 0 { return -1; + } } - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*data).state.drain == 0 as libc::c_int as libc::c_ulong {} else { - __assert_fail( + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*data).state.drain == 0 as libc::c_int as libc::c_ulong { + } else { + __assert_fail( b"data->state.drain == 0\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 1497 as libc::c_int as libc::c_uint, @@ -2175,80 +2174,80 @@ extern "C" fn http2_handle_stream_close( )) .as_ptr(), ); - } - /* Reset to FALSE to prevent infinite loop in readwrite_data function. */ - (*stream).closed = false; - if (*stream).error == NGHTTP2_REFUSED_STREAM as u32 { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 1); - -#[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 1 as libc::c_int, - b"REFUSED_STREAM\0" as *const u8 as *const libc::c_char, - ); - (*data).state.set_refused_stream(1 as bit); + } + /* Reset to FALSE to prevent infinite loop in readwrite_data function. */ + (*stream).closed = false; + if (*stream).error == NGHTTP2_REFUSED_STREAM as u32 { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 1); + + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 1 as libc::c_int, + b"REFUSED_STREAM\0" as *const u8 as *const libc::c_char, + ); + (*data).state.set_refused_stream(1 as bit); *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ return -1; - } else { + } else { if (*stream).error != NGHTTP2_NO_ERROR as u32 { - Curl_failf( - data, - b"HTTP/2 stream %d was not closed cleanly: %s (err %u)\0" as *const u8 - as *const libc::c_char, - (*stream).stream_id, - nghttp2_http2_strerror((*stream).error), - (*stream).error, - ); - *err = CURLE_HTTP2_STREAM; + Curl_failf( + data, + b"HTTP/2 stream %d was not closed cleanly: %s (err %u)\0" as *const u8 + as *const libc::c_char, + (*stream).stream_id, + nghttp2_http2_strerror((*stream).error), + (*stream).error, + ); + *err = CURLE_HTTP2_STREAM; return -1; + } } - } - if !(*stream).bodystarted { - Curl_failf( + if !(*stream).bodystarted { + Curl_failf( data, b"HTTP/2 stream %d was closed cleanly, but before getting all response header fields, treated as error\0" as *const u8 as *const libc::c_char, (*stream).stream_id, ); - *err = CURLE_HTTP2_STREAM; + *err = CURLE_HTTP2_STREAM; return -1; - } + } - if Curl_dyn_len(&mut (*stream).trailer_recvbuf) != 0 { - let mut trailp: *mut libc::c_char = Curl_dyn_ptr(&mut (*stream).trailer_recvbuf); - let mut lf: *mut libc::c_char = 0 as *mut libc::c_char; - loop { + if Curl_dyn_len(&mut (*stream).trailer_recvbuf) != 0 { + let mut trailp: *mut libc::c_char = Curl_dyn_ptr(&mut (*stream).trailer_recvbuf); + let mut lf: *mut libc::c_char = 0 as *mut libc::c_char; + loop { let mut len: size_t = 0 as size_t; - let mut result: CURLcode = CURLE_OK; + let mut result: CURLcode = CURLE_OK; /* each trailer line ends with a newline */ - lf = strchr(trailp, '\n' as i32); - if lf.is_null() { - break; - } + lf = strchr(trailp, '\n' as i32); + if lf.is_null() { + break; + } len = lf.offset(1 as isize).offset_from(trailp) as i64 as size_t; - Curl_debug(data, CURLINFO_HEADER_IN, trailp, len); + Curl_debug(data, CURLINFO_HEADER_IN, trailp, len); /* pass the trailers one by one to the callback */ result = Curl_client_write(data, 1 << 1, trailp, len); if result != 0 { - *err = result; + *err = result; return -1; - } - lf = lf.offset(1); - trailp = lf; - if lf.is_null() { - break; + } + lf = lf.offset(1); + trailp = lf; + if lf.is_null() { + break; + } } } - } (*stream).close_handled = true; return 0 as ssize_t; -} + } } /* @@ -2260,27 +2259,27 @@ extern "C" fn http2_handle_stream_close( extern "C" fn h2_pri_spec(mut data: *mut Curl_easy, pri_spec: *mut nghttp2_priority_spec) { unsafe { let depstream: *mut HTTP = if !((*data).set.stream_depends_on).is_null() { - (*(*data).set.stream_depends_on).req.p.http - } else { - 0 as *mut HTTP - }; + (*(*data).set.stream_depends_on).req.p.http + } else { + 0 as *mut HTTP + }; let depstream_id: int32_t = if !depstream.is_null() { - (*depstream).stream_id - } else { + (*depstream).stream_id + } else { 0 - }; - nghttp2_priority_spec_init( - pri_spec, - depstream_id, - (*data).set.stream_weight, + }; + nghttp2_priority_spec_init( + pri_spec, + depstream_id, + (*data).set.stream_weight, ((*data).set).stream_depends_e() as i32, - ); - (*data).state.stream_weight = (*data).set.stream_weight; + ); + (*data).state.stream_weight = (*data).set.stream_weight; (*data) .state .set_stream_depends_e(((*data).set).stream_depends_e()); (*data).state.stream_depends_on = (*data).set.stream_depends_on; -} + } } /* @@ -2293,46 +2292,46 @@ extern "C" fn h2_session_send(data: *mut Curl_easy, h2: *mut nghttp2_session) -> unsafe { let stream: *mut HTTP = (*data).req.p.http; let httpc: *mut http_conn = &mut (*(*data).conn).proto.httpc; - set_transfer(httpc, data); - if (*data).set.stream_weight != (*data).state.stream_weight + set_transfer(httpc, data); + if (*data).set.stream_weight != (*data).state.stream_weight || ((*data).set).stream_depends_e() != ((*data).state).stream_depends_e() - || (*data).set.stream_depends_on != (*data).state.stream_depends_on - { + || (*data).set.stream_depends_on != (*data).state.stream_depends_on + { /* send new weight and/or dependency */ - let mut pri_spec: nghttp2_priority_spec = nghttp2_priority_spec { - stream_id: 0, - weight: 0, - exclusive: 0, - }; + let mut pri_spec: nghttp2_priority_spec = nghttp2_priority_spec { + stream_id: 0, + weight: 0, + exclusive: 0, + }; let mut rv: i32 = 0; - h2_pri_spec(data, &mut pri_spec); - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*stream).stream_id != -(1 as libc::c_int) {} else { - __assert_fail( - b"stream->stream_id != -1\0" as *const u8 as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 1596 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 59], - &[libc::c_char; 59], - >(b"int h2_session_send(struct Curl_easy *, nghttp2_session *)\0")) + h2_pri_spec(data, &mut pri_spec); + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*stream).stream_id != -(1 as libc::c_int) { + } else { + __assert_fail( + b"stream->stream_id != -1\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 1596 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 59], &[libc::c_char; 59]>( + b"int h2_session_send(struct Curl_easy *, nghttp2_session *)\0", + )) .as_ptr(), - ); - } - rv = nghttp2_submit_priority( - h2, + ); + } + rv = nghttp2_submit_priority( + h2, NGHTTP2_FLAG_NONE as uint8_t, - (*stream).stream_id, - &mut pri_spec, - ); - if rv != 0 { - return rv; + (*stream).stream_id, + &mut pri_spec, + ); + if rv != 0 { + return rv; + } } - } - return nghttp2_session_send(h2); -} + return nghttp2_session_send(h2); + } } #[cfg(USE_NGHTTP2)] @@ -2344,20 +2343,20 @@ extern "C" fn http2_recv( err: *mut CURLcode, ) -> ssize_t { unsafe { - let mut nread: ssize_t = 0; + let mut nread: ssize_t = 0; let conn: *mut connectdata = (*data).conn; - let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; - let mut stream: *mut HTTP = (*data).req.p.http; + let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; + let mut stream: *mut HTTP = (*data).req.p.http; - if should_close_session(httpc) != 0 { - if ((*conn).bits).close() != 0 { + if should_close_session(httpc) != 0 { + if ((*conn).bits).close() != 0 { /* already marked for closure, return OK and we're done */ - *err = CURLE_OK; + *err = CURLE_OK; return 0; - } - *err = CURLE_HTTP2; + } + *err = CURLE_HTTP2; return -1; - } + } /* Nullify here because we call nghttp2_session_send() and they might refer to the old buffer. */ @@ -2370,49 +2369,50 @@ extern "C" fn http2_recv( */ if (*stream).bodystarted as i32 != 0 - && (*stream).nread_header_recvbuf < Curl_dyn_len(&mut (*stream).header_recvbuf) - { + && (*stream).nread_header_recvbuf < Curl_dyn_len(&mut (*stream).header_recvbuf) + { /* If there is header data pending for this stream to return, do that */ let left: size_t = (Curl_dyn_len(&mut (*stream).header_recvbuf)) - .wrapping_sub((*stream).nread_header_recvbuf); + .wrapping_sub((*stream).nread_header_recvbuf); let ncopy: size_t = CURLMIN(len, left); - memcpy( - mem as *mut libc::c_void, - (Curl_dyn_ptr(&mut (*stream).header_recvbuf)) + memcpy( + mem as *mut libc::c_void, + (Curl_dyn_ptr(&mut (*stream).header_recvbuf)) .offset((*stream).nread_header_recvbuf as isize) as *const libc::c_void, - ncopy, - ); + ncopy, + ); (*stream).nread_header_recvbuf = ((*stream).nread_header_recvbuf as u64).wrapping_add(ncopy) as size_t; - return ncopy as ssize_t; - } + return ncopy as ssize_t; + } - if (*data).state.drain != 0 && (*stream).memlen != 0 { - if mem != (*stream).mem { + if (*data).state.drain != 0 && (*stream).memlen != 0 { + if mem != (*stream).mem { /* if we didn't get the same buffer this time, we must move the data to the beginning */ - memmove( - mem as *mut libc::c_void, - (*stream).mem as *const libc::c_void, - (*stream).memlen, - ); - (*stream).len = len.wrapping_sub((*stream).memlen); + memmove( + mem as *mut libc::c_void, + (*stream).mem as *const libc::c_void, + (*stream).memlen, + ); + (*stream).len = len.wrapping_sub((*stream).memlen); (*stream).mem = mem; - } + } if (*httpc).pause_stream_id == (*stream).stream_id && ((*stream).pausedata).is_null() { /* We have paused nghttp2, but we have no pause data (see on_data_chunk_recv). */ (*httpc).pause_stream_id = 0; if h2_process_pending_input(data, httpc, err) != 0 { return -1 as ssize_t; + } } - } - } else if !((*stream).pausedata).is_null() { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*httpc).pause_stream_id == (*stream).stream_id {} else { - __assert_fail( + } else if !((*stream).pausedata).is_null() { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*httpc).pause_stream_id == (*stream).stream_id { + } else { + __assert_fail( b"httpc->pause_stream_id == stream->stream_id\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, @@ -2425,19 +2425,20 @@ extern "C" fn http2_recv( )) .as_ptr(), ); - } - nread = (CURLMIN(len, (*stream).pauselen)) as ssize_t; - memcpy( - mem as *mut libc::c_void, - (*stream).pausedata as *const libc::c_void, + } + nread = (CURLMIN(len, (*stream).pauselen)) as ssize_t; + memcpy( + mem as *mut libc::c_void, + (*stream).pausedata as *const libc::c_void, nread as u64, - ); + ); (*stream).pausedata = ((*stream).pausedata).offset(nread as isize); (*stream).pauselen = ((*stream).pauselen as u64).wrapping_sub(nread as u64) as size_t; if (*stream).pauselen == 0 { - if (*httpc).pause_stream_id == (*stream).stream_id {} else { + if (*httpc).pause_stream_id == (*stream).stream_id { + } else { __assert_fail( b"httpc->pause_stream_id == stream->stream_id\0" as *const u8 as *const libc::c_char, @@ -2466,11 +2467,11 @@ extern "C" fn http2_recv( and stream could be hanged. */ if h2_process_pending_input(data, httpc, err) != 0 { return -1 as ssize_t; + } } - } - return nread; - } else { - if (*httpc).pause_stream_id != 0 { + return nread; + } else { + if (*httpc).pause_stream_id != 0 { /* If a stream paused nghttp2_session_mem_recv previously, and has not processed all data, it still refers to the buffer in nghttp2_session. If we call nghttp2_session_mem_recv(), we may @@ -2479,63 +2480,64 @@ extern "C" fn http2_recv( socket is not read. But it seems that usually streams are notified with its drain property, and socket is read again quickly. */ - if (*stream).closed { + if (*stream).closed { /* closed overrides paused */ return 0; - } - *err = CURLE_AGAIN; + } + *err = CURLE_AGAIN; return -1; - } else { + } else { /* remember where to store incoming data for this stream and how big the buffer is */ (*stream).mem = mem; - (*stream).len = len; + (*stream).len = len; (*stream).memlen = 0 as size_t; if (*httpc).inbuflen == 0 { nread = ((*httpc).recv_underlying).expect("non-null function pointer")( - data, + data, FIRSTSOCKET as i32, - (*httpc).inbuf, + (*httpc).inbuf, H2_BUFSIZE as size_t, - err, - ); + err, + ); if nread == -1 { if *err != CURLE_AGAIN { - Curl_failf( - data, + Curl_failf( + data, b"Failed receiving HTTP2 data\0" as *const u8 as *const i8, - ); - } else if (*stream).closed { + ); + } else if (*stream).closed { /* received when the stream was already closed! */ return http2_handle_stream_close(conn, data, stream, err); - } + } return -1; - } + } if nread == 0 { - if !(*stream).closed { + if !(*stream).closed { /* This will happen when the server or proxy server is SIGKILLed during data transfer. We should emit an error since our data received may be incomplete. */ - Curl_failf( + Curl_failf( data, b"HTTP/2 stream %d was not closed cleanly before end of the underlying stream\0" as *const u8 as *const libc::c_char, (*stream).stream_id, ); - *err = CURLE_HTTP2_STREAM; + *err = CURLE_HTTP2_STREAM; return -1; - } - *err = CURLE_OK; + } + *err = CURLE_OK; return 0; - } + } - (*httpc).inbuflen = nread as size_t; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*httpc).nread_inbuf == 0 as libc::c_int as libc::c_ulong {} else { - __assert_fail( + (*httpc).inbuflen = nread as size_t; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*httpc).nread_inbuf == 0 as libc::c_int as libc::c_ulong { + } else { + __assert_fail( b"httpc->nread_inbuf == 0\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 1770 as libc::c_int as libc::c_uint, @@ -2547,37 +2549,37 @@ extern "C" fn http2_recv( )) .as_ptr(), ); - } - } else { + } + } else { nread = ((*httpc).inbuflen).wrapping_sub((*httpc).nread_inbuf) as ssize_t; - } + } - if h2_process_pending_input(data, httpc, err) != 0 { + if h2_process_pending_input(data, httpc, err) != 0 { return -1; + } } } - } - if (*stream).memlen != 0 { + if (*stream).memlen != 0 { let retlen: ssize_t = (*stream).memlen as ssize_t; (*stream).memlen = 0 as size_t; - if !((*httpc).pause_stream_id == (*stream).stream_id) { + if !((*httpc).pause_stream_id == (*stream).stream_id) { /* data for this stream is returned now, but this stream caused a pause already so we need it called again asap */ - if !(*stream).closed { - drained_transfer(data, httpc); - } else { + if !(*stream).closed { + drained_transfer(data, httpc); + } else { /* this stream is closed, trigger a another read ASAP to detect that */ Curl_expire(data, 0 as timediff_t, EXPIRE_RUN_NOW); + } } + return retlen; } - return retlen; - } - if (*stream).closed { - return http2_handle_stream_close(conn, data, stream, err); - } - *err = CURLE_AGAIN; + if (*stream).closed { + return http2_handle_stream_close(conn, data, stream, err); + } + *err = CURLE_AGAIN; return -1; -} + } } /* @@ -2589,41 +2591,41 @@ extern "C" fn http2_recv( extern "C" fn contains_trailers(mut p: *const i8, len: size_t) -> bool { unsafe { let mut end: *const i8 = p.offset(len as isize); - loop { + loop { while p != end && (*p as i32 == ' ' as i32 || *p as i32 == '\t' as i32) { - p = p.offset(1); - } - if p == end + p = p.offset(1); + } + if p == end || (end.offset_from(p) as size_t) < (::std::mem::size_of::<[i8; 9]>() as u64).wrapping_sub(1 as u64) - { + { return false; - } - if Curl_strncasecompare( + } + if Curl_strncasecompare( b"trailers\0" as *const u8 as *const i8, - p, + p, (::std::mem::size_of::<[i8; 9]>() as u64).wrapping_sub(1 as u64), - ) != 0 - { + ) != 0 + { p = p.offset( (::std::mem::size_of::<[i8; 9]>() as u64).wrapping_sub(1 as u64) as isize, ); while p != end && (*p as i32 == ' ' as i32 || *p as i32 == '\t' as i32) { - p = p.offset(1); - } + p = p.offset(1); + } if p == end || *p as i32 == ',' as i32 { return 1 as i32 != 0; + } } - } /* skip to next token */ while p != end && *p as i32 != ',' as i32 { - p = p.offset(1); - } - if p == end { + p = p.offset(1); + } + if p == end { return false; + } + p = p.offset(1); } - p = p.offset(1); -} } } @@ -2636,73 +2638,73 @@ extern "C" fn inspect_header( valuelen: size_t, ) -> header_instruction { unsafe { - match namelen { - 2 => { + match namelen { + 2 => { if Curl_strncasecompare(b"te\0" as *const u8 as *const i8, name, namelen) == 0 { - return HEADERINST_FORWARD; - } + return HEADERINST_FORWARD; + } return (if contains_trailers(value, valuelen) as i32 != 0 { HEADERINST_TE_TRAILERS as i32 - } else { + } else { HEADERINST_IGNORE as i32 - }) as header_instruction; - } - 7 => { - return (if Curl_strncasecompare( - b"upgrade\0" as *const u8 as *const libc::c_char, - name, - namelen, - ) != 0 - { + }) as header_instruction; + } + 7 => { + return (if Curl_strncasecompare( + b"upgrade\0" as *const u8 as *const libc::c_char, + name, + namelen, + ) != 0 + { HEADERINST_IGNORE - } else { + } else { HEADERINST_FORWARD - }) as header_instruction; - } - 10 => { - return (if Curl_strncasecompare( + }) as header_instruction; + } + 10 => { + return (if Curl_strncasecompare( b"connection\0" as *const u8 as *const i8, - name, - namelen, - ) != 0 - || Curl_strncasecompare( - b"keep-alive\0" as *const u8 as *const i8, name, namelen, ) != 0 - { + || Curl_strncasecompare( + b"keep-alive\0" as *const u8 as *const i8, + name, + namelen, + ) != 0 + { HEADERINST_IGNORE - } else { + } else { HEADERINST_FORWARD - }) as header_instruction; - } - 16 => { - return (if Curl_strncasecompare( + }) as header_instruction; + } + 16 => { + return (if Curl_strncasecompare( b"proxy-connection\0" as *const u8 as *const i8, - name, - namelen, - ) != 0 - { + name, + namelen, + ) != 0 + { HEADERINST_IGNORE - } else { + } else { HEADERINST_FORWARD - }) as header_instruction; - } - 17 => { - return (if Curl_strncasecompare( + }) as header_instruction; + } + 17 => { + return (if Curl_strncasecompare( b"transfer-encoding\0" as *const u8 as *const i8, - name, - namelen, - ) != 0 - { + name, + namelen, + ) != 0 + { HEADERINST_IGNORE - } else { + } else { HEADERINST_FORWARD - }) as header_instruction; - } - _ => return HEADERINST_FORWARD, - }; -} + }) as header_instruction; + } + _ => return HEADERINST_FORWARD, + }; + } } #[cfg(USE_NGHTTP2)] @@ -2751,8 +2753,8 @@ unsafe extern "C" fn http2_send( *err = CURLE_HTTP2_STREAM; return -1; } else if (*stream).closed { - return http2_handle_stream_close(conn, data, stream, err); - } + return http2_handle_stream_close(conn, data, stream, err); + } /* If stream_id != -1, we have dispatched request HEADERS, and now are going to send or sending request body in DATA frame */ (*stream).upload_mem = mem as *const uint8_t; @@ -2813,27 +2815,27 @@ unsafe extern "C" fn http2_send( new headers: :method, :path and :scheme. Therefore we need one more space. */ nheader = nheader.wrapping_add(1); - match () { - #[cfg(not(CURLDEBUG))] - _ => { - nva = Curl_cmalloc.expect("non-null function pointer")( - (::std::mem::size_of::() as u64).wrapping_mul(nheader), - ) as *mut nghttp2_nv; - } - #[cfg(CURLDEBUG)] - _ => { - nva = curl_dbg_malloc( - (::std::mem::size_of::() as libc::c_ulong).wrapping_mul(nheader), - 1978 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ) as *mut nghttp2_nv; - } + match () { + #[cfg(not(CURLDEBUG))] + _ => { + nva = Curl_cmalloc.expect("non-null function pointer")( + (::std::mem::size_of::() as u64).wrapping_mul(nheader), + ) as *mut nghttp2_nv; } - - if nva.is_null() { - *err = CURLE_OUT_OF_MEMORY; - return -1; + #[cfg(CURLDEBUG)] + _ => { + nva = curl_dbg_malloc( + (::std::mem::size_of::() as libc::c_ulong).wrapping_mul(nheader), + 1978 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ) as *mut nghttp2_nv; } + } + + if nva.is_null() { + *err = CURLE_OUT_OF_MEMORY; + return -1; + } /* Extract :method, :path from request line We do line endings with CRLF so checking for CR is enough */ @@ -2843,9 +2845,9 @@ unsafe extern "C" fn http2_send( } /* Method does not contain spaces */ - end = memchr( - hdbuf as *const libc::c_void, - ' ' as i32, + end = memchr( + hdbuf as *const libc::c_void, + ' ' as i32, line_end.offset_from(hdbuf) as i64 as u64, ) as *mut i8; if end.is_null() || end == hdbuf { @@ -2857,10 +2859,10 @@ unsafe extern "C" fn http2_send( (*nva.offset(0)).valuelen = end.offset_from(hdbuf) as size_t; (*nva.offset(0)).flags = NGHTTP2_NV_FLAG_NONE as uint8_t; if HEADER_OVERFLOW(*nva.offset(0 as isize)) { - Curl_failf( - data, + Curl_failf( + data, b"Failed sending HTTP request: Header overflow\0" as *const u8 as *const i8, - ); + ); break 'fail; } @@ -2869,14 +2871,14 @@ unsafe extern "C" fn http2_send( /* Path may contain spaces so scan backwards */ end = 0 as *mut i8; i = line_end.offset_from(hdbuf) as size_t; - while i != 0 { + while i != 0 { if *hdbuf.offset(i.wrapping_sub(1) as isize) as i32 == ' ' as i32 { end = &mut *hdbuf.offset(i.wrapping_sub(1) as isize) as *mut i8; - break; - } else { - i = i.wrapping_sub(1); - } - } + break; + } else { + i = i.wrapping_sub(1); + } + } if end.is_null() || end == hdbuf { break 'fail; } @@ -2886,10 +2888,10 @@ unsafe extern "C" fn http2_send( (*nva.offset(1)).valuelen = end.offset_from(hdbuf) as size_t; (*nva.offset(1)).flags = NGHTTP2_NV_FLAG_NONE as uint8_t; if HEADER_OVERFLOW(*nva.offset(1 as isize)) { - Curl_failf( - data, + Curl_failf( + data, b"Failed sending HTTP request: Header overflow\0" as *const u8 as *const i8, - ); + ); break 'fail; } @@ -2897,118 +2899,118 @@ unsafe extern "C" fn http2_send( (*nva.offset(2)).namelen = strlen((*nva.offset(2)).name as *mut i8); if (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 { (*nva.offset(2)).value = b"https\0" as *const u8 as *const i8 as *mut u8; - } else { + } else { (*nva.offset(2)).value = b"http\0" as *const u8 as *const i8 as *mut u8; - } + } (*nva.offset(2)).valuelen = strlen((*nva.offset(2)).value as *mut i8); (*nva.offset(2)).flags = NGHTTP2_NV_FLAG_NONE as uint8_t; if (*nva.offset(2)).namelen > 0xffff as u64 || (*nva.offset(2)).valuelen > (0xffff as u64).wrapping_sub((*nva.offset(2)).namelen) - { - Curl_failf( - data, + { + Curl_failf( + data, b"Failed sending HTTP request: Header overflow\0" as *const u8 as *const i8, - ); + ); break 'fail; - } + } authority_idx = 0; i = 3; while i < nheader { - let mut hlen: size_t = 0; + let mut hlen: size_t = 0; hdbuf = line_end.offset(2); /* check for next CR, but only within the piece of data left in the given buffer */ - line_end = memchr( - hdbuf as *const libc::c_void, - '\r' as i32, + line_end = memchr( + hdbuf as *const libc::c_void, + '\r' as i32, len.wrapping_sub(hdbuf.offset_from(mem as *mut i8) as u64), ) as *mut i8; /* header continuation lines are not supported */ - if line_end.is_null() || line_end == hdbuf { + if line_end.is_null() || line_end == hdbuf { break 'fail; - } + } if *hdbuf as i32 == ' ' as i32 || *hdbuf as i32 == '\t' as i32 { break 'fail; - } + } - end = hdbuf; + end = hdbuf; while end < line_end && *end as i32 != ':' as i32 { - end = end.offset(1); - } - if end == hdbuf || end == line_end { + end = end.offset(1); + } + if end == hdbuf || end == line_end { break 'fail; - } + } hlen = end.offset_from(hdbuf) as size_t; if hlen == 4 && Curl_strncasecompare(b"host\0" as *const u8 as *const i8, hdbuf, 4) != 0 - { - authority_idx = i; + { + authority_idx = i; (*nva.offset(i as isize)).name = b":authority\0" as *const u8 as *const i8 as *mut u8; (*nva.offset(i as isize)).namelen = strlen((*nva.offset(i as isize)).name as *mut i8); - } else { + } else { (*nva.offset(i as isize)).namelen = end.offset_from(hdbuf) as size_t; /* Lower case the header name for HTTP/2 */ Curl_strntolower(hdbuf, hdbuf, (*nva.offset(i as isize)).namelen); (*nva.offset(i as isize)).name = hdbuf as *mut u8; - } + } hdbuf = end.offset(1); while *hdbuf as i32 == ' ' as i32 || *hdbuf as i32 == '\t' as i32 { - hdbuf = hdbuf.offset(1); - } - end = line_end; + hdbuf = hdbuf.offset(1); + } + end = line_end; const HEADERINST_IGNORE: u32 = 1; const HEADERINST_TE_TRAILERS: u32 = 2; - match inspect_header( + match inspect_header( (*nva.offset(i as isize)).name as *const i8, - (*nva.offset(i as isize)).namelen, - hdbuf, + (*nva.offset(i as isize)).namelen, + hdbuf, end.offset_from(hdbuf) as size_t, ) as u32 - { + { HEADERINST_IGNORE => { - nheader = nheader.wrapping_sub(1); - continue; - } + nheader = nheader.wrapping_sub(1); + continue; + } HEADERINST_TE_TRAILERS => { (*nva.offset(i as isize)).value = b"trailers\0" as *const u8 as *const i8 as *mut uint8_t; (*nva.offset(i as isize)).valuelen = (::std::mem::size_of::<[i8; 9]>() as u64).wrapping_sub(1); - } - _ => { + } + _ => { (*nva.offset(i as isize)).value = hdbuf as *mut u8; (*nva.offset(i as isize)).valuelen = end.offset_from(hdbuf) as size_t; - } - } + } + } (*nva.offset(i as isize)).flags = NGHTTP2_NV_FLAG_NONE as uint8_t; if HEADER_OVERFLOW(*nva.offset(i as isize)) { - Curl_failf( - data, + Curl_failf( + data, b"Failed sending HTTP request: Header overflow\0" as *const u8 as *const i8, - ); + ); break 'fail; } - i = i.wrapping_add(1); - } + i = i.wrapping_add(1); + } /* :authority must come before non-pseudo header fields */ if authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX { let mut authority: nghttp2_nv = *nva.offset(authority_idx as isize); - i = authority_idx; + i = authority_idx; while i > AUTHORITY_DST_IDX { *nva.offset(i as isize) = *nva.offset(i.wrapping_sub(1) as isize); - i = i.wrapping_sub(1); - } - *nva.offset(i as isize) = authority; - } + i = i.wrapping_sub(1); + } + *nva.offset(i as isize) = authority; + } /* Warn stream may be rejected if cumulative length of headers is too large. It appears nghttp2 will not send a header frame larger than 64KB. */ @@ -3016,100 +3018,100 @@ unsafe extern "C" fn http2_send( let mut acc: size_t = 0; i = 0; - while i < nheader { + while i < nheader { acc = (acc as u64).wrapping_add( - ((*nva.offset(i as isize)).namelen) - .wrapping_add((*nva.offset(i as isize)).valuelen), + ((*nva.offset(i as isize)).namelen) + .wrapping_add((*nva.offset(i as isize)).valuelen), ) as size_t; - i = i.wrapping_add(1); - } + i = i.wrapping_add(1); + } if acc > MAX_ACC { - Curl_infof( + Curl_infof( data, b"http2_send: Warning: The cumulative length of all headers exceeds %d bytes and that could cause the stream to be rejected.\0" as *const u8 as *const i8, MAX_ACC, ); - } + } - h2_pri_spec(data, &mut pri_spec); + h2_pri_spec(data, &mut pri_spec); match (*data).state.httpreq as u32 { HTTPREQ_POST | HTTPREQ_POST_FORM | HTTPREQ_POST_MIME | HTTPREQ_PUT => { if (*data).state.infilesize != -1 { - (*stream).upload_left = (*data).state.infilesize; - } else { + (*stream).upload_left = (*data).state.infilesize; + } else { /* data sending without specifying the data amount up front */ (*stream).upload_left = -1; /* unknown, but not zero */ - } + } data_prd.read_callback = Some( - data_source_read_callback - as unsafe extern "C" fn( - *mut nghttp2_session, - int32_t, - *mut uint8_t, - size_t, - *mut uint32_t, - *mut nghttp2_data_source, - *mut libc::c_void, - ) -> ssize_t, - ); - data_prd.source.ptr = 0 as *mut libc::c_void; - stream_id = nghttp2_submit_request( - h2, - &mut pri_spec, - nva, - nheader, - &mut data_prd, - data as *mut libc::c_void, - ); - } - _ => { - stream_id = nghttp2_submit_request( - h2, - &mut pri_spec, - nva, - nheader, - 0 as *const nghttp2_data_provider, - data as *mut libc::c_void, - ); - } - } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(nva as *mut libc::c_void); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - nva as *mut libc::c_void, - 2157 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ); - nva = 0 as *mut nghttp2_nv; + data_source_read_callback + as unsafe extern "C" fn( + *mut nghttp2_session, + int32_t, + *mut uint8_t, + size_t, + *mut uint32_t, + *mut nghttp2_data_source, + *mut libc::c_void, + ) -> ssize_t, + ); + data_prd.source.ptr = 0 as *mut libc::c_void; + stream_id = nghttp2_submit_request( + h2, + &mut pri_spec, + nva, + nheader, + &mut data_prd, + data as *mut libc::c_void, + ); + } + _ => { + stream_id = nghttp2_submit_request( + h2, + &mut pri_spec, + nva, + nheader, + 0 as *const nghttp2_data_provider, + data as *mut libc::c_void, + ); + } + } + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(nva as *mut libc::c_void); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + nva as *mut libc::c_void, + 2157 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ); + nva = 0 as *mut nghttp2_nv; if stream_id < 0 { - *err = CURLE_SEND_ERROR; + *err = CURLE_SEND_ERROR; return -1; - } + } - Curl_infof( - data, + Curl_infof( + data, b"Using Stream ID: %x (easy handle %p)\0" as *const u8 as *const i8, - stream_id, - data as *mut libc::c_void, - ); - (*stream).stream_id = stream_id; - - rv = h2_session_send(data, h2); - if rv != 0 { - *err = CURLE_SEND_ERROR; + stream_id, + data as *mut libc::c_void, + ); + (*stream).stream_id = stream_id; + + rv = h2_session_send(data, h2); + if rv != 0 { + *err = CURLE_SEND_ERROR; return -1; - } + } - if should_close_session(httpc) != 0 { - *err = CURLE_HTTP2; + if should_close_session(httpc) != 0 { + *err = CURLE_HTTP2; return -1; - } + } /* If whole HEADERS frame was sent off to the underlying socket, the nghttp2 library calls data_source_read_callback. But only it found that no data @@ -3118,15 +3120,13 @@ unsafe extern "C" fn http2_send( results that no writable socket check is performed. To workaround this, we issue nghttp2_session_resume_data() here to bring back DATA transmission from deferred state. */ - nghttp2_session_resume_data(h2, (*stream).stream_id); - return len as ssize_t; - } - #[cfg(not(CURLDEBUG))] + nghttp2_session_resume_data(h2, (*stream).stream_id); + return len as ssize_t; + } + #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(nva as *mut libc::c_void); - - - #[cfg(CURLDEBUG)] + #[cfg(CURLDEBUG)] curl_dbg_free( nva as *mut libc::c_void, 2199 as libc::c_int, @@ -3140,22 +3140,22 @@ unsafe extern "C" fn http2_send( #[no_mangle] pub extern "C" fn Curl_http2_setup(data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { unsafe { - let mut result: CURLcode = CURLE_OK; - let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; - let mut stream: *mut HTTP = (*data).req.p.http; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !((*data).state.buffer).is_null() {} else { - __assert_fail( - b"data->state.buffer\0" as *const u8 as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 2211 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 68], - &[libc::c_char; 68], - >(b"CURLcode Curl_http2_setup(struct Curl_easy *, struct connectdata *)\0")) + let mut result: CURLcode = CURLE_OK; + let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; + let mut stream: *mut HTTP = (*data).req.p.http; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !((*data).state.buffer).is_null() { + } else { + __assert_fail( + b"data->state.buffer\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 2211 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 68], &[libc::c_char; 68]>( + b"CURLcode Curl_http2_setup(struct Curl_easy *, struct connectdata *)\0", + )) .as_ptr(), - ); - } + ); + } (*stream).stream_id = -1; @@ -3166,32 +3166,32 @@ pub extern "C" fn Curl_http2_setup(data: *mut Curl_easy, mut conn: *mut connectd (*stream).upload_mem = 0 as *const uint8_t; (*stream).upload_len = 0 as size_t; (*stream).mem = (*data).state.buffer; - (*stream).len = (*data).set.buffer_size as size_t; + (*stream).len = (*data).set.buffer_size as size_t; - multi_connchanged((*data).multi); + multi_connchanged((*data).multi); /* below this point only connection related inits are done, which only needs to be done once per connection */ - if (*conn).handler == &Curl_handler_http2_ssl as *const Curl_handler - || (*conn).handler == &Curl_handler_http2 as *const Curl_handler - { + if (*conn).handler == &Curl_handler_http2_ssl as *const Curl_handler + || (*conn).handler == &Curl_handler_http2 as *const Curl_handler + { return CURLE_OK; /* already done */ - } + } if (*(*conn).handler).flags & ((1) << 0) as u32 != 0 { (*conn).handler = &Curl_handler_http2_ssl; - } else { + } else { (*conn).handler = &Curl_handler_http2; - } - result = http2_init(data, conn); - if result as u64 != 0 { - Curl_dyn_free(&mut (*stream).header_recvbuf); - return result; - } - Curl_infof( - data, + } + result = http2_init(data, conn); + if result as u64 != 0 { + Curl_dyn_free(&mut (*stream).header_recvbuf); + return result; + } + Curl_infof( + data, b"Using HTTP2, server supports multiplexing\0" as *const u8 as *const i8, - ); + ); ((*conn).bits).set_multiplex(1 as bit); (*conn).httpversion = 20 as u8; (*(*conn).bundle).multiuse = 2; @@ -3199,12 +3199,12 @@ pub extern "C" fn Curl_http2_setup(data: *mut Curl_easy, mut conn: *mut connectd (*httpc).nread_inbuf = 0 as size_t; (*httpc).pause_stream_id = 0; (*httpc).drain_total = 0 as size_t; - Curl_infof( - data, + Curl_infof( + data, b"Connection state changed (HTTP/2 confirmed)\0" as *const u8 as *const i8, - ); - return CURLE_OK; -} + ); + return CURLE_OK; + } } #[cfg(USE_NGHTTP2)] @@ -3215,211 +3215,206 @@ pub extern "C" fn Curl_http2_switched( nread: size_t, ) -> CURLcode { unsafe { - let mut result: CURLcode = CURLE_OK; + let mut result: CURLcode = CURLE_OK; let conn: *mut connectdata = (*data).conn; - let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; + let mut httpc: *mut http_conn = &mut (*conn).proto.httpc; let mut rv: i32 = 0; - let mut stream: *mut HTTP = (*data).req.p.http; + let mut stream: *mut HTTP = (*data).req.p.http; - result = Curl_http2_setup(data, conn); + result = Curl_http2_setup(data, conn); if result != 0 { - return result; - } + return result; + } (*httpc).recv_underlying = (*conn).recv[FIRSTSOCKET]; (*httpc).send_underlying = (*conn).send[FIRSTSOCKET]; (*conn).recv[FIRSTSOCKET] = Some( - http2_recv + http2_recv as extern "C" fn(*mut Curl_easy, i32, *mut i8, size_t, *mut CURLcode) -> ssize_t, - ); + ); (*conn).send[FIRSTSOCKET] = Some( - http2_send - as unsafe extern "C" fn( - *mut Curl_easy, + http2_send + as unsafe extern "C" fn( + *mut Curl_easy, i32, - *const libc::c_void, - size_t, - *mut CURLcode, - ) -> ssize_t, - ); + *const libc::c_void, + size_t, + *mut CURLcode, + ) -> ssize_t, + ); if (*data).req.upgr101 == UPGR101_RECEIVED { /* stream 1 is opened implicitly on upgrade */ (*stream).stream_id = 1; /* queue SETTINGS frame (again) */ - rv = nghttp2_session_upgrade2( - (*httpc).h2, - ((*httpc).binsettings).as_mut_ptr(), - (*httpc).binlen, + rv = nghttp2_session_upgrade2( + (*httpc).h2, + ((*httpc).binsettings).as_mut_ptr(), + (*httpc).binlen, ((*data).state.httpreq == HTTPREQ_HEAD) as i32, - 0 as *mut libc::c_void, - ); - - if rv != 0 { - Curl_failf( - data, - b"nghttp2_session_upgrade2() failed: %s(%d)\0" as *const u8 as *const i8, - nghttp2_strerror(rv), - rv, + 0 as *mut libc::c_void, ); - return CURLE_HTTP2; - } - rv = nghttp2_session_set_stream_user_data( - (*httpc).h2, - (*stream).stream_id, - data as *mut libc::c_void, - ); + if rv != 0 { + Curl_failf( + data, + b"nghttp2_session_upgrade2() failed: %s(%d)\0" as *const u8 as *const i8, + nghttp2_strerror(rv), + rv, + ); + return CURLE_HTTP2; + } - if rv != 0 { - Curl_infof( - data, - b"http/2: failed to set user_data for stream %d!\0" as *const u8 as *const i8, + rv = nghttp2_session_set_stream_user_data( + (*httpc).h2, (*stream).stream_id, + data as *mut libc::c_void, ); - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - __assert_fail( - b"0\0" as *const u8 as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 2296 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 71], - &[libc::c_char; 71], - >( - b"CURLcode Curl_http2_switched(struct Curl_easy *, const char *, size_t)\0", - )) + + if rv != 0 { + Curl_infof( + data, + b"http/2: failed to set user_data for stream %d!\0" as *const u8 as *const i8, + (*stream).stream_id, + ); + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + __assert_fail( + b"0\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 2296 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 71], &[libc::c_char; 71]>( + b"CURLcode Curl_http2_switched(struct Curl_easy *, const char *, size_t)\0", + )) .as_ptr(), - ); - } - } else { - populate_settings(data, httpc); + ); + } + } else { + populate_settings(data, httpc); /* stream ID is unknown at this point */ (*stream).stream_id = -1; - rv = nghttp2_submit_settings( - (*httpc).h2, + rv = nghttp2_submit_settings( + (*httpc).h2, NGHTTP2_FLAG_NONE as uint8_t, - ((*httpc).local_settings).as_mut_ptr(), - (*httpc).local_settings_num, + ((*httpc).local_settings).as_mut_ptr(), + (*httpc).local_settings_num, + ); + if rv != 0 { + Curl_failf( + data, + b"nghttp2_submit_settings() failed: %s(%d)\0" as *const u8 as *const i8, + nghttp2_strerror(rv), + rv, + ); + return CURLE_HTTP2; + } + } + + rv = nghttp2_session_set_local_window_size( + (*httpc).h2, + NGHTTP2_FLAG_NONE as uint8_t, + 0, + 32 * 1024 * 1024, ); + if rv != 0 { Curl_failf( data, - b"nghttp2_submit_settings() failed: %s(%d)\0" as *const u8 as *const i8, + b"nghttp2_session_set_local_window_size() failed: %s(%d)\0" as *const u8 + as *const libc::c_char, nghttp2_strerror(rv), rv, ); return CURLE_HTTP2; } - } - - rv = nghttp2_session_set_local_window_size( - (*httpc).h2, - NGHTTP2_FLAG_NONE as uint8_t, - 0, - 32 * 1024 * 1024, - ); - - if rv != 0 { - Curl_failf( - data, - b"nghttp2_session_set_local_window_size() failed: %s(%d)\0" as *const u8 - as *const libc::c_char, - nghttp2_strerror(rv), - rv, - ); - return CURLE_HTTP2; - } /* we are going to copy mem to httpc->inbuf. This is required since mem is part of buffer pointed by stream->mem, and callbacks called by nghttp2_session_mem_recv() will write stream specific data into stream->mem, overwriting data already there. */ if H2_BUFSIZE < nread { - Curl_failf( + Curl_failf( data, b"connection buffer size is too small to store data following HTTP Upgrade response header: buflen=%d, datalen=%zu\0" as *const u8 as *const i8, H2_BUFSIZE , nread, ); - return CURLE_HTTP2; - } + return CURLE_HTTP2; + } - Curl_infof( - data, - b"Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=%zu\0" + Curl_infof( + data, + b"Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=%zu\0" as *const u8 as *const i8, - nread, - ); + nread, + ); - if nread != 0 { + if nread != 0 { memcpy( (*httpc).inbuf as *mut libc::c_void, mem as *const libc::c_void, nread, ); - } + } - (*httpc).inbuflen = nread; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*httpc).nread_inbuf == 0 as libc::c_int as libc::c_ulong {} else { - __assert_fail( - b"httpc->nread_inbuf == 0\0" as *const u8 as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 2342 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 71], - &[libc::c_char; 71], - >( - b"CURLcode Curl_http2_switched(struct Curl_easy *, const char *, size_t)\0", - )) + (*httpc).inbuflen = nread; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*httpc).nread_inbuf == 0 as libc::c_int as libc::c_ulong { + } else { + __assert_fail( + b"httpc->nread_inbuf == 0\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 2342 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 71], &[libc::c_char; 71]>( + b"CURLcode Curl_http2_switched(struct Curl_easy *, const char *, size_t)\0", + )) .as_ptr(), - ); - } + ); + } if -1 == h2_process_pending_input(data, httpc, &mut result) { - return CURLE_HTTP2; - } + return CURLE_HTTP2; + } - return CURLE_OK; - } + return CURLE_OK; } +} #[cfg(USE_NGHTTP2)] #[no_mangle] pub extern "C" fn Curl_http2_stream_pause(data: *mut Curl_easy, pause: bool) -> CURLcode { unsafe { #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !data.is_null() {} else { + if !data.is_null() { + } else { __assert_fail( b"data\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 2352 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 60], - &[libc::c_char; 60], - >(b"CURLcode Curl_http2_stream_pause(struct Curl_easy *, _Bool)\0")) - .as_ptr(), + (*::std::mem::transmute::<&[u8; 60], &[libc::c_char; 60]>( + b"CURLcode Curl_http2_stream_pause(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), ); } #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !((*data).conn).is_null() {} else { + if !((*data).conn).is_null() { + } else { __assert_fail( b"data->conn\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 2353 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 60], - &[libc::c_char; 60], - >(b"CURLcode Curl_http2_stream_pause(struct Curl_easy *, _Bool)\0")) - .as_ptr(), + (*::std::mem::transmute::<&[u8; 60], &[libc::c_char; 60]>( + b"CURLcode Curl_http2_stream_pause(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), ); } if (*(*(*data).conn).handler).protocol & PROTO_FAMILY_HTTP == 0 - || ((*(*data).conn).proto.httpc.h2).is_null() - { + || ((*(*data).conn).proto.httpc.h2).is_null() + { return CURLE_OK; - } else { + } else { match () { #[cfg(NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE)] _ => { @@ -3427,52 +3422,52 @@ pub extern "C" fn Curl_http2_stream_pause(data: *mut Curl_easy, pause: bool) -> let httpc: *mut http_conn = &mut (*(*data).conn).proto.httpc; let window: uint32_t = (!pause as i32 * HTTP2_HUGE_WINDOW_SIZE) as uint32_t; let mut rv: i32 = nghttp2_session_set_local_window_size( - (*httpc).h2, + (*httpc).h2, NGHTTP2_FLAG_NONE as uint8_t, - (*stream).stream_id, - window as int32_t, - ); - if rv != 0 { - Curl_failf( - data, - b"nghttp2_session_set_local_window_size() failed: %s(%d)\0" as *const u8 + (*stream).stream_id, + window as int32_t, + ); + if rv != 0 { + Curl_failf( + data, + b"nghttp2_session_set_local_window_size() failed: %s(%d)\0" as *const u8 as *const i8, - nghttp2_strerror(rv), - rv, - ); - return CURLE_HTTP2; - } - rv = h2_session_send(data, (*httpc).h2); - if rv != 0 { - return CURLE_SEND_ERROR; + nghttp2_strerror(rv), + rv, + ); + return CURLE_HTTP2; + } + rv = h2_session_send(data, (*httpc).h2); + if rv != 0 { + return CURLE_SEND_ERROR; + } + #[cfg(DEBUGBUILD)] + Curl_infof( + data, + b"Set HTTP/2 window size to %u for stream %u\0" as *const u8 + as *const libc::c_char, + window, + (*stream).stream_id, + ); + let mut window2: uint32_t = nghttp2_session_get_stream_local_window_size( + (*httpc).h2, + (*stream).stream_id, + ) as uint32_t; + #[cfg(DEBUGBUILD)] + Curl_infof( + data, + b"HTTP/2 window size is now %u for stream %u\0" as *const u8 + as *const libc::c_char, + window2, + (*stream).stream_id, + ); + } + #[cfg(not(NGHTTP2_HAS_SET_LOCAL_WINDOWS_SIZE))] + _ => {} + } } - #[cfg(DEBUGBUILD)] - Curl_infof( - data, - b"Set HTTP/2 window size to %u for stream %u\0" as *const u8 - as *const libc::c_char, - window, - (*stream).stream_id, - ); - let mut window2: uint32_t = nghttp2_session_get_stream_local_window_size( - (*httpc).h2, - (*stream).stream_id, - ) as uint32_t; - #[cfg(DEBUGBUILD)] - Curl_infof( - data, - b"HTTP/2 window size is now %u for stream %u\0" as *const u8 - as *const libc::c_char, - window2, - (*stream).stream_id, - ); + return CURLE_OK; } - #[cfg(not(NGHTTP2_HAS_SET_LOCAL_WINDOWS_SIZE))] - _ => {} -} - } - return CURLE_OK; -} } #[cfg(USE_NGHTTP2)] @@ -3483,40 +3478,40 @@ pub extern "C" fn Curl_http2_add_child( exclusive: bool, ) -> CURLcode { unsafe { - if !parent.is_null() { - let mut tail: *mut *mut Curl_http2_dep = 0 as *mut *mut Curl_http2_dep; - #[cfg(not(CURLDEBUG))] - - let mut dep: *mut Curl_http2_dep = Curl_ccalloc.expect("non-null function pointer")( - 1 as size_t, - ::std::mem::size_of::() as u64, - ) as *mut Curl_http2_dep; - - #[cfg(CURLDEBUG)] - let mut dep: *mut Curl_http2_dep = curl_dbg_calloc( - 1 as libc::c_int as size_t, - ::std::mem::size_of::() as libc::c_ulong, - 2402 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ) as *mut Curl_http2_dep; - if dep.is_null() { - return CURLE_OUT_OF_MEMORY; - } + if !parent.is_null() { + let mut tail: *mut *mut Curl_http2_dep = 0 as *mut *mut Curl_http2_dep; + #[cfg(not(CURLDEBUG))] + let mut dep: *mut Curl_http2_dep = Curl_ccalloc.expect("non-null function pointer")( + 1 as size_t, + ::std::mem::size_of::() as u64, + ) as *mut Curl_http2_dep; + + #[cfg(CURLDEBUG)] + let mut dep: *mut Curl_http2_dep = curl_dbg_calloc( + 1 as libc::c_int as size_t, + ::std::mem::size_of::() as libc::c_ulong, + 2402 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ) as *mut Curl_http2_dep; + if dep.is_null() { + return CURLE_OUT_OF_MEMORY; + } (*dep).data = child; if !((*parent).set.stream_dependents).is_null() && exclusive as i32 != 0 { - let mut node: *mut Curl_http2_dep = (*parent).set.stream_dependents; - while !node.is_null() { + let mut node: *mut Curl_http2_dep = (*parent).set.stream_dependents; + while !node.is_null() { (*(*node).data).set.stream_depends_on = child; - node = (*node).next; - } - tail = &mut (*child).set.stream_dependents; - while !(*tail).is_null() { - tail = &mut (**tail).next; - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*tail).is_null() {} else { - __assert_fail( + node = (*node).next; + } + tail = &mut (*child).set.stream_dependents; + while !(*tail).is_null() { + tail = &mut (**tail).next; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*tail).is_null() { + } else { + __assert_fail( b"!*tail\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 2418 as libc::c_int as libc::c_uint, @@ -3528,19 +3523,20 @@ pub extern "C" fn Curl_http2_add_child( )) .as_ptr(), ); - } - *tail = (*parent).set.stream_dependents; + } + *tail = (*parent).set.stream_dependents; (*parent).set.stream_dependents = 0 as *mut Curl_http2_dep; - } + } - tail = &mut (*parent).set.stream_dependents; - while !(*tail).is_null() { + tail = &mut (*parent).set.stream_dependents; + while !(*tail).is_null() { (*(**tail).data).set.set_stream_depends_e(0 as bit); - tail = &mut (**tail).next; - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*tail).is_null() {} else { - __assert_fail( + tail = &mut (**tail).next; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*tail).is_null() { + } else { + __assert_fail( b"!*tail\0" as *const u8 as *const libc::c_char, b"http2.c\0" as *const u8 as *const libc::c_char, 2429 as libc::c_int as libc::c_uint, @@ -3552,89 +3548,88 @@ pub extern "C" fn Curl_http2_add_child( )) .as_ptr(), ); + } + *tail = dep; } - *tail = dep; - } (*child).set.stream_depends_on = parent; (*child).set.set_stream_depends_e(exclusive as bit); - return CURLE_OK; -} + return CURLE_OK; + } } #[cfg(USE_NGHTTP2)] #[no_mangle] pub extern "C" fn Curl_http2_remove_child(parent: *mut Curl_easy, child: *mut Curl_easy) { unsafe { - let mut last: *mut Curl_http2_dep = 0 as *mut Curl_http2_dep; - let mut data: *mut Curl_http2_dep = (*parent).set.stream_dependents; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*child).set.stream_depends_on == parent {} else { - __assert_fail( - b"child->set.stream_depends_on == parent\0" as *const u8 - as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 2442 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 69], - &[libc::c_char; 69], - >(b"void Curl_http2_remove_child(struct Curl_easy *, struct Curl_easy *)\0")) + let mut last: *mut Curl_http2_dep = 0 as *mut Curl_http2_dep; + let mut data: *mut Curl_http2_dep = (*parent).set.stream_dependents; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*child).set.stream_depends_on == parent { + } else { + __assert_fail( + b"child->set.stream_depends_on == parent\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 2442 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( + b"void Curl_http2_remove_child(struct Curl_easy *, struct Curl_easy *)\0", + )) .as_ptr(), - ); - } - while !data.is_null() && (*data).data != child { - last = data; - data = (*data).next; - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !data.is_null() {} else { - __assert_fail( - b"data\0" as *const u8 as *const libc::c_char, - b"http2.c\0" as *const u8 as *const libc::c_char, - 2449 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 69], - &[libc::c_char; 69], - >(b"void Curl_http2_remove_child(struct Curl_easy *, struct Curl_easy *)\0")) + ); + } + while !data.is_null() && (*data).data != child { + last = data; + data = (*data).next; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !data.is_null() { + } else { + __assert_fail( + b"data\0" as *const u8 as *const libc::c_char, + b"http2.c\0" as *const u8 as *const libc::c_char, + 2449 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( + b"void Curl_http2_remove_child(struct Curl_easy *, struct Curl_easy *)\0", + )) .as_ptr(), - ); - } - if !data.is_null() { - if !last.is_null() { + ); + } + if !data.is_null() { + if !last.is_null() { (*last).next = (*data).next; - } else { + } else { (*parent).set.stream_dependents = (*data).next; + } + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(data as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + data as *mut libc::c_void, + 2458 as libc::c_int, + b"http2.c\0" as *const u8 as *const libc::c_char, + ); } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(data as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - data as *mut libc::c_void, - 2458 as libc::c_int, - b"http2.c\0" as *const u8 as *const libc::c_char, - ); - } (*child).set.stream_depends_on = 0 as *mut Curl_easy; (*child).set.set_stream_depends_e(0 as bit); -} + } } #[cfg(USE_NGHTTP2)] #[no_mangle] pub extern "C" fn Curl_http2_cleanup_dependencies(data: *mut Curl_easy) { unsafe { - while !((*data).set.stream_dependents).is_null() { - let mut tmp: *mut Curl_easy = (*(*data).set.stream_dependents).data; - Curl_http2_remove_child(data, tmp); - if !((*data).set.stream_depends_on).is_null() { + while !((*data).set.stream_dependents).is_null() { + let mut tmp: *mut Curl_easy = (*(*data).set.stream_dependents).data; + Curl_http2_remove_child(data, tmp); + if !((*data).set.stream_depends_on).is_null() { Curl_http2_add_child((*data).set.stream_depends_on, tmp, false); + } } - } - if !((*data).set.stream_depends_on).is_null() { - Curl_http2_remove_child((*data).set.stream_depends_on, data); - } + if !((*data).set.stream_depends_on).is_null() { + Curl_http2_remove_child((*data).set.stream_depends_on, data); + } } } diff --git a/rust/rust_project/src/http_aws_sigv4.rs b/rust/rust_project/src/http_aws_sigv4.rs index a5f7670..8422c39 100644 --- a/rust/rust_project/src/http_aws_sigv4.rs +++ b/rust/rust_project/src/http_aws_sigv4.rs @@ -12,557 +12,643 @@ * Create: 2022-10-31 * Description: http aws sigv4 ******************************************************************************/ - use ::libc; - use rust_ffi::src::ffi_alias::type_alias::*; - use rust_ffi::src::ffi_fun::fun_call::*; - use rust_ffi::src::ffi_struct::struct_define::*; - - extern "C" fn sha256_to_hex(mut dst: *mut libc::c_char, mut sha: *mut u8, mut dst_l: size_t) { - let mut i: i32 = 0; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if dst_l >= 65 as libc::c_int as u64 { - } else { - unsafe{ - __assert_fail( - b"dst_l >= 65\0" as *const u8 as *const libc::c_char, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - 63, - (*::std::mem::transmute::<&[u8; 52], &[libc::c_char; 52]>( - b"void sha256_to_hex(char *, unsigned char *, size_t)\0", - )) - .as_ptr(), - );} - } - i = 0 as i32; - while i < 32 as i32 { - unsafe{ - curl_msnprintf( - dst.offset((i * 2 as i32) as isize), - dst_l.wrapping_sub((i * 2 as i32) as u64), - b"%02x\0" as *const u8 as *const libc::c_char, - *sha.offset(i as isize) as i32, - );} - i += 1; - } - } - #[no_mangle] - pub extern "C" fn Curl_output_aws_sigv4(mut data: *mut Curl_easy, mut proxy: bool) -> CURLcode { - let mut current_block: u64; - let mut ret: CURLcode = CURLE_OUT_OF_MEMORY; - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut len: size_t = 0; - let mut tmp0: *const libc::c_char = 0 as *const libc::c_char; - let mut tmp1: *const libc::c_char = 0 as *const libc::c_char; - let mut provider0_low: *mut libc::c_char = 0 as *mut libc::c_char; - let mut provider0_up: *mut libc::c_char = 0 as *mut libc::c_char; - let mut provider1_low: *mut libc::c_char = 0 as *mut libc::c_char; - let mut provider1_mid: *mut libc::c_char = 0 as *mut libc::c_char; - let mut region: *mut libc::c_char = 0 as *mut libc::c_char; - let mut service: *mut libc::c_char = 0 as *mut libc::c_char; - let mut hostname: *const libc::c_char =unsafe{ (*conn).host.name}; - #[cfg(DEBUGBUILD)] - let mut force_timestamp: *mut libc::c_char = 0 as *mut libc::c_char; - let mut clock: time_t = 0; - let mut tm: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *const libc::c_char, - }; - let mut timestamp: [libc::c_char; 17] = [0; 17]; - let mut date: [libc::c_char; 9] = [0; 9]; - let mut content_type: *const libc::c_char =unsafe{ - Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char)}; - let mut canonical_headers: *mut libc::c_char = 0 as *mut libc::c_char; - let mut signed_headers: *mut libc::c_char = 0 as *mut libc::c_char; - let mut httpreq: Curl_HttpReq = HTTPREQ_GET; - let mut method: *const libc::c_char = 0 as *const libc::c_char; - let mut post_data: *const libc::c_char = (if unsafe{!((*data).set.postfields).is_null() }{ - unsafe{ - (*data).set.postfields} - } else { - b"\0" as *const u8 as *const libc::c_char as *const libc::c_void - }) as *const libc::c_char; - let mut sha_hash: [u8; 32] = [0; 32]; - let mut sha_hex: [libc::c_char; 65] = [0; 65]; - let mut canonical_request: *mut libc::c_char = 0 as *mut libc::c_char; - let mut request_type: *mut libc::c_char = 0 as *mut libc::c_char; - let mut credential_scope: *mut libc::c_char = 0 as *mut libc::c_char; - let mut str_to_sign: *mut libc::c_char = 0 as *mut libc::c_char; - let mut user: *const libc::c_char = if unsafe{!((*data).state.aptr.user).is_null()} { - unsafe{(*data).state.aptr.user as *const libc::c_char} - } else { - b"\0" as *const u8 as *const libc::c_char - }; - let mut passwd: *const libc::c_char = if unsafe{!((*data).state.aptr.passwd).is_null()} { - unsafe{(*data).state.aptr.passwd as *const libc::c_char} - } else { - b"\0" as *const u8 as *const libc::c_char - }; - let mut secret: *mut libc::c_char = 0 as *mut libc::c_char; - let mut tmp_sign0: [u8; 32] = [ - 0 as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - ]; - let mut tmp_sign1: [u8; 32] = [ - 0 as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - ]; - let mut auth_headers: *mut libc::c_char = 0 as *mut libc::c_char; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !proxy { - } else { - unsafe{ - __assert_fail( - b"!proxy\0" as *const u8 as *const libc::c_char, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - 109, - (*::std::mem::transmute::<&[u8; 58], &[libc::c_char; 58]>( - b"CURLcode Curl_output_aws_sigv4(struct Curl_easy *, _Bool)\0", - )) - .as_ptr(), - );} - } - if unsafe{!(Curl_checkheaders(data, b"Authorization\0" as *const u8 as *const libc::c_char)) - .is_null()} - { - /* Authorization already present, Bailing out */ - return CURLE_OK; - } - /* - * Parameters parsing - * Google and Outscale use the same OSC or GOOG, - * but Amazon uses AWS and AMZ for header arguments. - * AWS is the default because most of non-amazon providers - * are still using aws:amz as a prefix. - */ - tmp0 = if unsafe{ !((*data).set.str_0[STRING_AWS_SIGV4 as usize]).is_null()} { - unsafe{(*data).set.str_0[STRING_AWS_SIGV4 as usize] as *const libc::c_char} - } else { - b"aws:amz\0" as *const u8 as *const libc::c_char - }; - tmp1 = unsafe{strchr(tmp0, ':' as i32)}; - len = if !tmp1.is_null() { - unsafe{ - tmp1.offset_from(tmp0) as size_t} - } else { - unsafe{ strlen(tmp0)} - }; - 'fail: loop { - if len < 1 as i32 as u64 { - unsafe{ - Curl_infof( - data, - b"first provider can't be empty\0" as *const u8 as *const libc::c_char, - );} - ret = CURLE_BAD_FUNCTION_ARGUMENT; - break 'fail; - } - match () { - #[cfg(not(CURLDEBUG))] - _ => { - provider0_low = unsafe{ Curl_cmalloc.expect("non-null function pointer")( - len.wrapping_add(1 as u64), - ) as *mut libc::c_char}; - provider0_up = unsafe{Curl_cmalloc.expect("non-null function pointer")( - len.wrapping_add(1 as u64), - ) as *mut libc::c_char}; - } - #[cfg(CURLDEBUG)] - _ => { - provider0_low = unsafe{curl_dbg_malloc( - len.wrapping_add(1 as u64), - 133, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char}; - provider0_up = unsafe{curl_dbg_malloc( - len.wrapping_add(1 as u64), - 134, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char}; - } - } - if provider0_low.is_null() || provider0_up.is_null() { - break 'fail; - } - unsafe{Curl_strntolower(provider0_low, tmp0, len); - *provider0_low.offset(len as isize) = '\u{0}' as libc::c_char; - Curl_strntoupper(provider0_up, tmp0, len); - *provider0_up.offset(len as isize) = '\u{0}' as libc::c_char;} - if !tmp1.is_null() { - tmp0 = unsafe{tmp1.offset(1 as isize)}; - tmp1 = unsafe{strchr(tmp0, ':' as i32)}; - len = if !tmp1.is_null() { - unsafe{tmp1.offset_from(tmp0) as size_t} - } else { - unsafe{strlen(tmp0)} - }; - if len < 1 as u64 { - unsafe{ - Curl_infof( - data, - b"second provider can't be empty\0" as *const u8 as *const libc::c_char, - );} - ret = CURLE_BAD_FUNCTION_ARGUMENT; - break 'fail; - } - match () { - #[cfg(not(CURLDEBUG))] - _ => { - provider1_low =unsafe{ +use ::libc; +use rust_ffi::src::ffi_alias::type_alias::*; +use rust_ffi::src::ffi_fun::fun_call::*; +use rust_ffi::src::ffi_struct::struct_define::*; + +extern "C" fn sha256_to_hex(mut dst: *mut libc::c_char, mut sha: *mut u8, mut dst_l: size_t) { + let mut i: i32 = 0; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if dst_l >= 65 as libc::c_int as u64 { + } else { + unsafe { + __assert_fail( + b"dst_l >= 65\0" as *const u8 as *const libc::c_char, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + 63, + (*::std::mem::transmute::<&[u8; 52], &[libc::c_char; 52]>( + b"void sha256_to_hex(char *, unsigned char *, size_t)\0", + )) + .as_ptr(), + ); + } + } + i = 0 as i32; + while i < 32 as i32 { + unsafe { + curl_msnprintf( + dst.offset((i * 2 as i32) as isize), + dst_l.wrapping_sub((i * 2 as i32) as u64), + b"%02x\0" as *const u8 as *const libc::c_char, + *sha.offset(i as isize) as i32, + ); + } + i += 1; + } +} +#[no_mangle] +pub extern "C" fn Curl_output_aws_sigv4(mut data: *mut Curl_easy, mut proxy: bool) -> CURLcode { + let mut current_block: u64; + let mut ret: CURLcode = CURLE_OUT_OF_MEMORY; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut len: size_t = 0; + let mut tmp0: *const libc::c_char = 0 as *const libc::c_char; + let mut tmp1: *const libc::c_char = 0 as *const libc::c_char; + let mut provider0_low: *mut libc::c_char = 0 as *mut libc::c_char; + let mut provider0_up: *mut libc::c_char = 0 as *mut libc::c_char; + let mut provider1_low: *mut libc::c_char = 0 as *mut libc::c_char; + let mut provider1_mid: *mut libc::c_char = 0 as *mut libc::c_char; + let mut region: *mut libc::c_char = 0 as *mut libc::c_char; + let mut service: *mut libc::c_char = 0 as *mut libc::c_char; + let mut hostname: *const libc::c_char = unsafe { (*conn).host.name }; + #[cfg(DEBUGBUILD)] + let mut force_timestamp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut clock: time_t = 0; + let mut tm: tm = tm { + tm_sec: 0, + tm_min: 0, + tm_hour: 0, + tm_mday: 0, + tm_mon: 0, + tm_year: 0, + tm_wday: 0, + tm_yday: 0, + tm_isdst: 0, + tm_gmtoff: 0, + tm_zone: 0 as *const libc::c_char, + }; + let mut timestamp: [libc::c_char; 17] = [0; 17]; + let mut date: [libc::c_char; 9] = [0; 9]; + let mut content_type: *const libc::c_char = + unsafe { Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char) }; + let mut canonical_headers: *mut libc::c_char = 0 as *mut libc::c_char; + let mut signed_headers: *mut libc::c_char = 0 as *mut libc::c_char; + let mut httpreq: Curl_HttpReq = HTTPREQ_GET; + let mut method: *const libc::c_char = 0 as *const libc::c_char; + let mut post_data: *const libc::c_char = (if unsafe { !((*data).set.postfields).is_null() } { + unsafe { (*data).set.postfields } + } else { + b"\0" as *const u8 as *const libc::c_char as *const libc::c_void + }) as *const libc::c_char; + let mut sha_hash: [u8; 32] = [0; 32]; + let mut sha_hex: [libc::c_char; 65] = [0; 65]; + let mut canonical_request: *mut libc::c_char = 0 as *mut libc::c_char; + let mut request_type: *mut libc::c_char = 0 as *mut libc::c_char; + let mut credential_scope: *mut libc::c_char = 0 as *mut libc::c_char; + let mut str_to_sign: *mut libc::c_char = 0 as *mut libc::c_char; + let mut user: *const libc::c_char = if unsafe { !((*data).state.aptr.user).is_null() } { + unsafe { (*data).state.aptr.user as *const libc::c_char } + } else { + b"\0" as *const u8 as *const libc::c_char + }; + let mut passwd: *const libc::c_char = if unsafe { !((*data).state.aptr.passwd).is_null() } { + unsafe { (*data).state.aptr.passwd as *const libc::c_char } + } else { + b"\0" as *const u8 as *const libc::c_char + }; + let mut secret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tmp_sign0: [u8; 32] = [ + 0 as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]; + let mut tmp_sign1: [u8; 32] = [ + 0 as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]; + let mut auth_headers: *mut libc::c_char = 0 as *mut libc::c_char; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !proxy { + } else { + unsafe { + __assert_fail( + b"!proxy\0" as *const u8 as *const libc::c_char, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + 109, + (*::std::mem::transmute::<&[u8; 58], &[libc::c_char; 58]>( + b"CURLcode Curl_output_aws_sigv4(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), + ); + } + } + if unsafe { + !(Curl_checkheaders(data, b"Authorization\0" as *const u8 as *const libc::c_char)).is_null() + } { + /* Authorization already present, Bailing out */ + return CURLE_OK; + } + /* + * Parameters parsing + * Google and Outscale use the same OSC or GOOG, + * but Amazon uses AWS and AMZ for header arguments. + * AWS is the default because most of non-amazon providers + * are still using aws:amz as a prefix. + */ + tmp0 = if unsafe { !((*data).set.str_0[STRING_AWS_SIGV4 as usize]).is_null() } { + unsafe { (*data).set.str_0[STRING_AWS_SIGV4 as usize] as *const libc::c_char } + } else { + b"aws:amz\0" as *const u8 as *const libc::c_char + }; + tmp1 = unsafe { strchr(tmp0, ':' as i32) }; + len = if !tmp1.is_null() { + unsafe { tmp1.offset_from(tmp0) as size_t } + } else { + unsafe { strlen(tmp0) } + }; + 'fail: loop { + if len < 1 as i32 as u64 { + unsafe { + Curl_infof( + data, + b"first provider can't be empty\0" as *const u8 as *const libc::c_char, + ); + } + ret = CURLE_BAD_FUNCTION_ARGUMENT; + break 'fail; + } + match () { + #[cfg(not(CURLDEBUG))] + _ => { + provider0_low = unsafe { + Curl_cmalloc.expect("non-null function pointer")(len.wrapping_add(1 as u64)) + as *mut libc::c_char + }; + provider0_up = unsafe { + Curl_cmalloc.expect("non-null function pointer")(len.wrapping_add(1 as u64)) + as *mut libc::c_char + }; + } + #[cfg(CURLDEBUG)] + _ => { + provider0_low = unsafe { + curl_dbg_malloc( + len.wrapping_add(1 as u64), + 133, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ) as *mut libc::c_char + }; + provider0_up = unsafe { + curl_dbg_malloc( + len.wrapping_add(1 as u64), + 134, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ) as *mut libc::c_char + }; + } + } + if provider0_low.is_null() || provider0_up.is_null() { + break 'fail; + } + unsafe { + Curl_strntolower(provider0_low, tmp0, len); + *provider0_low.offset(len as isize) = '\u{0}' as libc::c_char; + Curl_strntoupper(provider0_up, tmp0, len); + *provider0_up.offset(len as isize) = '\u{0}' as libc::c_char; + } + if !tmp1.is_null() { + tmp0 = unsafe { tmp1.offset(1 as isize) }; + tmp1 = unsafe { strchr(tmp0, ':' as i32) }; + len = if !tmp1.is_null() { + unsafe { tmp1.offset_from(tmp0) as size_t } + } else { + unsafe { strlen(tmp0) } + }; + if len < 1 as u64 { + unsafe { + Curl_infof( + data, + b"second provider can't be empty\0" as *const u8 as *const libc::c_char, + ); + } + ret = CURLE_BAD_FUNCTION_ARGUMENT; + break 'fail; + } + match () { + #[cfg(not(CURLDEBUG))] + _ => { + provider1_low = unsafe { Curl_cmalloc.expect("non-null function pointer")(len.wrapping_add(1 as u64)) - as *mut libc::c_char}; - provider1_mid =unsafe{ + as *mut libc::c_char + }; + provider1_mid = unsafe { Curl_cmalloc.expect("non-null function pointer")(len.wrapping_add(1 as u64)) - as *mut libc::c_char}; - } - #[cfg(CURLDEBUG)] - _ => { - provider1_low = unsafe{curl_dbg_malloc( + as *mut libc::c_char + }; + } + #[cfg(CURLDEBUG)] + _ => { + provider1_low = unsafe { + curl_dbg_malloc( len.wrapping_add(1 as libc::c_int as libc::c_ulong), 152 as libc::c_int, b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char}; - provider1_mid = unsafe{curl_dbg_malloc( + ) as *mut libc::c_char + }; + provider1_mid = unsafe { + curl_dbg_malloc( len.wrapping_add(1 as libc::c_int as libc::c_ulong), 153 as libc::c_int, b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char}; + ) as *mut libc::c_char + }; + } + } + + if provider1_low.is_null() || provider1_mid.is_null() { + break 'fail; + } + unsafe { + Curl_strntolower(provider1_low, tmp0, len); + *provider1_low.offset(len as isize) = '\u{0}' as libc::c_char; + Curl_strntolower(provider1_mid, tmp0, len); + *provider1_mid.offset(0 as isize) = + Curl_raw_toupper(*provider1_mid.offset(0 as isize)); + *provider1_mid.offset(len as isize) = '\u{0}' as libc::c_char; + } + if !tmp1.is_null() { + tmp0 = unsafe { tmp1.offset(1 as isize) }; + tmp1 = unsafe { strchr(tmp0, ':' as i32) }; + len = if !tmp1.is_null() { + unsafe { tmp1.offset_from(tmp0) as size_t } + } else { + unsafe { strlen(tmp0) } + }; + if len < 1 as u64 { + unsafe { + Curl_infof( + data, + b"region can't be empty\0" as *const u8 as *const libc::c_char, + ); + } + ret = CURLE_BAD_FUNCTION_ARGUMENT; + break 'fail; + } + region = unsafe { + Curl_memdup(tmp0 as *const libc::c_void, len.wrapping_add(1 as u64)) + as *mut libc::c_char + }; + if region.is_null() { + break 'fail; + } + unsafe { + *region.offset(len as isize) = '\u{0}' as libc::c_char; + } + if !tmp1.is_null() { + tmp0 = unsafe { tmp1.offset(1 as isize) }; + #[cfg(not(CURLDEBUG))] + let mut new_service: *mut libc::c_char = + unsafe { Curl_cstrdup.expect("non-null function pointer")(tmp0) }; + #[cfg(CURLDEBUG)] + let mut new_service: *mut libc::c_char = unsafe { + curl_dbg_strdup( + tmp0, + 180, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ) + }; + service = new_service; + if service.is_null() { + break 'fail; + } + if unsafe { strlen(service) } < 1 as u64 { + unsafe { + Curl_infof( + data, + b"service can't be empty\0" as *const u8 as *const libc::c_char, + ); + } + ret = CURLE_BAD_FUNCTION_ARGUMENT; + break 'fail; + } + } + } + } else { + provider1_low = unsafe { + Curl_memdup( + provider0_low as *const libc::c_void, + len.wrapping_add(1 as u64), + ) as *mut libc::c_char + }; + provider1_mid = unsafe { + Curl_memdup( + provider0_low as *const libc::c_void, + len.wrapping_add(1 as u64), + ) as *mut libc::c_char + }; + if provider1_low.is_null() || provider1_mid.is_null() { + break 'fail; + } + unsafe { + *provider1_mid.offset(0 as isize) = + Curl_raw_toupper(*provider1_mid.offset(0 as isize)); + } + } + if service.is_null() { + tmp0 = hostname; + tmp1 = unsafe { strchr(tmp0, '.' as i32) }; + len = unsafe { tmp1.offset_from(tmp0) as size_t }; + if tmp1.is_null() || len < 1 as u64 { + unsafe { + Curl_infof( + data, + b"service missing in parameters or hostname\0" as *const u8 + as *const libc::c_char, + ); + } + ret = CURLE_URL_MALFORMAT; + break 'fail; + } + service = unsafe { + Curl_memdup(tmp0 as *const libc::c_void, len.wrapping_add(1 as u64)) + as *mut libc::c_char + }; + if service.is_null() { + break 'fail; + } + unsafe { + *service.offset(len as isize) = '\u{0}' as libc::c_char; + } + if region.is_null() { + tmp0 = unsafe { tmp1.offset(1 as isize) }; + tmp1 = unsafe { strchr(tmp0, '.' as i32) }; + len = unsafe { tmp1.offset_from(tmp0) as size_t }; + if tmp1.is_null() || len < 1 as u64 { + unsafe { + Curl_infof( + data, + b"region missing in parameters or hostname\0" as *const u8 + as *const libc::c_char, + ); } - } - - if provider1_low.is_null() || provider1_mid.is_null() { - break 'fail; - } - unsafe{Curl_strntolower(provider1_low, tmp0, len); - *provider1_low.offset(len as isize) = '\u{0}' as libc::c_char; - Curl_strntolower(provider1_mid, tmp0, len); - *provider1_mid.offset(0 as isize) = - Curl_raw_toupper(*provider1_mid.offset(0 as isize)); - *provider1_mid.offset(len as isize) = '\u{0}' as libc::c_char;} - if !tmp1.is_null() { - tmp0 = unsafe{tmp1.offset(1 as isize)}; - tmp1 = unsafe{strchr(tmp0, ':' as i32)}; - len = if !tmp1.is_null() { - unsafe{tmp1.offset_from(tmp0) as size_t} - } else { - unsafe{strlen(tmp0)} - }; - if len < 1 as u64 { - unsafe{Curl_infof( - data, - b"region can't be empty\0" as *const u8 as *const libc::c_char, - );} - ret = CURLE_BAD_FUNCTION_ARGUMENT; - break 'fail; - } - region = unsafe{Curl_memdup(tmp0 as *const libc::c_void, len.wrapping_add(1 as u64)) - as *mut libc::c_char}; - if region.is_null() { - break 'fail; - } - unsafe{*region.offset(len as isize) = '\u{0}' as libc::c_char;} - if !tmp1.is_null() { - tmp0 = unsafe{tmp1.offset(1 as isize)}; - #[cfg(not(CURLDEBUG))] - let mut new_service: *mut libc::c_char = - unsafe{Curl_cstrdup.expect("non-null function pointer")(tmp0)}; - #[cfg(CURLDEBUG)] - let mut new_service: *mut libc::c_char = unsafe{curl_dbg_strdup( - tmp0, - 180, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - )}; - service = new_service; - if service.is_null() { - break 'fail; - } - if unsafe{strlen(service)} < 1 as u64 { - unsafe{ - Curl_infof( - data, - b"service can't be empty\0" as *const u8 as *const libc::c_char, - );} - ret = CURLE_BAD_FUNCTION_ARGUMENT; - break 'fail; - } - } - } - } else { - provider1_low =unsafe{Curl_memdup( - provider0_low as *const libc::c_void, - len.wrapping_add(1 as u64), - ) as *mut libc::c_char}; - provider1_mid = unsafe{Curl_memdup( - provider0_low as *const libc::c_void, - len.wrapping_add(1 as u64), - ) as *mut libc::c_char}; - if provider1_low.is_null() || provider1_mid.is_null() { - break 'fail; - } - unsafe{*provider1_mid.offset(0 as isize) = - Curl_raw_toupper(*provider1_mid.offset(0 as isize));} - } - if service.is_null() { - tmp0 = hostname; - tmp1 = unsafe{strchr(tmp0, '.' as i32)}; - len = unsafe{tmp1.offset_from(tmp0) as size_t}; - if tmp1.is_null() || len < 1 as u64 { - unsafe{Curl_infof( - data, - b"service missing in parameters or hostname\0" as *const u8 - as *const libc::c_char, - );} - ret = CURLE_URL_MALFORMAT; - break 'fail; - } - service = unsafe{Curl_memdup(tmp0 as *const libc::c_void, len.wrapping_add(1 as u64)) - as *mut libc::c_char}; - if service.is_null() { - break 'fail; - } - unsafe{*service.offset(len as isize) = '\u{0}' as libc::c_char;} - if region.is_null() { - tmp0 = unsafe{tmp1.offset(1 as isize)}; - tmp1 = unsafe{strchr(tmp0, '.' as i32)}; - len = unsafe{tmp1.offset_from(tmp0) as size_t}; - if tmp1.is_null() || len < 1 as u64 { - unsafe{ - Curl_infof( - data, - b"region missing in parameters or hostname\0" as *const u8 - as *const libc::c_char, - );} - ret = CURLE_URL_MALFORMAT; - break 'fail; - } - region = unsafe{Curl_memdup(tmp0 as *const libc::c_void, len.wrapping_add(1 as u64)) - as *mut libc::c_char}; - if region.is_null() { - break 'fail; - } - unsafe{*region.offset(len as isize) = '\u{0}' as libc::c_char;} - } - } - unsafe{ - match () { - #[cfg(CURLDEBUG)] - _ => { - force_timestamp = - getenv(b"CURL_FORCETIME\0" as *const u8 as *const libc::c_char); - if !force_timestamp.is_null() { - clock = 0 as time_t; - } else { - time(&mut clock); - } - } - #[cfg(not(CURLDEBUG))] - _ => { - time(&mut clock); - } - } + ret = CURLE_URL_MALFORMAT; + break 'fail; + } + region = unsafe { + Curl_memdup(tmp0 as *const libc::c_void, len.wrapping_add(1 as u64)) + as *mut libc::c_char + }; + if region.is_null() { + break 'fail; + } + unsafe { + *region.offset(len as isize) = '\u{0}' as libc::c_char; + } } - ret = unsafe{Curl_gmtime(clock, &mut tm)}; - if ret as u32 != CURLE_OK as u32 { - break 'fail; - } - if unsafe{strftime( - timestamp.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 17]>() as u64, - b"%Y%m%dT%H%M%SZ\0" as *const u8 as *const libc::c_char, - &mut tm, - )} == 0 - { - break 'fail; - } - unsafe{memcpy( - date.as_mut_ptr() as *mut libc::c_void, - timestamp.as_mut_ptr() as *const libc::c_void, - ::std::mem::size_of::<[libc::c_char; 9]>() as u64, - );} - date[(::std::mem::size_of::<[libc::c_char; 9]>() as u64).wrapping_sub(1 as u64) - as usize] = 0 as libc::c_char; - if !content_type.is_null() { - content_type =unsafe{ strchr(content_type, ':' as i32)}; - if content_type.is_null() { - ret = CURLE_FAILED_INIT; - break 'fail; - } - content_type = unsafe{content_type.offset(1)}; - while unsafe{*content_type as i32} == ' ' as i32 || unsafe{*content_type as i32} == '\t' as i32 { - content_type = unsafe{content_type.offset(1)}; - } - canonical_headers = unsafe{curl_maprintf( - b"content-type:%s\nhost:%s\nx-%s-date:%s\n\0" as *const u8 - as *const libc::c_char, - content_type, - hostname, - provider1_low, - timestamp.as_mut_ptr(), - )}; - signed_headers = unsafe{curl_maprintf( - b"content-type;host;x-%s-date\0" as *const u8 as *const libc::c_char, - provider1_low, - )}; - } else { - canonical_headers = unsafe{curl_maprintf( - b"host:%s\nx-%s-date:%s\n\0" as *const u8 as *const libc::c_char, - hostname, - provider1_low, - timestamp.as_mut_ptr(), - )}; - signed_headers = unsafe{curl_maprintf( - b"host;x-%s-date\0" as *const u8 as *const libc::c_char, - provider1_low, - )}; - } - if canonical_headers.is_null() || signed_headers.is_null() { - break 'fail; - } - unsafe{Curl_sha256it( - sha_hash.as_mut_ptr(), - post_data as *const u8, - strlen(post_data), - );} - sha256_to_hex( - sha_hex.as_mut_ptr(), - sha_hash.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 65]>() as u64, - ); - unsafe{Curl_http_method(data, conn, &mut method, &mut httpreq);} - canonical_request =unsafe{ curl_maprintf( - b"%s\n%s\n%s\n%s\n%s\n%s\0" as *const u8 as *const libc::c_char, - method, - (*data).state.up.path, - if !((*data).state.up.query).is_null() { - (*data).state.up.query as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - canonical_headers, - signed_headers, - sha_hex.as_mut_ptr(), - )}; - if canonical_request.is_null() { - break 'fail; - } - request_type = unsafe{curl_maprintf( - b"%s4_request\0" as *const u8 as *const libc::c_char, - provider0_low, - )}; - if request_type.is_null() { - break 'fail; - } - credential_scope = unsafe{curl_maprintf( - b"%s/%s/%s/%s\0" as *const u8 as *const libc::c_char, - date.as_mut_ptr(), - region, - service, - request_type, - )}; - if credential_scope.is_null() { - break 'fail; - } - unsafe{Curl_sha256it( - sha_hash.as_mut_ptr(), - canonical_request as *mut u8, - strlen(canonical_request), - );} - sha256_to_hex( - sha_hex.as_mut_ptr(), - sha_hash.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 65]>() as u64, - ); - /* - * Google allow to use rsa key instead of HMAC, so this code might change - * In the furure, but for now we support only HMAC version - */ - str_to_sign =unsafe{ curl_maprintf( - b"%s4-HMAC-SHA256\n%s\n%s\n%s\0" as *const u8 as *const libc::c_char, - provider0_up, - timestamp.as_mut_ptr(), - credential_scope, - sha_hex.as_mut_ptr(), - )}; - if str_to_sign.is_null() { - break 'fail; - } - secret = unsafe{curl_maprintf( - b"%s4%s\0" as *const u8 as *const libc::c_char, - provider0_up, - passwd, - )}; - if secret.is_null() { - break 'fail; - } - ret = unsafe{Curl_hmacit( - Curl_HMAC_SHA256.as_ptr(), - secret as *mut u8, - strlen(secret) as size_t, - date.as_mut_ptr() as *mut u8, - strlen(date.as_mut_ptr()) as size_t, - tmp_sign0.as_mut_ptr(), - )}; - if ret as u32 != CURLE_OK as u32 { - break 'fail; - } - ret = unsafe{Curl_hmacit( - Curl_HMAC_SHA256.as_ptr(), - tmp_sign0.as_mut_ptr(), - ::std::mem::size_of::<[u8; 32]>() as u32 as size_t, - region as *mut u8, - strlen(region) as size_t, - tmp_sign1.as_mut_ptr(), - )}; - if ret as u32 != CURLE_OK as u32 { - break 'fail; - } - ret = unsafe{Curl_hmacit( - Curl_HMAC_SHA256.as_ptr(), - tmp_sign1.as_mut_ptr(), - ::std::mem::size_of::<[u8; 32]>() as u32 as size_t, - service as *mut u8, - strlen(service) as size_t, - tmp_sign0.as_mut_ptr(), - )}; - if ret as u32 != CURLE_OK as u32 { - break 'fail; - } - ret = unsafe{Curl_hmacit( - Curl_HMAC_SHA256.as_ptr(), - tmp_sign0.as_mut_ptr(), - ::std::mem::size_of::<[u8; 32]>() as u32 as size_t, - request_type as *mut u8, - strlen(request_type) as size_t, - tmp_sign1.as_mut_ptr(), - )}; - if ret as u32 != CURLE_OK as u32 { - break 'fail; - } - ret = unsafe{Curl_hmacit( - Curl_HMAC_SHA256.as_ptr(), - tmp_sign1.as_mut_ptr(), - ::std::mem::size_of::<[u8; 32]>() as u32 as size_t, - str_to_sign as *mut u8, - strlen(str_to_sign) as size_t, - tmp_sign0.as_mut_ptr(), - )}; - if ret as u32 != CURLE_OK as u32 { - break 'fail; - } - sha256_to_hex( - sha_hex.as_mut_ptr(), - tmp_sign0.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 65]>() as u64, - ); - auth_headers = unsafe{curl_maprintf( + } + unsafe { + match () { + #[cfg(CURLDEBUG)] + _ => { + force_timestamp = + getenv(b"CURL_FORCETIME\0" as *const u8 as *const libc::c_char); + if !force_timestamp.is_null() { + clock = 0 as time_t; + } else { + time(&mut clock); + } + } + #[cfg(not(CURLDEBUG))] + _ => { + time(&mut clock); + } + } + } + ret = unsafe { Curl_gmtime(clock, &mut tm) }; + if ret as u32 != CURLE_OK as u32 { + break 'fail; + } + if unsafe { + strftime( + timestamp.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 17]>() as u64, + b"%Y%m%dT%H%M%SZ\0" as *const u8 as *const libc::c_char, + &mut tm, + ) + } == 0 + { + break 'fail; + } + unsafe { + memcpy( + date.as_mut_ptr() as *mut libc::c_void, + timestamp.as_mut_ptr() as *const libc::c_void, + ::std::mem::size_of::<[libc::c_char; 9]>() as u64, + ); + } + date[(::std::mem::size_of::<[libc::c_char; 9]>() as u64).wrapping_sub(1 as u64) as usize] = + 0 as libc::c_char; + if !content_type.is_null() { + content_type = unsafe { strchr(content_type, ':' as i32) }; + if content_type.is_null() { + ret = CURLE_FAILED_INIT; + break 'fail; + } + content_type = unsafe { content_type.offset(1) }; + while unsafe { *content_type as i32 } == ' ' as i32 + || unsafe { *content_type as i32 } == '\t' as i32 + { + content_type = unsafe { content_type.offset(1) }; + } + canonical_headers = unsafe { + curl_maprintf( + b"content-type:%s\nhost:%s\nx-%s-date:%s\n\0" as *const u8 + as *const libc::c_char, + content_type, + hostname, + provider1_low, + timestamp.as_mut_ptr(), + ) + }; + signed_headers = unsafe { + curl_maprintf( + b"content-type;host;x-%s-date\0" as *const u8 as *const libc::c_char, + provider1_low, + ) + }; + } else { + canonical_headers = unsafe { + curl_maprintf( + b"host:%s\nx-%s-date:%s\n\0" as *const u8 as *const libc::c_char, + hostname, + provider1_low, + timestamp.as_mut_ptr(), + ) + }; + signed_headers = unsafe { + curl_maprintf( + b"host;x-%s-date\0" as *const u8 as *const libc::c_char, + provider1_low, + ) + }; + } + if canonical_headers.is_null() || signed_headers.is_null() { + break 'fail; + } + unsafe { + Curl_sha256it( + sha_hash.as_mut_ptr(), + post_data as *const u8, + strlen(post_data), + ); + } + sha256_to_hex( + sha_hex.as_mut_ptr(), + sha_hash.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 65]>() as u64, + ); + unsafe { + Curl_http_method(data, conn, &mut method, &mut httpreq); + } + canonical_request = unsafe { + curl_maprintf( + b"%s\n%s\n%s\n%s\n%s\n%s\0" as *const u8 as *const libc::c_char, + method, + (*data).state.up.path, + if !((*data).state.up.query).is_null() { + (*data).state.up.query as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + canonical_headers, + signed_headers, + sha_hex.as_mut_ptr(), + ) + }; + if canonical_request.is_null() { + break 'fail; + } + request_type = unsafe { + curl_maprintf( + b"%s4_request\0" as *const u8 as *const libc::c_char, + provider0_low, + ) + }; + if request_type.is_null() { + break 'fail; + } + credential_scope = unsafe { + curl_maprintf( + b"%s/%s/%s/%s\0" as *const u8 as *const libc::c_char, + date.as_mut_ptr(), + region, + service, + request_type, + ) + }; + if credential_scope.is_null() { + break 'fail; + } + unsafe { + Curl_sha256it( + sha_hash.as_mut_ptr(), + canonical_request as *mut u8, + strlen(canonical_request), + ); + } + sha256_to_hex( + sha_hex.as_mut_ptr(), + sha_hash.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 65]>() as u64, + ); + /* + * Google allow to use rsa key instead of HMAC, so this code might change + * In the furure, but for now we support only HMAC version + */ + str_to_sign = unsafe { + curl_maprintf( + b"%s4-HMAC-SHA256\n%s\n%s\n%s\0" as *const u8 as *const libc::c_char, + provider0_up, + timestamp.as_mut_ptr(), + credential_scope, + sha_hex.as_mut_ptr(), + ) + }; + if str_to_sign.is_null() { + break 'fail; + } + secret = unsafe { + curl_maprintf( + b"%s4%s\0" as *const u8 as *const libc::c_char, + provider0_up, + passwd, + ) + }; + if secret.is_null() { + break 'fail; + } + ret = unsafe { + Curl_hmacit( + Curl_HMAC_SHA256.as_ptr(), + secret as *mut u8, + strlen(secret) as size_t, + date.as_mut_ptr() as *mut u8, + strlen(date.as_mut_ptr()) as size_t, + tmp_sign0.as_mut_ptr(), + ) + }; + if ret as u32 != CURLE_OK as u32 { + break 'fail; + } + ret = unsafe { + Curl_hmacit( + Curl_HMAC_SHA256.as_ptr(), + tmp_sign0.as_mut_ptr(), + ::std::mem::size_of::<[u8; 32]>() as u32 as size_t, + region as *mut u8, + strlen(region) as size_t, + tmp_sign1.as_mut_ptr(), + ) + }; + if ret as u32 != CURLE_OK as u32 { + break 'fail; + } + ret = unsafe { + Curl_hmacit( + Curl_HMAC_SHA256.as_ptr(), + tmp_sign1.as_mut_ptr(), + ::std::mem::size_of::<[u8; 32]>() as u32 as size_t, + service as *mut u8, + strlen(service) as size_t, + tmp_sign0.as_mut_ptr(), + ) + }; + if ret as u32 != CURLE_OK as u32 { + break 'fail; + } + ret = unsafe { + Curl_hmacit( + Curl_HMAC_SHA256.as_ptr(), + tmp_sign0.as_mut_ptr(), + ::std::mem::size_of::<[u8; 32]>() as u32 as size_t, + request_type as *mut u8, + strlen(request_type) as size_t, + tmp_sign1.as_mut_ptr(), + ) + }; + if ret as u32 != CURLE_OK as u32 { + break 'fail; + } + ret = unsafe { + Curl_hmacit( + Curl_HMAC_SHA256.as_ptr(), + tmp_sign1.as_mut_ptr(), + ::std::mem::size_of::<[u8; 32]>() as u32 as size_t, + str_to_sign as *mut u8, + strlen(str_to_sign) as size_t, + tmp_sign0.as_mut_ptr(), + ) + }; + if ret as u32 != CURLE_OK as u32 { + break 'fail; + } + sha256_to_hex( + sha_hex.as_mut_ptr(), + tmp_sign0.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 65]>() as u64, + ); + auth_headers = unsafe { + curl_maprintf( b"Authorization: %s4-HMAC-SHA256 Credential=%s/%s, SignedHeaders=%s, Signature=%s\r\nX-%s-Date: %s\r\n\0" as *const u8 as *const libc::c_char, provider0_up, @@ -572,133 +658,187 @@ sha_hex.as_mut_ptr(), provider1_mid, timestamp.as_mut_ptr(), - )}; - if auth_headers.is_null() { - break 'fail; - } - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.userpwd as *mut libc::c_void, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( + ) + }; + if auth_headers.is_null() { + break 'fail; + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.userpwd as *mut libc::c_void, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( (*data).state.aptr.userpwd as *mut libc::c_void, 372 as libc::c_int, b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, ); - (*data).state.aptr.userpwd = 0 as *mut libc::c_char; - (*data).state.aptr.userpwd = auth_headers; - ((*data).state.authhost).set_done(1 as bit);} - ret = CURLE_OK; - break 'fail; - } - #[cfg(not(CURLDEBUG))] - unsafe{ - Curl_cfree.expect("non-null function pointer")(provider0_low as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{ - Curl_cfree.expect("non-null function pointer")(provider0_up as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(provider1_low as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(provider1_mid as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(region as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(service as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(canonical_headers as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(signed_headers as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(canonical_request as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(request_type as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(credential_scope as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(str_to_sign as *mut libc::c_void);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(secret as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - provider0_low as *mut libc::c_void, - 378, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - provider0_up as *mut libc::c_void, - 379, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - provider1_low as *mut libc::c_void, - 380, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - provider1_mid as *mut libc::c_void, - 381, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - region as *mut libc::c_void, - 382, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - service as *mut libc::c_void, - 383, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - canonical_headers as *mut libc::c_void, - 384, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - signed_headers as *mut libc::c_void, - 385, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - canonical_request as *mut libc::c_void, - 386, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - request_type as *mut libc::c_void, - 387, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - credential_scope as *mut libc::c_void, - 388, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - str_to_sign as *mut libc::c_void, - 389, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - secret as *mut libc::c_void, - 390, - b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, - );} - return ret; - } - /* !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) */ - \ No newline at end of file + (*data).state.aptr.userpwd = 0 as *mut libc::c_char; + (*data).state.aptr.userpwd = auth_headers; + ((*data).state.authhost).set_done(1 as bit); + } + ret = CURLE_OK; + break 'fail; + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(provider0_low as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(provider0_up as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(provider1_low as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(provider1_mid as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(region as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(service as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(canonical_headers as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(signed_headers as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(canonical_request as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(request_type as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(credential_scope as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(str_to_sign as *mut libc::c_void); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(secret as *mut libc::c_void); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + provider0_low as *mut libc::c_void, + 378, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + provider0_up as *mut libc::c_void, + 379, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + provider1_low as *mut libc::c_void, + 380, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + provider1_mid as *mut libc::c_void, + 381, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + region as *mut libc::c_void, + 382, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + service as *mut libc::c_void, + 383, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + canonical_headers as *mut libc::c_void, + 384, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + signed_headers as *mut libc::c_void, + 385, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + canonical_request as *mut libc::c_void, + 386, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + request_type as *mut libc::c_void, + 387, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + credential_scope as *mut libc::c_void, + 388, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + str_to_sign as *mut libc::c_void, + 389, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + secret as *mut libc::c_void, + 390, + b"http_aws_sigv4.c\0" as *const u8 as *const libc::c_char, + ); + } + return ret; +} +/* !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) */ diff --git a/rust/rust_project/src/http_chunks.rs b/rust/rust_project/src/http_chunks.rs index 25a9c38..773eb54 100644 --- a/rust/rust_project/src/http_chunks.rs +++ b/rust/rust_project/src/http_chunks.rs @@ -12,323 +12,327 @@ * Create: 2022-10-31 * Description: http chunks ******************************************************************************/ - use ::libc; - use rust_ffi::src::ffi_alias::type_alias::*; - use rust_ffi::src::ffi_fun::fun_call::*; - use rust_ffi::src::ffi_struct::struct_define::*; - /* - * Chunk format (simplified): +use ::libc; +use rust_ffi::src::ffi_alias::type_alias::*; +use rust_ffi::src::ffi_fun::fun_call::*; +use rust_ffi::src::ffi_struct::struct_define::*; +/* +* Chunk format (simplified): +* +* [ chunk extension ] CRLF +* CRLF +* +* Highlights from RFC2616 section 3.6 say: + + The chunked encoding modifies the body of a message in order to + transfer it as a series of chunks, each with its own size indicator, + followed by an OPTIONAL trailer containing entity-header fields. This + allows dynamically produced content to be transferred along with the + information necessary for the recipient to verify that it has + received the full message. + + Chunked-Body = *chunk + last-chunk + trailer + CRLF + + chunk = chunk-size [ chunk-extension ] CRLF + chunk-data CRLF + chunk-size = 1*HEX + last-chunk = 1*("0") [ chunk-extension ] CRLF + + chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) + chunk-ext-name = token + chunk-ext-val = token | quoted-string + chunk-data = chunk-size(OCTET) + trailer = *(entity-header CRLF) + + The chunk-size field is a string of hex digits indicating the size of + the chunk. The chunked encoding is ended by any chunk whose size is + zero, followed by the trailer, which is terminated by an empty line. + +*/ +#[no_mangle] +pub extern "C" fn Curl_httpchunk_init(mut data: *mut Curl_easy) { + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut chunk: *mut Curl_chunker = unsafe { &mut (*conn).chunk }; + unsafe { + (*chunk).hexindex = 0 as u8; /* start at 0 */ + (*chunk).state = CHUNK_HEX; /* we get hex first! */ + Curl_dyn_init(&mut (*conn).trailer, 4096 as size_t); + } +} + +/* + * chunk_read() returns a OK for normal operations, or a positive return code + * for errors. STOP means this sequence of chunks is complete. The 'wrote' + * argument is set to tell the caller how many bytes we actually passed to the + * client (for byte-counting and whatever). * - * [ chunk extension ] CRLF - * CRLF + * The states and the state-machine is further explained in the header file. * - * Highlights from RFC2616 section 3.6 say: - - The chunked encoding modifies the body of a message in order to - transfer it as a series of chunks, each with its own size indicator, - followed by an OPTIONAL trailer containing entity-header fields. This - allows dynamically produced content to be transferred along with the - information necessary for the recipient to verify that it has - received the full message. - - Chunked-Body = *chunk - last-chunk - trailer - CRLF - - chunk = chunk-size [ chunk-extension ] CRLF - chunk-data CRLF - chunk-size = 1*HEX - last-chunk = 1*("0") [ chunk-extension ] CRLF - - chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) - chunk-ext-name = token - chunk-ext-val = token | quoted-string - chunk-data = chunk-size(OCTET) - trailer = *(entity-header CRLF) - - The chunk-size field is a string of hex digits indicating the size of - the chunk. The chunked encoding is ended by any chunk whose size is - zero, followed by the trailer, which is terminated by an empty line. - + * This function always uses ASCII hex values to accommodate non-ASCII hosts. + * For example, 0x0d and 0x0a are used instead of '\r' and '\n'. */ - #[no_mangle] - pub extern "C" fn Curl_httpchunk_init(mut data: *mut Curl_easy) { - - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut chunk: *mut Curl_chunker = unsafe{&mut (*conn).chunk}; - unsafe{(*chunk).hexindex = 0 as u8; /* start at 0 */ - (*chunk).state = CHUNK_HEX; /* we get hex first! */ - Curl_dyn_init(&mut (*conn).trailer, 4096 as size_t);} +#[no_mangle] +pub extern "C" fn Curl_httpchunk_read( + mut data: *mut Curl_easy, + mut datap: *mut libc::c_char, + mut datalen: ssize_t, + mut wrotep: *mut ssize_t, + mut extrap: *mut CURLcode, +) -> CHUNKcode { + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ch: *mut Curl_chunker = unsafe { &mut (*conn).chunk }; + let mut k: *mut SingleRequest = unsafe { &mut (*data).req }; + let mut piece: size_t = 0; + let mut length: curl_off_t = datalen; + let mut wrote: *mut size_t = wrotep as *mut size_t; + unsafe { + *wrote = 0 as size_t; + } /* nothing's written yet */ - } - - /* - * chunk_read() returns a OK for normal operations, or a positive return code - * for errors. STOP means this sequence of chunks is complete. The 'wrote' - * argument is set to tell the caller how many bytes we actually passed to the - * client (for byte-counting and whatever). - * - * The states and the state-machine is further explained in the header file. - * - * This function always uses ASCII hex values to accommodate non-ASCII hosts. - * For example, 0x0d and 0x0a are used instead of '\r' and '\n'. - */ - #[no_mangle] - pub extern "C" fn Curl_httpchunk_read( - mut data: *mut Curl_easy, - mut datap: *mut libc::c_char, - mut datalen: ssize_t, - mut wrotep: *mut ssize_t, - mut extrap: *mut CURLcode, - ) -> CHUNKcode { - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut ch: *mut Curl_chunker = unsafe{&mut (*conn).chunk}; - let mut k: *mut SingleRequest =unsafe{ &mut (*data).req}; - let mut piece: size_t = 0; - let mut length: curl_off_t = datalen; - let mut wrote: *mut size_t = wrotep as *mut size_t; - unsafe{*wrote = 0 as size_t;} /* nothing's written yet */ - - /* the original data is written to the client, but we go on with the - chunk read process, to properly calculate the content length*/ - if unsafe{((*data).set).http_te_skip() as i32} != 0 && unsafe{(*k).ignorebody()} == 0 { - result = unsafe{Curl_client_write(data, (1 as i32) << 0 as i32, datap, datalen as size_t)}; - if result as u64 != 0 { - unsafe{*extrap = result;} - return CHUNKE_PASSTHRU_ERROR; /* longer hex than we support */ - } - } - while length != 0 { - let mut current_block_101: u64; - unsafe{ - match (*ch).state as u32 { - 0 => { - if Curl_isxdigit(*datap as i32) != 0 { - /* This is illegal data, we received junk where we expected - a hexadecimal digit. */ - if ((*ch).hexindex as i32) < 8 as i32 { - (*ch).hexbuffer[(*ch).hexindex as usize] = *datap; - datap = datap.offset(1); - length -= 1; - (*ch).hexindex = ((*ch).hexindex).wrapping_add(1); - } else { - return CHUNKE_TOO_LONG_HEX; - } - } else { - /* length and datap are unmodified */ - let mut endptr: *mut libc::c_char = 0 as *mut libc::c_char; - if 0 as i32 == (*ch).hexindex as i32 { - return CHUNKE_ILLEGAL_HEX; - } - (*ch).hexbuffer[(*ch).hexindex as usize] = 0 as libc::c_char; - /* convert to host encoding before calling strtoul */ - result = CURLE_OK as CURLcode; - if result as u64 != 0 { - /* Curl_convert_from_network calls failf if unsuccessful */ - /* Treat it as a bad hex character */ - return CHUNKE_ILLEGAL_HEX; - } - if curlx_strtoofft( - ((*ch).hexbuffer).as_mut_ptr(), - &mut endptr, - 16 as i32, - &mut (*ch).datasize, - ) as u64 - != 0 - { - /* now wait for the CRLF */ - return CHUNKE_ILLEGAL_HEX; - } - (*ch).state = CHUNK_LF; - } - } - 1 => { - if *datap as i32 == 0xa as i32 { - if 0 as i64 == (*ch).datasize { - (*ch).state = CHUNK_TRAILER; - } else { - (*ch).state = CHUNK_DATA; - } - } - datap = datap.offset(1); - length -= 1; - } - 2 => { - piece = curlx_sotouz(if (*ch).datasize >= length { - length - } else { - (*ch).datasize - }); - if ((*data).set).http_te_skip() == 0 && (*k).ignorebody() == 0 { - if ((*data).set).http_ce_skip() == 0 && !((*k).writer_stack).is_null() { - result = Curl_unencode_write(data, (*k).writer_stack, datap, piece); - } else { - result = Curl_client_write(data, (1 as i32) << 0 as i32, datap, piece); - } - if result as u64 != 0 { - *extrap = result; - return CHUNKE_PASSTHRU_ERROR; - } - } - /* decrease amount left to expect */ - *wrote = (*wrote as u64).wrapping_add(piece) as size_t; - (*ch).datasize = ((*ch).datasize as u64).wrapping_sub(piece) as curl_off_t; - datap = datap.offset(piece as isize); - /* move read pointer forward */ - length = (length as u64).wrapping_sub(piece) as curl_off_t; - /* decrease space left in this round */ - if 0 as i64 == (*ch).datasize { - /* end of data this round, we now expect a trailing CRLF */ - (*ch).state = CHUNK_POSTLF; - } - } - 3 => { - if *datap as i32 == 0xa as i32 { - /* The last one before we go back to hex state and start all over. */ - Curl_httpchunk_init(data); /* sets state back to CHUNK_HEX */ - } else if *datap as i32 != 0xd as i32 { - return CHUNKE_BAD_CHUNK; - } - datap = datap.offset(1); - length -= 1; - } - 5 => { - if *datap as i32 == 0xd as i32 || *datap as i32 == 0xa as i32 { - let mut tr: *mut libc::c_char = Curl_dyn_ptr(&mut (*conn).trailer); - /* this is the end of a trailer, but if the trailer was zero bytes - there was no trailer and we move on */ - if !tr.is_null() { - let mut trlen: size_t = 0; - result = Curl_dyn_add( - &mut (*conn).trailer, - b"\r\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, - ); - if result as u64 != 0 { - return CHUNKE_OUT_OF_MEMORY; - } - tr = Curl_dyn_ptr(&mut (*conn).trailer); - trlen = Curl_dyn_len(&mut (*conn).trailer); - /* Convert to host encoding before calling Curl_client_write */ - result = CURLE_OK as CURLcode; - if result as u64 != 0 { - /* Curl_convert_from_network calls failf if unsuccessful */ - /* Treat it as a bad chunk */ - return CHUNKE_BAD_CHUNK; - } - if ((*data).set).http_te_skip() == 0 { - /* already on the LF */ - result = Curl_client_write(data, (1 as i32) << 1 as i32, tr, trlen); - if result as u64 != 0 { - *extrap = result; - return CHUNKE_PASSTHRU_ERROR; - } - } - Curl_dyn_reset(&mut (*conn).trailer); - /* no trailer, we're on the final CRLF pair */ - (*ch).state = CHUNK_TRAILER_CR; - if *datap as i32 == 0xa as i32 { - current_block_101 = 15586796709793571329; - } else { - current_block_101 = 14329534724295951598; - } - } else { - (*ch).state = CHUNK_TRAILER_POSTCR; - current_block_101 = 15586796709793571329; - } - } else { - result = Curl_dyn_addn( - &mut (*conn).trailer, - datap as *const libc::c_void, - 1 as size_t, - ); - if result as u64 != 0 { - return CHUNKE_OUT_OF_MEMORY; - } - current_block_101 = 14329534724295951598; - } - match current_block_101 { - 15586796709793571329 => {} - _ => { - datap = datap.offset(1); - length -= 1; - } - } - } - 6 => { - if *datap as i32 == 0xa as i32 { - /* no trailer, we're on the final CRLF pair */ - (*ch).state = CHUNK_TRAILER_POSTCR; - datap = datap.offset(1); - length -= 1; - /* don't advance the pointer */ - } else { - return CHUNKE_BAD_CHUNK; - } - } - 7 => { - /* We enter this state when a CR should arrive so we expect to - have to first pass a CR before we wait for LF */ - if *datap as i32 != 0xd as i32 && *datap as i32 != 0xa as i32 - /* not a CR then it must be another header in the trailer */ - { - (*ch).state = CHUNK_TRAILER; - } else { - if *datap as i32 == 0xd as i32 { - /* skip if CR */ - datap = datap.offset(1); - length -= 1; - } - /* now wait for the final LF */ - (*ch).state = CHUNK_STOP; /* return stop */ - } - } - 4 => { - if *datap as i32 == 0xa as i32 { - length -= 1; - /* Record the length of any data left in the end of the buffer - even if there's no more chunks to read */ - (*ch).datasize = curlx_sotouz(length) as curl_off_t; - return CHUNKE_STOP; /* return stop */ - } else { - return CHUNKE_BAD_CHUNK; - } - } - _ => {} - } + /* the original data is written to the client, but we go on with the + chunk read process, to properly calculate the content length*/ + if unsafe { ((*data).set).http_te_skip() as i32 } != 0 && unsafe { (*k).ignorebody() } == 0 { + result = + unsafe { Curl_client_write(data, (1 as i32) << 0 as i32, datap, datalen as size_t) }; + if result as u64 != 0 { + unsafe { + *extrap = result; + } + return CHUNKE_PASSTHRU_ERROR; /* longer hex than we support */ + } + } + while length != 0 { + let mut current_block_101: u64; + unsafe { + match (*ch).state as u32 { + 0 => { + if Curl_isxdigit(*datap as i32) != 0 { + /* This is illegal data, we received junk where we expected + a hexadecimal digit. */ + if ((*ch).hexindex as i32) < 8 as i32 { + (*ch).hexbuffer[(*ch).hexindex as usize] = *datap; + datap = datap.offset(1); + length -= 1; + (*ch).hexindex = ((*ch).hexindex).wrapping_add(1); + } else { + return CHUNKE_TOO_LONG_HEX; + } + } else { + /* length and datap are unmodified */ + let mut endptr: *mut libc::c_char = 0 as *mut libc::c_char; + if 0 as i32 == (*ch).hexindex as i32 { + return CHUNKE_ILLEGAL_HEX; + } + (*ch).hexbuffer[(*ch).hexindex as usize] = 0 as libc::c_char; + /* convert to host encoding before calling strtoul */ + result = CURLE_OK as CURLcode; + if result as u64 != 0 { + /* Curl_convert_from_network calls failf if unsuccessful */ + /* Treat it as a bad hex character */ + return CHUNKE_ILLEGAL_HEX; + } + if curlx_strtoofft( + ((*ch).hexbuffer).as_mut_ptr(), + &mut endptr, + 16 as i32, + &mut (*ch).datasize, + ) as u64 + != 0 + { + /* now wait for the CRLF */ + return CHUNKE_ILLEGAL_HEX; + } + (*ch).state = CHUNK_LF; + } + } + 1 => { + if *datap as i32 == 0xa as i32 { + if 0 as i64 == (*ch).datasize { + (*ch).state = CHUNK_TRAILER; + } else { + (*ch).state = CHUNK_DATA; + } + } + datap = datap.offset(1); + length -= 1; + } + 2 => { + piece = curlx_sotouz(if (*ch).datasize >= length { + length + } else { + (*ch).datasize + }); + if ((*data).set).http_te_skip() == 0 && (*k).ignorebody() == 0 { + if ((*data).set).http_ce_skip() == 0 && !((*k).writer_stack).is_null() { + result = Curl_unencode_write(data, (*k).writer_stack, datap, piece); + } else { + result = Curl_client_write(data, (1 as i32) << 0 as i32, datap, piece); + } + if result as u64 != 0 { + *extrap = result; + return CHUNKE_PASSTHRU_ERROR; + } + } + /* decrease amount left to expect */ + *wrote = (*wrote as u64).wrapping_add(piece) as size_t; + (*ch).datasize = ((*ch).datasize as u64).wrapping_sub(piece) as curl_off_t; + datap = datap.offset(piece as isize); + /* move read pointer forward */ + length = (length as u64).wrapping_sub(piece) as curl_off_t; + /* decrease space left in this round */ + if 0 as i64 == (*ch).datasize { + /* end of data this round, we now expect a trailing CRLF */ + (*ch).state = CHUNK_POSTLF; + } + } + 3 => { + if *datap as i32 == 0xa as i32 { + /* The last one before we go back to hex state and start all over. */ + Curl_httpchunk_init(data); /* sets state back to CHUNK_HEX */ + } else if *datap as i32 != 0xd as i32 { + return CHUNKE_BAD_CHUNK; + } + datap = datap.offset(1); + length -= 1; + } + 5 => { + if *datap as i32 == 0xd as i32 || *datap as i32 == 0xa as i32 { + let mut tr: *mut libc::c_char = Curl_dyn_ptr(&mut (*conn).trailer); + /* this is the end of a trailer, but if the trailer was zero bytes + there was no trailer and we move on */ + if !tr.is_null() { + let mut trlen: size_t = 0; + result = Curl_dyn_add( + &mut (*conn).trailer, + b"\r\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + if result as u64 != 0 { + return CHUNKE_OUT_OF_MEMORY; + } + tr = Curl_dyn_ptr(&mut (*conn).trailer); + trlen = Curl_dyn_len(&mut (*conn).trailer); + /* Convert to host encoding before calling Curl_client_write */ + result = CURLE_OK as CURLcode; + if result as u64 != 0 { + /* Curl_convert_from_network calls failf if unsuccessful */ + /* Treat it as a bad chunk */ + return CHUNKE_BAD_CHUNK; + } + if ((*data).set).http_te_skip() == 0 { + /* already on the LF */ + result = Curl_client_write(data, (1 as i32) << 1 as i32, tr, trlen); + if result as u64 != 0 { + *extrap = result; + return CHUNKE_PASSTHRU_ERROR; + } + } + Curl_dyn_reset(&mut (*conn).trailer); + /* no trailer, we're on the final CRLF pair */ + (*ch).state = CHUNK_TRAILER_CR; + if *datap as i32 == 0xa as i32 { + current_block_101 = 15586796709793571329; + } else { + current_block_101 = 14329534724295951598; + } + } else { + (*ch).state = CHUNK_TRAILER_POSTCR; + current_block_101 = 15586796709793571329; + } + } else { + result = Curl_dyn_addn( + &mut (*conn).trailer, + datap as *const libc::c_void, + 1 as size_t, + ); + if result as u64 != 0 { + return CHUNKE_OUT_OF_MEMORY; + } + current_block_101 = 14329534724295951598; + } + match current_block_101 { + 15586796709793571329 => {} + _ => { + datap = datap.offset(1); + length -= 1; + } + } + } + 6 => { + if *datap as i32 == 0xa as i32 { + /* no trailer, we're on the final CRLF pair */ + (*ch).state = CHUNK_TRAILER_POSTCR; + datap = datap.offset(1); + length -= 1; + /* don't advance the pointer */ + } else { + return CHUNKE_BAD_CHUNK; + } + } + 7 => { + /* We enter this state when a CR should arrive so we expect to + have to first pass a CR before we wait for LF */ + if *datap as i32 != 0xd as i32 && *datap as i32 != 0xa as i32 + /* not a CR then it must be another header in the trailer */ + { + (*ch).state = CHUNK_TRAILER; + } else { + if *datap as i32 == 0xd as i32 { + /* skip if CR */ + datap = datap.offset(1); + length -= 1; + } + /* now wait for the final LF */ + (*ch).state = CHUNK_STOP; /* return stop */ + } + } + 4 => { + if *datap as i32 == 0xa as i32 { + length -= 1; + /* Record the length of any data left in the end of the buffer + even if there's no more chunks to read */ + (*ch).datasize = curlx_sotouz(length) as curl_off_t; + return CHUNKE_STOP; /* return stop */ + } else { + return CHUNKE_BAD_CHUNK; + } + } + _ => {} } - } - return CHUNKE_OK; - } - #[no_mangle] - pub extern "C" fn Curl_chunked_strerror(mut code: CHUNKcode) -> *const libc::c_char { - unsafe{ - match code as i32 { - 1 => return b"Too long hexadecimal number\0" as *const u8 as *const libc::c_char, - 2 => { - return b"Illegal or missing hexadecimal sequence\0" as *const u8 - as *const libc::c_char; - } - 3 => return b"Malformed encoding found\0" as *const u8 as *const libc::c_char, - 6 => { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - __assert_fail( - b"0\0" as *const u8 as *const libc::c_char, - b"http_chunks.c\0" as *const u8 as *const libc::c_char, - 334, - (*::std::mem::transmute::<&[u8; 45], &[libc::c_char; 45]>( - b"const char *Curl_chunked_strerror(CHUNKcode)\0", - )) - .as_ptr(), - ); - return b"\0" as *const u8 as *const libc::c_char; - } - 4 => return b"Bad content-encoding found\0" as *const u8 as *const libc::c_char, - 5 => return b"Out of memory\0" as *const u8 as *const libc::c_char, - _ => return b"OK\0" as *const u8 as *const libc::c_char, - }; } - } - /* CURL_DISABLE_HTTP */ - \ No newline at end of file + } + return CHUNKE_OK; +} +#[no_mangle] +pub extern "C" fn Curl_chunked_strerror(mut code: CHUNKcode) -> *const libc::c_char { + unsafe { + match code as i32 { + 1 => return b"Too long hexadecimal number\0" as *const u8 as *const libc::c_char, + 2 => { + return b"Illegal or missing hexadecimal sequence\0" as *const u8 + as *const libc::c_char; + } + 3 => return b"Malformed encoding found\0" as *const u8 as *const libc::c_char, + 6 => { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + __assert_fail( + b"0\0" as *const u8 as *const libc::c_char, + b"http_chunks.c\0" as *const u8 as *const libc::c_char, + 334, + (*::std::mem::transmute::<&[u8; 45], &[libc::c_char; 45]>( + b"const char *Curl_chunked_strerror(CHUNKcode)\0", + )) + .as_ptr(), + ); + return b"\0" as *const u8 as *const libc::c_char; + } + 4 => return b"Bad content-encoding found\0" as *const u8 as *const libc::c_char, + 5 => return b"Out of memory\0" as *const u8 as *const libc::c_char, + _ => return b"OK\0" as *const u8 as *const libc::c_char, + }; + } +} +/* CURL_DISABLE_HTTP */ diff --git a/rust/rust_project/src/http_digest.rs b/rust/rust_project/src/http_digest.rs index e943c4b..0429141 100644 --- a/rust/rust_project/src/http_digest.rs +++ b/rust/rust_project/src/http_digest.rs @@ -12,210 +12,205 @@ * Create: 2022-10-31 * Description: http digest ******************************************************************************/ - use ::libc; - use rust_ffi::src::ffi_alias::type_alias::*; - use rust_ffi::src::ffi_fun::fun_call::*; - use rust_ffi::src::ffi_struct::struct_define::*; - - /* Test example headers: - - WWW-Authenticate: Digest realm="testrealm", nonce="1053604598" - Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598" - - */ - - #[no_mangle] - pub extern "C" fn Curl_input_digest( - mut data: *mut Curl_easy, - mut proxy: bool, - mut header: *const libc::c_char, - ) -> CURLcode { - /* rest of the *-authenticate: - header */ - let mut digest: *mut digestdata = 0 as *mut digestdata; - /* Point to the correct struct with this */ - if proxy { - digest = unsafe{&mut (*data).state.proxydigest}; - } else { - digest = unsafe{&mut (*data).state.digest}; - } - if unsafe{curl_strnequal( - b"Digest\0" as *const u8 as *const libc::c_char, - header, - strlen(b"Digest\0" as *const u8 as *const libc::c_char), - )} == 0 - || unsafe{Curl_isspace(*header.offset(6 as i32 as isize) as u8 as i32)} - == 0 - { - return CURLE_BAD_CONTENT_ENCODING; - } - header = unsafe{header.offset(strlen(b"Digest\0" as *const u8 as *const libc::c_char) as isize)}; - while unsafe{*header as i32 }!= 0 && unsafe{Curl_isspace(*header as u8 as i32)} != 0 - { - header =unsafe{ header.offset(1)}; - } - return unsafe{Curl_auth_decode_digest_http_message(header, digest)}; - - } - #[no_mangle] - pub extern "C" fn Curl_output_digest( - mut data: *mut Curl_easy, - mut proxy: bool, - mut request: *const u8, - mut uripath: *const u8, - ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut path: *mut u8 = 0 as *mut u8; - let mut tmp: *mut libc::c_char = 0 as *mut libc::c_char; - let mut response: *mut libc::c_char = 0 as *mut libc::c_char; - let mut len: size_t = 0; - let mut have_chlg: bool = false; - /* Point to the address of the pointer that holds the string to send to the - server, which is for a plain host or for a HTTP proxy */ - let mut allocuserpwd: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; - /* Point to the name and password for this */ - let mut userp: *const libc::c_char = 0 as *const libc::c_char; - let mut passwdp: *const libc::c_char = 0 as *const libc::c_char; - /* Point to the correct struct with this */ - let mut digest: *mut digestdata = 0 as *mut digestdata; - let mut authp: *mut auth = 0 as *mut auth; - if proxy { - if cfg!(not(CURL_DISABLE_PROXY)) { - unsafe{ - digest = &mut (*data).state.proxydigest; - allocuserpwd = &mut (*data).state.aptr.proxyuserpwd; - userp = (*data).state.aptr.proxyuser; - passwdp = (*data).state.aptr.proxypasswd; - authp = &mut (*data).state.authproxy; +use ::libc; +use rust_ffi::src::ffi_alias::type_alias::*; +use rust_ffi::src::ffi_fun::fun_call::*; +use rust_ffi::src::ffi_struct::struct_define::*; + +/* Test example headers: + +WWW-Authenticate: Digest realm="testrealm", nonce="1053604598" +Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598" + +*/ + +#[no_mangle] +pub extern "C" fn Curl_input_digest( + mut data: *mut Curl_easy, + mut proxy: bool, + mut header: *const libc::c_char, +) -> CURLcode { + /* rest of the *-authenticate: + header */ + let mut digest: *mut digestdata =unsafe { 0 as *mut digestdata}; + /* Point to the correct struct with this */ + unsafe { + if proxy { + digest = &mut (*data).state.proxydigest; + } else { + digest = &mut (*data).state.digest; + } + if curl_strnequal( + b"Digest\0" as *const u8 as *const libc::c_char, + header, + strlen(b"Digest\0" as *const u8 as *const libc::c_char), + ) == 0 + || Curl_isspace(*header.offset(6 as i32 as isize) as u8 as i32) == 0 + { + return CURLE_BAD_CONTENT_ENCODING; + } + header = header.offset(strlen(b"Digest\0" as *const u8 as *const libc::c_char) as isize); + while *header as i32 != 0 && Curl_isspace(*header as u8 as i32) != 0 { + header = header.offset(1); + } + return Curl_auth_decode_digest_http_message(header, digest); + } +} +#[no_mangle] +pub extern "C" fn Curl_output_digest( + mut data: *mut Curl_easy, + mut proxy: bool, + mut request: *const u8, + mut uripath: *const u8, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut path: *mut u8 =unsafe { 0 as *mut u8}; + let mut tmp: *mut libc::c_char =unsafe { 0 as *mut libc::c_char}; + let mut response: *mut libc::c_char =unsafe { 0 as *mut libc::c_char}; + let mut len: size_t = 0; + let mut have_chlg: bool = false; + /* Point to the address of the pointer that holds the string to send to the + server, which is for a plain host or for a HTTP proxy */ + let mut allocuserpwd: *mut *mut libc::c_char =unsafe { 0 as *mut *mut libc::c_char}; + /* Point to the name and password for this */ + let mut userp: *const libc::c_char =unsafe { 0 as *const libc::c_char}; + let mut passwdp: *const libc::c_char =unsafe { 0 as *const libc::c_char}; + /* Point to the correct struct with this */ + let mut digest: *mut digestdata = unsafe {0 as *mut digestdata}; + let mut authp: *mut auth =unsafe { 0 as *mut auth}; + unsafe { + if proxy { + if cfg!(not(CURL_DISABLE_PROXY)) { + digest = &mut (*data).state.proxydigest; + allocuserpwd = &mut (*data).state.aptr.proxyuserpwd; + userp = (*data).state.aptr.proxyuser; + passwdp = (*data).state.aptr.proxypasswd; + authp = &mut (*data).state.authproxy; + } else { + return CURLE_NOT_BUILT_IN; + } + } else { + digest = &mut (*data).state.digest; + allocuserpwd = &mut (*data).state.aptr.userpwd; + userp = (*data).state.aptr.user; + passwdp = (*data).state.aptr.passwd; + authp = &mut (*data).state.authhost; + } + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(*allocuserpwd as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + *allocuserpwd as *mut libc::c_void, + 112 as i32, + b"http_digest.c\0" as *const u8 as *const libc::c_char, + ); + *allocuserpwd = 0 as *mut libc::c_char; + /* not set means empty */ + if userp.is_null() { + userp = b"\0" as *const u8 as *const libc::c_char; + } + if passwdp.is_null() { + passwdp = b"\0" as *const u8 as *const libc::c_char; + } + have_chlg = if !((*digest).nonce).is_null() { + 1 as i32 + } else { + 0 as i32 + } != 0; + if !have_chlg { + (*authp).set_done(0 as bit); + return CURLE_OK; + } + /* So IE browsers < v7 cut off the URI part at the query part when they + evaluate the MD5 and some (IIS?) servers work with them so we may need to + do the Digest IE-style. Note that the different ways cause different MD5 + sums to get sent. + + Apache servers can be set to do the Digest IE-style automatically using + the BrowserMatch feature: + https://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie + + Further details on Digest implementation differences: + http://www.fngtps.com/2006/09/http-authentication + */ + + if (*authp).iestyle() != 0 { + tmp = strchr(uripath as *mut libc::c_char, '?' as i32); + if !tmp.is_null() { + let mut urilen: size_t = tmp.offset_from(uripath as *mut libc::c_char) as size_t; + /* typecast is fine here since the value is always less than 32 bits */ + path = curl_maprintf( + b"%.*s\0" as *const u8 as *const libc::c_char, + urilen as i32, + uripath, + ) as *mut u8; } - } else { - return CURLE_NOT_BUILT_IN; - } - } else { - unsafe{ - digest = &mut (*data).state.digest; - allocuserpwd = &mut (*data).state.aptr.userpwd; - userp = (*data).state.aptr.user; - passwdp = (*data).state.aptr.passwd; - authp = &mut (*data).state.authhost; } - } - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(*allocuserpwd as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - *allocuserpwd as *mut libc::c_void, - 112 as i32, - b"http_digest.c\0" as *const u8 as *const libc::c_char, - );} - unsafe{*allocuserpwd = 0 as *mut libc::c_char;} - /* not set means empty */ - if userp.is_null() { - userp = b"\0" as *const u8 as *const libc::c_char; - } - if passwdp.is_null() { - passwdp = b"\0" as *const u8 as *const libc::c_char; - } - have_chlg = if unsafe{ !((*digest).nonce).is_null()} { - 1 as i32 - } else { - 0 as i32 - } != 0; - if !have_chlg { - unsafe{(*authp).set_done(0 as bit);} - return CURLE_OK; - } - /* So IE browsers < v7 cut off the URI part at the query part when they - evaluate the MD5 and some (IIS?) servers work with them so we may need to - do the Digest IE-style. Note that the different ways cause different MD5 - sums to get sent. - - Apache servers can be set to do the Digest IE-style automatically using - the BrowserMatch feature: - https://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie - - Further details on Digest implementation differences: - http://www.fngtps.com/2006/09/http-authentication - */ - - if unsafe{ (*authp).iestyle()} != 0 { - tmp = unsafe{strchr(uripath as *mut libc::c_char, '?' as i32)}; - if !tmp.is_null() { - let mut urilen: size_t = - unsafe{tmp.offset_from(uripath as *mut libc::c_char) as size_t}; - /* typecast is fine here since the value is always less than 32 bits */ - path = unsafe{curl_maprintf( - b"%.*s\0" as *const u8 as *const libc::c_char, - urilen as i32, - uripath, - ) as *mut u8}; - } - } - if tmp.is_null() { - #[cfg(not(CURLDEBUG))] - let mut newpath: *mut u8 = - unsafe{Curl_cstrdup.expect("non-null function pointer")(uripath as *mut libc::c_char) - as *mut u8}; - #[cfg(CURLDEBUG)] - let mut newpath: *mut u8 = unsafe{curl_dbg_strdup( - uripath as *mut libc::c_char, - 154 as i32, - b"http_digest.c\0" as *const u8 as *const libc::c_char, - ) as *mut u8}; - path = newpath; - } - if path.is_null() { - return CURLE_OUT_OF_MEMORY; - } - result = unsafe{Curl_auth_create_digest_http_message( - data, - userp, - passwdp, - request, - path, - digest, - &mut response, - &mut len, - )}; - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(path as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - path as *mut libc::c_void, - 161 as i32, - b"http_digest.c\0" as *const u8 as *const libc::c_char, - );} - if result as u64 != 0 { - return result; - } - unsafe{*allocuserpwd = curl_maprintf( - b"%sAuthorization: Digest %s\r\n\0" as *const u8 as *const libc::c_char, - if proxy as i32 != 0 { - b"Proxy-\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - response, - );} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(response as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - response as *mut libc::c_void, - 168 as i32, - b"http_digest.c\0" as *const u8 as *const libc::c_char, - );} - if unsafe{(*allocuserpwd).is_null()} { - return CURLE_OUT_OF_MEMORY; - } - unsafe{(*authp).set_done(1 as bit);} - return CURLE_OK; - - } - #[no_mangle] - pub extern "C" fn Curl_http_auth_cleanup_digest(mut data: *mut Curl_easy) { - unsafe{ - Curl_auth_digest_cleanup(&mut (*data).state.digest); - Curl_auth_digest_cleanup(&mut (*data).state.proxydigest); - } - } \ No newline at end of file + if tmp.is_null() { + #[cfg(not(CURLDEBUG))] + let mut newpath: *mut u8 = + Curl_cstrdup.expect("non-null function pointer")(uripath as *mut libc::c_char) + as *mut u8; + #[cfg(CURLDEBUG)] + let mut newpath: *mut u8 = curl_dbg_strdup( + uripath as *mut libc::c_char, + 154 as i32, + b"http_digest.c\0" as *const u8 as *const libc::c_char, + ) as *mut u8; + path = newpath; + } + if path.is_null() { + return CURLE_OUT_OF_MEMORY; + } + result = Curl_auth_create_digest_http_message( + data, + userp, + passwdp, + request, + path, + digest, + &mut response, + &mut len, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(path as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + path as *mut libc::c_void, + 161 as i32, + b"http_digest.c\0" as *const u8 as *const libc::c_char, + ); + if result as u64 != 0 { + return result; + } + *allocuserpwd = curl_maprintf( + b"%sAuthorization: Digest %s\r\n\0" as *const u8 as *const libc::c_char, + if proxy as i32 != 0 { + b"Proxy-\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + response, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(response as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + response as *mut libc::c_void, + 168 as i32, + b"http_digest.c\0" as *const u8 as *const libc::c_char, + ); + if (*allocuserpwd).is_null() { + return CURLE_OUT_OF_MEMORY; + } + (*authp).set_done(1 as bit); + return CURLE_OK; + } +} +#[no_mangle] +pub extern "C" fn Curl_http_auth_cleanup_digest(mut data: *mut Curl_easy) { + unsafe { + Curl_auth_digest_cleanup(&mut (*data).state.digest); + Curl_auth_digest_cleanup(&mut (*data).state.proxydigest); + } +} diff --git a/rust/rust_project/src/http_negotiate.rs b/rust/rust_project/src/http_negotiate.rs index 082baf4..0b8f4f1 100644 --- a/rust/rust_project/src/http_negotiate.rs +++ b/rust/rust_project/src/http_negotiate.rs @@ -8,301 +8,276 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: pnext, + * Author: pnext, * Create: 2022-10-31 * Description: http negotiate ******************************************************************************/ - use ::libc; - use rust_ffi::src::ffi_alias::type_alias::*; - use rust_ffi::src::ffi_fun::fun_call::*; - use rust_ffi::src::ffi_struct::struct_define::*; - - #[no_mangle] - pub extern "C" fn Curl_input_negotiate( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut proxy: bool, - mut header: *const libc::c_char, - ) -> CURLcode { - unsafe{ - let mut result: CURLcode = CURLE_OK; - let mut len: size_t = 0; - let mut userp: *const libc::c_char = 0 as *const libc::c_char; - let mut passwdp: *const libc::c_char = 0 as *const libc::c_char; - let mut service: *const libc::c_char = 0 as *const libc::c_char; - let mut host: *const libc::c_char = 0 as *const libc::c_char; - let mut neg_ctx: *mut negotiatedata = 0 as *mut negotiatedata; - let mut state: curlnegotiate = GSS_AUTHNONE; - if proxy { - match () { - #[cfg(not(CURL_DISABLE_PROXY))] - _ => { - userp = (*conn).http_proxy.user; - passwdp = (*conn).http_proxy.passwd; - service = if !((*data) - .set - .str_0[STRING_PROXY_SERVICE_NAME as i32 as usize]) - .is_null() - { - (*data).set.str_0[STRING_PROXY_SERVICE_NAME as i32 as usize] - as *const libc::c_char - } else { - b"HTTP\0" as *const u8 as *const libc::c_char - }; - host = (*conn).http_proxy.host.name; - neg_ctx = &mut (*conn).proxyneg; - state = (*conn).proxy_negotiate_state; - } - #[cfg(CURL_DISABLE_PROXY)] - _ => { - return CURLE_NOT_BUILT_IN; - } - } - } else { - userp = (*conn).user; - passwdp = (*conn).passwd; - service = if !((*data).set.str_0[STRING_SERVICE_NAME as i32 as usize]) - .is_null() - { - (*data).set.str_0[STRING_SERVICE_NAME as i32 as usize] - as *const libc::c_char - } else { - b"HTTP\0" as *const u8 as *const libc::c_char - }; - host = (*conn).host.name; - neg_ctx = &mut (*conn).negotiate; - state = (*conn).http_negotiate_state; - } - if userp.is_null() { - userp = b"\0" as *const u8 as *const libc::c_char; - } - if passwdp.is_null() { - passwdp = b"\0" as *const u8 as *const libc::c_char; - } - header = header - .offset(strlen(b"Negotiate\0" as *const u8 as *const libc::c_char) as isize); - while *header as i32 != 0 - && Curl_isspace(*header as u8 as i32) != 0 - { - header = header.offset(1); - } - len = strlen(header); - (*neg_ctx) - .set_havenegdata( - (len != 0 as i32 as u64) as i32 as bit, - ); +use ::libc; +use rust_ffi::src::ffi_alias::type_alias::*; +use rust_ffi::src::ffi_fun::fun_call::*; +use rust_ffi::src::ffi_struct::struct_define::*; - if len == 0 { - if state as u32 == GSS_AUTHSUCC as i32 as u32 { - unsafe{ - Curl_infof( - data, - b"Negotiate auth restarted\0" as *const u8 as *const libc::c_char, - ); +#[no_mangle] +pub extern "C" fn Curl_input_negotiate( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut proxy: bool, + mut header: *const libc::c_char, +) -> CURLcode { + unsafe { + let mut result: CURLcode = CURLE_OK; + let mut len: size_t = 0; + let mut userp: *const libc::c_char = 0 as *const libc::c_char; + let mut passwdp: *const libc::c_char = 0 as *const libc::c_char; + let mut service: *const libc::c_char = 0 as *const libc::c_char; + let mut host: *const libc::c_char = 0 as *const libc::c_char; + let mut neg_ctx: *mut negotiatedata = 0 as *mut negotiatedata; + let mut state: curlnegotiate = GSS_AUTHNONE; + if proxy { + match () { + #[cfg(not(CURL_DISABLE_PROXY))] + _ => { + userp = (*conn).http_proxy.user; + passwdp = (*conn).http_proxy.passwd; + service = if !((*data).set.str_0[STRING_PROXY_SERVICE_NAME as i32 as usize]) + .is_null() + { + (*data).set.str_0[STRING_PROXY_SERVICE_NAME as i32 as usize] + as *const libc::c_char + } else { + b"HTTP\0" as *const u8 as *const libc::c_char + }; + host = (*conn).http_proxy.host.name; + neg_ctx = &mut (*conn).proxyneg; + state = (*conn).proxy_negotiate_state; + } + #[cfg(CURL_DISABLE_PROXY)] + _ => { + return CURLE_NOT_BUILT_IN; + } } - Curl_http_auth_cleanup_negotiate(conn); - } else if state as u32 != GSS_AUTHNONE as i32 as u32 { - Curl_http_auth_cleanup_negotiate(conn); - return CURLE_LOGIN_DENIED; - } - } - result = Curl_auth_decode_spnego_message( - data, - userp, - passwdp, - service, - host, - header, - neg_ctx, - ); - if result as u64 != 0 { - Curl_http_auth_cleanup_negotiate(conn); - } - return result; - } - } - #[no_mangle] - pub extern "C" fn Curl_output_negotiate( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut proxy: bool, - ) -> CURLcode { - - let mut neg_ctx: *mut negotiatedata = if proxy as i32 != 0 { - unsafe{ - &mut (*conn).proxyneg + } else { + userp = (*conn).user; + passwdp = (*conn).passwd; + service = if !((*data).set.str_0[STRING_SERVICE_NAME as i32 as usize]).is_null() { + (*data).set.str_0[STRING_SERVICE_NAME as i32 as usize] as *const libc::c_char + } else { + b"HTTP\0" as *const u8 as *const libc::c_char + }; + host = (*conn).host.name; + neg_ctx = &mut (*conn).negotiate; + state = (*conn).http_negotiate_state; } - } else { - unsafe{ - &mut (*conn).negotiate + if userp.is_null() { + userp = b"\0" as *const u8 as *const libc::c_char; } - }; - let mut authp: *mut auth = if proxy as i32 != 0 { - unsafe{ - &mut (*data).state.authproxy + if passwdp.is_null() { + passwdp = b"\0" as *const u8 as *const libc::c_char; } - } else { - unsafe{ - &mut (*data).state.authhost + header = header.offset(strlen(b"Negotiate\0" as *const u8 as *const libc::c_char) as isize); + while *header as i32 != 0 && Curl_isspace(*header as u8 as i32) != 0 { + header = header.offset(1); } - }; - let mut state: *mut curlnegotiate = if proxy as i32 != 0 { - unsafe{ - &mut (*conn).proxy_negotiate_state + len = strlen(header); + (*neg_ctx).set_havenegdata((len != 0 as i32 as u64) as i32 as bit); + + if len == 0 { + if state as u32 == GSS_AUTHSUCC as i32 as u32 { + unsafe { + Curl_infof( + data, + b"Negotiate auth restarted\0" as *const u8 as *const libc::c_char, + ); + } + Curl_http_auth_cleanup_negotiate(conn); + } else if state as u32 != GSS_AUTHNONE as i32 as u32 { + Curl_http_auth_cleanup_negotiate(conn); + return CURLE_LOGIN_DENIED; + } } - } else { - unsafe{ - &mut (*conn).http_negotiate_state + result = + Curl_auth_decode_spnego_message(data, userp, passwdp, service, host, header, neg_ctx); + if result as u64 != 0 { + Curl_http_auth_cleanup_negotiate(conn); + } + return result; + } +} +#[no_mangle] +pub extern "C" fn Curl_output_negotiate( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut proxy: bool, +) -> CURLcode { + let mut neg_ctx: *mut negotiatedata = if proxy as i32 != 0 { + unsafe { &mut (*conn).proxyneg } + } else { + unsafe { &mut (*conn).negotiate } + }; + let mut authp: *mut auth = if proxy as i32 != 0 { + unsafe { &mut (*data).state.authproxy } + } else { + unsafe { &mut (*data).state.authhost } + }; + let mut state: *mut curlnegotiate = if proxy as i32 != 0 { + unsafe { &mut (*conn).proxy_negotiate_state } + } else { + unsafe { &mut (*conn).http_negotiate_state } + }; + let mut base64: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: size_t = 0 as i32 as size_t; + let mut userp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result: CURLcode = CURLE_OK; + unsafe { + (*authp).set_done(0 as i32 as bit); + } + if unsafe { *state as u32 } == GSS_AUTHRECV as i32 as u32 { + if unsafe { (*neg_ctx).havenegdata() } != 0 { + unsafe { + (*neg_ctx).set_havemultiplerequests(1 as i32 as bit); + } } - }; - let mut base64: *mut libc::c_char = 0 as *mut libc::c_char; - let mut len: size_t = 0 as i32 as size_t; - let mut userp: *mut libc::c_char = 0 as *mut libc::c_char; - let mut result: CURLcode = CURLE_OK; - unsafe{ - (*authp).set_done(0 as i32 as bit); - } - if unsafe{ *state as u32} == GSS_AUTHRECV as i32 as u32{ - if unsafe{(*neg_ctx).havenegdata()} != 0 { - unsafe{ - (*neg_ctx).set_havemultiplerequests(1 as i32 as bit); + } else if unsafe { *state as u32 } == GSS_AUTHSUCC as i32 as u32 { + if unsafe { (*neg_ctx).havenoauthpersist() } == 0 { + unsafe { + (*neg_ctx) + .set_noauthpersist(((*neg_ctx).havemultiplerequests() == 0) as i32 as bit); } - } - } else if unsafe{*state as u32 }== GSS_AUTHSUCC as i32 as u32 { - if unsafe{(*neg_ctx).havenoauthpersist() }== 0 { - unsafe{ - (*neg_ctx) - .set_noauthpersist( - ((*neg_ctx).havemultiplerequests() == 0) as i32 as bit, - ); - } - } - } - if unsafe{(*neg_ctx).noauthpersist() as i32} != 0 - ||unsafe{ *state as u32} != GSS_AUTHDONE as i32 as u32 - && unsafe{*state as u32} != GSS_AUTHSUCC as i32 as u32 - { - if unsafe{(*neg_ctx).noauthpersist() as i32 }!= 0 - && unsafe{*state as u32 }== GSS_AUTHSUCC as i32 as u32 - {unsafe{ - Curl_infof( + } + } + if unsafe { (*neg_ctx).noauthpersist() as i32 } != 0 + || unsafe { *state as u32 } != GSS_AUTHDONE as i32 as u32 + && unsafe { *state as u32 } != GSS_AUTHSUCC as i32 as u32 + { + if unsafe { (*neg_ctx).noauthpersist() as i32 } != 0 + && unsafe { *state as u32 } == GSS_AUTHSUCC as i32 as u32 + { + unsafe { + Curl_infof( data, b"Curl_output_negotiate, no persistent authentication: cleanup existing context\0" as *const u8 as *const libc::c_char, ); - Curl_http_auth_cleanup_negotiate(conn); + Curl_http_auth_cleanup_negotiate(conn); } - } - if unsafe{((*neg_ctx).context).is_null() }{ - result = Curl_input_negotiate( - data, - conn, - proxy, - b"Negotiate\0" as *const u8 as *const libc::c_char, - ); - if result as u32 == CURLE_AUTH_ERROR as i32 as u32 - { - unsafe{(*authp).set_done(1 as i32 as bit);} - return CURLE_OK; - } else { - if result as u64 != 0 { - return result; - } - } - } - unsafe{ - result = Curl_auth_create_spnego_message(data, neg_ctx, &mut base64, &mut len);} - if result as u64 != 0 { - return result; - } - unsafe{ - userp = curl_maprintf( - b"%sAuthorization: Negotiate %s\r\n\0" as *const u8 as *const libc::c_char, - if proxy as i32 != 0 { - b"Proxy-\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - base64, - );} - if proxy { - unsafe{ - #[cfg(not(CURLDEBUG))] - Curl_cfree - .expect( - "non-null function pointer", - )((*data).state.aptr.proxyuserpwd as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - 172 as i32, - b"http_negotiate.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh0 = (*data).state.aptr.proxyuserpwd; - unsafe{ (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; - // let ref mut fresh1 = (*data).state.aptr.proxyuserpwd; - (*data).state.aptr.proxyuserpwd = userp; - } - } else { - unsafe{ - #[cfg(not(CURLDEBUG))] - Curl_cfree - .expect( - "non-null function pointer", - )((*data).state.aptr.userpwd as *mut libc::c_void); - - - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.userpwd as *mut libc::c_void, - 176 as i32, - b"http_negotiate.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh2 = (*data).state.aptr.userpwd; - (*data).state.aptr.userpwd = 0 as *mut libc::c_char; - // let ref mut fresh3 = (*data).state.aptr.userpwd; - (*data).state.aptr.userpwd = userp; + } + if unsafe { ((*neg_ctx).context).is_null() } { + result = Curl_input_negotiate( + data, + conn, + proxy, + b"Negotiate\0" as *const u8 as *const libc::c_char, + ); + if result as u32 == CURLE_AUTH_ERROR as i32 as u32 { + unsafe { + (*authp).set_done(1 as i32 as bit); + } + return CURLE_OK; + } else { + if result as u64 != 0 { + return result; + } + } + } + unsafe { + result = Curl_auth_create_spnego_message(data, neg_ctx, &mut base64, &mut len); + } + if result as u64 != 0 { + return result; + } + unsafe { + userp = curl_maprintf( + b"%sAuthorization: Negotiate %s\r\n\0" as *const u8 as *const libc::c_char, + if proxy as i32 != 0 { + b"Proxy-\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + base64, + ); + } + if proxy { + unsafe { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + ); } - } - unsafe{ - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(base64 as *mut libc::c_void); - - - #[cfg(CURLDEBUG)] - curl_dbg_free( - base64 as *mut libc::c_void, - 180 as i32, - b"http_negotiate.c\0" as *const u8 as *const libc::c_char, - );} - if userp.is_null() { - return CURLE_OUT_OF_MEMORY; - } - unsafe{*state = GSS_AUTHSENT;} - #[cfg(HAVE_GSSAPI)] - if unsafe{ (*neg_ctx).status} == 0 as u32 - || unsafe{(*neg_ctx).status} - == ((1 as i32) << 0 as i32 + 0 as i32) - as u32 - { - unsafe{*state = GSS_AUTHDONE;} - } - } - if unsafe{*state as u32} == GSS_AUTHDONE as u32 - || unsafe{*state as u32 }== GSS_AUTHSUCC as u32 - { - unsafe{(*authp).set_done(1 as bit);} - } - unsafe{(*neg_ctx).set_havenegdata(0 as bit);} - return CURLE_OK; - } - #[no_mangle] - pub extern "C" fn Curl_http_auth_cleanup_negotiate(mut conn: *mut connectdata) { - unsafe{ - (*conn).http_negotiate_state = GSS_AUTHNONE; - (*conn).proxy_negotiate_state = GSS_AUTHNONE; - Curl_auth_cleanup_spnego(&mut (*conn).negotiate); - Curl_auth_cleanup_spnego(&mut (*conn).proxyneg); - } - } - \ No newline at end of file + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + 172 as i32, + b"http_negotiate.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh0 = (*data).state.aptr.proxyuserpwd; + unsafe { + (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; + // let ref mut fresh1 = (*data).state.aptr.proxyuserpwd; + (*data).state.aptr.proxyuserpwd = userp; + } + } else { + unsafe { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.userpwd as *mut libc::c_void, + ); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.userpwd as *mut libc::c_void, + 176 as i32, + b"http_negotiate.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh2 = (*data).state.aptr.userpwd; + (*data).state.aptr.userpwd = 0 as *mut libc::c_char; + // let ref mut fresh3 = (*data).state.aptr.userpwd; + (*data).state.aptr.userpwd = userp; + } + } + unsafe { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(base64 as *mut libc::c_void); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + base64 as *mut libc::c_void, + 180 as i32, + b"http_negotiate.c\0" as *const u8 as *const libc::c_char, + ); + } + if userp.is_null() { + return CURLE_OUT_OF_MEMORY; + } + unsafe { + *state = GSS_AUTHSENT; + } + #[cfg(HAVE_GSSAPI)] + if unsafe { (*neg_ctx).status } == 0 as u32 + || unsafe { (*neg_ctx).status } == ((1 as i32) << 0 as i32 + 0 as i32) as u32 + { + unsafe { + *state = GSS_AUTHDONE; + } + } + } + if unsafe { *state as u32 } == GSS_AUTHDONE as u32 + || unsafe { *state as u32 } == GSS_AUTHSUCC as u32 + { + unsafe { + (*authp).set_done(1 as bit); + } + } + unsafe { + (*neg_ctx).set_havenegdata(0 as bit); + } + return CURLE_OK; +} +#[no_mangle] +pub extern "C" fn Curl_http_auth_cleanup_negotiate(mut conn: *mut connectdata) { + unsafe { + (*conn).http_negotiate_state = GSS_AUTHNONE; + (*conn).proxy_negotiate_state = GSS_AUTHNONE; + Curl_auth_cleanup_spnego(&mut (*conn).negotiate); + Curl_auth_cleanup_spnego(&mut (*conn).proxyneg); + } +} diff --git a/rust/rust_project/src/http_ntlm.rs b/rust/rust_project/src/http_ntlm.rs index 7773232..cff393e 100644 --- a/rust/rust_project/src/http_ntlm.rs +++ b/rust/rust_project/src/http_ntlm.rs @@ -12,366 +12,355 @@ * Create: 2022-10-31 * Description: http ntlm ******************************************************************************/ - use ::libc; - use rust_ffi::src::ffi_alias::type_alias::*; - use rust_ffi::src::ffi_fun::fun_call::*; - use rust_ffi::src::ffi_struct::struct_define::*; - #[no_mangle] - pub extern "C" fn Curl_input_ntlm( - mut data: *mut Curl_easy, - mut proxy: bool,/* if proxy or not */ - mut header: *const libc::c_char,/* rest of the www-authenticate: - header */ - ) -> CURLcode { - /* point to the correct struct with this */ - let mut ntlm: *mut ntlmdata = 0 as *mut ntlmdata; - let mut state: *mut curlntlm = 0 as *mut curlntlm; - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - ntlm = if proxy as i32 != 0 { - unsafe{ &mut (*conn).proxyntlm} - } else { - unsafe{&mut (*conn).ntlm} - }; - state = if proxy as i32 != 0 { - unsafe{&mut (*conn).proxy_ntlm_state} - } else { - unsafe{&mut (*conn).http_ntlm_state} - }; - if unsafe{curl_strnequal( - b"NTLM\0" as *const u8 as *const libc::c_char, - header, - strlen(b"NTLM\0" as *const u8 as *const libc::c_char), - ) }!= 0 - { - header = unsafe{header.offset(strlen(b"NTLM\0" as *const u8 as *const libc::c_char) as isize)}; - while unsafe{ *header as i32} != 0 - && unsafe{Curl_isspace(*header as i32)} != 0 - { - header =unsafe{ header.offset(1)}; - } - if unsafe{*header} != 0 { - let mut hdr: *mut u8 = 0 as *mut u8; - let mut hdrlen: size_t = 0; - result = unsafe{Curl_base64_decode(header, &mut hdr, &mut hdrlen)}; - if result as u64 == 0 { - let mut hdrbuf: bufref = bufref { - dtor: None, - ptr: 0 as *const u8, - len: 0, - #[cfg(CURLDEBUG)] - signature: 0, - }; - unsafe{Curl_bufref_init(&mut hdrbuf); - Curl_bufref_set( - &mut hdrbuf, - hdr as *const libc::c_void, - hdrlen, - Some(curl_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), - );} - result = unsafe{Curl_auth_decode_ntlm_type2_message(data, &mut hdrbuf, ntlm)}; - unsafe{Curl_bufref_free(&mut hdrbuf);} - } - if result as u64 != 0 { - return result; - } - unsafe{*state = NTLMSTATE_TYPE2;} - } else { - if unsafe{ *state as u32} == NTLMSTATE_LAST as u32 { - unsafe{ - Curl_infof( - data, - b"NTLM auth restarted\0" as *const u8 as *const libc::c_char, - ); - Curl_http_auth_cleanup_ntlm(conn); +use ::libc; +use rust_ffi::src::ffi_alias::type_alias::*; +use rust_ffi::src::ffi_fun::fun_call::*; +use rust_ffi::src::ffi_struct::struct_define::*; +#[no_mangle] +pub extern "C" fn Curl_input_ntlm( + mut data: *mut Curl_easy, + mut proxy: bool, /* if proxy or not */ + mut header: *const libc::c_char, /* rest of the www-authenticate: + header */ +) -> CURLcode { + /* point to the correct struct with this */ + let mut ntlm: *mut ntlmdata = 0 as *mut ntlmdata; + let mut state: *mut curlntlm = 0 as *mut curlntlm; + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe {(*data).conn}; + ntlm = if proxy as i32 != 0 { + unsafe {&mut (*conn).proxyntlm} + } else { + unsafe {&mut (*conn).ntlm} + }; + state = if proxy as i32 != 0 { + unsafe {&mut (*conn).proxy_ntlm_state} + } else { + unsafe {&mut (*conn).http_ntlm_state} + }; + if unsafe {curl_strnequal( + b"NTLM\0" as *const u8 as *const libc::c_char, + header, + strlen(b"NTLM\0" as *const u8 as *const libc::c_char), + ) != 0} + { + unsafe { + header = header.offset(strlen(b"NTLM\0" as *const u8 as *const libc::c_char) as isize); + while *header as i32 != 0 && Curl_isspace(*header as i32) != 0 { + header = header.offset(1); + } + if *header != 0 { + let mut hdr: *mut u8 = 0 as *mut u8; + let mut hdrlen: size_t = 0; + result = Curl_base64_decode(header, &mut hdr, &mut hdrlen); + if result as u64 == 0 { + let mut hdrbuf: bufref = bufref { + dtor: None, + ptr: 0 as *const u8, + len: 0, + #[cfg(CURLDEBUG)] + signature: 0, + }; + Curl_bufref_init(&mut hdrbuf); + Curl_bufref_set( + &mut hdrbuf, + hdr as *const libc::c_void, + hdrlen, + Some(curl_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), + ); + result = Curl_auth_decode_ntlm_type2_message(data, &mut hdrbuf, ntlm); + Curl_bufref_free(&mut hdrbuf); } - } else if unsafe{*state as u32} == NTLMSTATE_TYPE3 as u32 { - unsafe{ - Curl_infof( - data, - b"NTLM handshake rejected\0" as *const u8 as *const libc::c_char, - ); - Curl_http_auth_cleanup_ntlm(conn); - *state = NTLMSTATE_NONE; - return CURLE_REMOTE_ACCESS_DENIED; + if result as u64 != 0 { + return result; } - } else if unsafe{*state as u32} >= NTLMSTATE_TYPE1 as u32 { - // if *state as u32 >= NTLMSTATE_TYPE1 as i32 as u32 { - unsafe{Curl_infof( - data, - b"NTLM handshake failure (internal error)\0" as *const u8 - as *const libc::c_char, - );} - return CURLE_REMOTE_ACCESS_DENIED; - // } - } - unsafe{*state = NTLMSTATE_TYPE1;} - } - } - return result; - - - } - #[no_mangle] - pub extern "C" fn Curl_output_ntlm(mut data: *mut Curl_easy, mut proxy: bool) -> CURLcode { - let mut base64: *mut libc::c_char = 0 as *mut libc::c_char; - let mut len: size_t = 0 as size_t; - let mut result: CURLcode = CURLE_OK; - let mut ntlmmsg: bufref = bufref { - dtor: None, - ptr: 0 as *const u8, - len: 0, - #[cfg(CURLDEBUG)] - signature: 0, - }; - let mut allocuserpwd: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; - let mut userp: *const libc::c_char = 0 as *const libc::c_char; - let mut passwdp: *const libc::c_char = 0 as *const libc::c_char; - let mut service: *const libc::c_char = 0 as *const libc::c_char; - let mut hostname: *const libc::c_char = 0 as *const libc::c_char; - let mut ntlm: *mut ntlmdata = 0 as *mut ntlmdata; - let mut state: *mut curlntlm = 0 as *mut curlntlm; - let mut authp: *mut auth = 0 as *mut auth; - let mut conn: *mut connectdata = unsafe{(*data).conn}; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{ !conn.is_null()} { - } else { - unsafe{ - __assert_fail( - b"conn\0" as *const u8 as *const libc::c_char, - b"http_ntlm.c\0" as *const u8 as *const libc::c_char, - 150, - (*::std::mem::transmute::<&[u8; 53], &[libc::c_char; 53]>( - b"CURLcode Curl_output_ntlm(struct Curl_easy *, _Bool)\0", - )) - .as_ptr(), - );} - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{!data.is_null()} { - } else { - unsafe{ - __assert_fail( - b"data\0" as *const u8 as *const libc::c_char, - b"http_ntlm.c\0" as *const u8 as *const libc::c_char, - 151, - (*::std::mem::transmute::<&[u8; 53], &[libc::c_char; 53]>( - b"CURLcode Curl_output_ntlm(struct Curl_easy *, _Bool)\0", - )) - .as_ptr(), - );} - } - if proxy { - unsafe{ - match () { - #[cfg(not(CURL_DISABLE_PROXY))] - _ => { - allocuserpwd = &mut (*data).state.aptr.proxyuserpwd; - userp = (*data).state.aptr.proxyuser; - passwdp = (*data).state.aptr.proxypasswd; - service = if !((*data).set.str_0[STRING_PROXY_SERVICE_NAME as usize]) - .is_null() - { - (*data).set.str_0[STRING_PROXY_SERVICE_NAME as usize] - as *const libc::c_char - } else { - b"HTTP\0" as *const u8 as *const libc::c_char - }; - hostname = (*conn).http_proxy.host.name; - ntlm = &mut (*conn).proxyntlm; - state = &mut (*conn).proxy_ntlm_state; - authp = &mut (*data).state.authproxy; - } - #[cfg(CURL_DISABLE_PROXY)] - _ => { - return CURLE_NOT_BUILT_IN; - } - } + *state = NTLMSTATE_TYPE2; + } else { + if *state as u32 == NTLMSTATE_LAST as u32 { + Curl_infof( + data, + b"NTLM auth restarted\0" as *const u8 as *const libc::c_char, + ); + Curl_http_auth_cleanup_ntlm(conn); + } else if *state as u32 == NTLMSTATE_TYPE3 as u32 { + Curl_infof( + data, + b"NTLM handshake rejected\0" as *const u8 as *const libc::c_char, + ); + Curl_http_auth_cleanup_ntlm(conn); + *state = NTLMSTATE_NONE; + return CURLE_REMOTE_ACCESS_DENIED; + } else if *state as u32 >= NTLMSTATE_TYPE1 as u32 { + // if *state as u32 >= NTLMSTATE_TYPE1 as i32 as u32 { + Curl_infof( + data, + b"NTLM handshake failure (internal error)\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_REMOTE_ACCESS_DENIED; + // } + } + *state = NTLMSTATE_TYPE1; + } + } + } + return result; + +} +#[no_mangle] +pub extern "C" fn Curl_output_ntlm(mut data: *mut Curl_easy, mut proxy: bool) -> CURLcode { + let mut base64: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: size_t = 0 as size_t; + let mut result: CURLcode = CURLE_OK; + let mut ntlmmsg: bufref = bufref { + dtor: None, + ptr: 0 as *const u8, + len: 0, + #[cfg(CURLDEBUG)] + signature: 0, + }; + let mut allocuserpwd: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut userp: *const libc::c_char = 0 as *const libc::c_char; + let mut passwdp: *const libc::c_char = 0 as *const libc::c_char; + let mut service: *const libc::c_char = 0 as *const libc::c_char; + let mut hostname: *const libc::c_char = 0 as *const libc::c_char; + let mut ntlm: *mut ntlmdata = 0 as *mut ntlmdata; + let mut state: *mut curlntlm = 0 as *mut curlntlm; + let mut authp: *mut auth = 0 as *mut auth; + let mut conn: *mut connectdata = unsafe {(*data).conn}; + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !conn.is_null() { + } else { + __assert_fail( + b"conn\0" as *const u8 as *const libc::c_char, + b"http_ntlm.c\0" as *const u8 as *const libc::c_char, + 150, + (*::std::mem::transmute::<&[u8; 53], &[libc::c_char; 53]>( + b"CURLcode Curl_output_ntlm(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), + ); + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !data.is_null() { + } else { + __assert_fail( + b"data\0" as *const u8 as *const libc::c_char, + b"http_ntlm.c\0" as *const u8 as *const libc::c_char, + 151, + (*::std::mem::transmute::<&[u8; 53], &[libc::c_char; 53]>( + b"CURLcode Curl_output_ntlm(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), + ); } + } + if proxy { + unsafe { + match () { + #[cfg(not(CURL_DISABLE_PROXY))] + _ => { + allocuserpwd = &mut (*data).state.aptr.proxyuserpwd; + userp = (*data).state.aptr.proxyuser; + passwdp = (*data).state.aptr.proxypasswd; + service = if !((*data).set.str_0[STRING_PROXY_SERVICE_NAME as usize]).is_null() + { + (*data).set.str_0[STRING_PROXY_SERVICE_NAME as usize] as *const libc::c_char + } else { + b"HTTP\0" as *const u8 as *const libc::c_char + }; + hostname = (*conn).http_proxy.host.name; + ntlm = &mut (*conn).proxyntlm; + state = &mut (*conn).proxy_ntlm_state; + authp = &mut (*data).state.authproxy; + } + #[cfg(CURL_DISABLE_PROXY)] + _ => { + return CURLE_NOT_BUILT_IN; + } + } + } } else { - unsafe{ - allocuserpwd = &mut (*data).state.aptr.userpwd; - userp = (*data).state.aptr.user; - passwdp = (*data).state.aptr.passwd; - service = if !((*data).set.str_0[STRING_SERVICE_NAME as usize]).is_null() { - (*data).set.str_0[STRING_SERVICE_NAME as usize] as *const libc::c_char - } else { - b"HTTP\0" as *const u8 as *const libc::c_char - }; - hostname = (*conn).host.name; - ntlm = &mut (*conn).ntlm; - state = &mut (*conn).http_ntlm_state; - authp = &mut (*data).state.authhost; + allocuserpwd =unsafe { &mut (*data).state.aptr.userpwd}; + userp = unsafe {(*data).state.aptr.user}; + passwdp = unsafe {(*data).state.aptr.passwd}; + service = unsafe {if !((*data).set.str_0[STRING_SERVICE_NAME as usize]).is_null() { + (*data).set.str_0[STRING_SERVICE_NAME as usize] as *const libc::c_char + } else { + b"HTTP\0" as *const u8 as *const libc::c_char + }}; + hostname = unsafe {(*conn).host.name}; + ntlm = unsafe {&mut (*conn).ntlm}; + state = unsafe {&mut (*conn).http_ntlm_state}; + authp =unsafe { &mut (*data).state.authhost}; + } + unsafe {(*authp).set_done(0 as bit);} + if userp.is_null() { + userp = b"\0" as *const u8 as *const libc::c_char; + } + if passwdp.is_null() { + passwdp = b"\0" as *const u8 as *const libc::c_char; + } + unsafe { Curl_bufref_init(&mut ntlmmsg);} + let mut current_block_61: u64; + unsafe { + match *state as u32 { + 2 => { + /* We already received the type-2 message, create a type-3 message */ + result = + Curl_auth_create_ntlm_type3_message(data, userp, passwdp, ntlm, &mut ntlmmsg); + if result as u64 == 0 && Curl_bufref_len(&mut ntlmmsg) != 0 { + result = Curl_base64_encode( + data, + Curl_bufref_ptr(&mut ntlmmsg) as *const libc::c_char, + Curl_bufref_len(&mut ntlmmsg), + &mut base64, + &mut len, + ); + if result as u64 == 0 { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + *allocuserpwd as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + *allocuserpwd as *mut libc::c_void, + 234, + b"http_ntlm.c\0" as *const u8 as *const libc::c_char, + ); + *allocuserpwd = curl_maprintf( + b"%sAuthorization: NTLM %s\r\n\0" as *const u8 as *const libc::c_char, + if proxy as i32 != 0 { + b"Proxy-\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + base64, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(base64 as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + base64 as *mut libc::c_void, + 238, + b"http_ntlm.c\0" as *const u8 as *const libc::c_char, + ); + if (*allocuserpwd).is_null() { + result = CURLE_OUT_OF_MEMORY; + } else { + *state = NTLMSTATE_TYPE3; /* we send a type-3 */ + (*authp).set_done(1 as bit); + } + } + } + current_block_61 = 15669289850109000831; + } + 3 => { + /* connection is already authenticated, + * don't send a header in future requests */ + *state = NTLMSTATE_LAST; + current_block_61 = 660359442149512078; + } + /* FALLTHROUGH */ + 4 => { + current_block_61 = 660359442149512078; + } + 1 | _ => { + /* for the weird cases we (re)start here */ + /* Create a type-1 message */ + result = Curl_auth_create_ntlm_type1_message( + data, + userp, + passwdp, + service, + hostname, + ntlm, + &mut ntlmmsg, + ); + if result as u64 == 0 { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if Curl_bufref_len(&mut ntlmmsg) != 0 as u64 { + } else { + __assert_fail( + b"Curl_bufref_len(&ntlmmsg) != 0\0" as *const u8 as *const libc::c_char, + b"http_ntlm.c\0" as *const u8 as *const libc::c_char, + 209, + (*::std::mem::transmute::<&[u8; 53], &[libc::c_char; 53]>( + b"CURLcode Curl_output_ntlm(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), + ); + } + result = Curl_base64_encode( + data, + Curl_bufref_ptr(&mut ntlmmsg) as *const libc::c_char, + Curl_bufref_len(&mut ntlmmsg), + &mut base64, + &mut len, + ); + if result as u64 == 0 { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + *allocuserpwd as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + *allocuserpwd as *mut libc::c_void, + 214, + b"http_ntlm.c\0" as *const u8 as *const libc::c_char, + ); + *allocuserpwd = curl_maprintf( + b"%sAuthorization: NTLM %s\r\n\0" as *const u8 as *const libc::c_char, + if proxy as i32 != 0 { + b"Proxy-\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + base64, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(base64 as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + base64 as *mut libc::c_void, + 218, + b"http_ntlm.c\0" as *const u8 as *const libc::c_char, + ); + if (*allocuserpwd).is_null() { + result = CURLE_OUT_OF_MEMORY; + } + } + } + current_block_61 = 15669289850109000831; + } + } + match current_block_61 { + 660359442149512078 => { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(*allocuserpwd as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + *allocuserpwd as *mut libc::c_void, + 255, + b"http_ntlm.c\0" as *const u8 as *const libc::c_char, + ); + *allocuserpwd = 0 as *mut libc::c_char; + (*authp).set_done(1 as bit); + } + _ => {} } - } - unsafe{ - (*authp).set_done(0 as bit);} - if userp.is_null() { - userp = b"\0" as *const u8 as *const libc::c_char; - } - if passwdp.is_null() { - passwdp = b"\0" as *const u8 as *const libc::c_char; - } - unsafe{Curl_bufref_init(&mut ntlmmsg);} - let mut current_block_61: u64; - match unsafe{*state as u32 }{ - 2 => { - - /* We already received the type-2 message, create a type-3 message */ - result =unsafe{ Curl_auth_create_ntlm_type3_message(data, userp, passwdp, ntlm, &mut ntlmmsg)}; - if result as u64 == 0 && unsafe{Curl_bufref_len(&mut ntlmmsg)} != 0 { - result = unsafe{Curl_base64_encode( - data, - Curl_bufref_ptr(&mut ntlmmsg) as *const libc::c_char, - Curl_bufref_len(&mut ntlmmsg), - &mut base64, - &mut len, - )}; - if result as u64 == 0 { - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")( - *allocuserpwd as *mut libc::c_void, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - *allocuserpwd as *mut libc::c_void, - 234, - b"http_ntlm.c\0" as *const u8 as *const libc::c_char, - ); - *allocuserpwd = curl_maprintf( - b"%sAuthorization: NTLM %s\r\n\0" as *const u8 as *const libc::c_char, - if proxy as i32 != 0 { - b"Proxy-\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - base64, - );} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(base64 as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - base64 as *mut libc::c_void, - 238, - b"http_ntlm.c\0" as *const u8 as *const libc::c_char, - ); - if (*allocuserpwd).is_null() { - result = CURLE_OUT_OF_MEMORY; - } else { - *state = NTLMSTATE_TYPE3; /* we send a type-3 */ - (*authp).set_done(1 as bit); - }} - } - } - current_block_61 = 15669289850109000831; - } - 3 => { - /* connection is already authenticated, - * don't send a header in future requests */ - unsafe{ *state = NTLMSTATE_LAST; - current_block_61 = 660359442149512078;} - } - /* FALLTHROUGH */ - 4 => { - current_block_61 = 660359442149512078; - } - 1 | _ => { - /* for the weird cases we (re)start here */ - /* Create a type-1 message */ - result =unsafe{ Curl_auth_create_ntlm_type1_message( - data, - userp, - passwdp, - service, - hostname, - ntlm, - &mut ntlmmsg, - )}; - if result as u64 == 0 { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{Curl_bufref_len(&mut ntlmmsg) }!= 0 as u64 { - } else { - unsafe{ - __assert_fail( - b"Curl_bufref_len(&ntlmmsg) != 0\0" as *const u8 as *const libc::c_char, - b"http_ntlm.c\0" as *const u8 as *const libc::c_char, - 209, - (*::std::mem::transmute::<&[u8; 53], &[libc::c_char; 53]>( - b"CURLcode Curl_output_ntlm(struct Curl_easy *, _Bool)\0", - )) - .as_ptr(), - );} - } - result = unsafe{Curl_base64_encode( - data, - Curl_bufref_ptr(&mut ntlmmsg) as *const libc::c_char, - Curl_bufref_len(&mut ntlmmsg), - &mut base64, - &mut len, - )}; - if result as u64 == 0 { - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")( - *allocuserpwd as *mut libc::c_void, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - *allocuserpwd as *mut libc::c_void, - 214, - b"http_ntlm.c\0" as *const u8 as *const libc::c_char, - ); - *allocuserpwd = curl_maprintf( - b"%sAuthorization: NTLM %s\r\n\0" as *const u8 as *const libc::c_char, - if proxy as i32 != 0 { - b"Proxy-\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - base64, - );} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(base64 as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - base64 as *mut libc::c_void, - 218, - b"http_ntlm.c\0" as *const u8 as *const libc::c_char, - ); - if (*allocuserpwd).is_null() { - result = CURLE_OUT_OF_MEMORY; - }} - } - } - current_block_61 = 15669289850109000831; - } - + Curl_bufref_free(&mut ntlmmsg);} + return result; + +} +#[no_mangle] +pub extern "C" fn Curl_http_auth_cleanup_ntlm(mut conn: *mut connectdata) { + unsafe { + Curl_auth_cleanup_ntlm(&mut (*conn).ntlm); + Curl_auth_cleanup_ntlm(&mut (*conn).proxyntlm); + #[cfg(NTLM_WB_ENABLED)] + Curl_http_auth_cleanup_ntlm_wb(conn); } - match current_block_61 { - 660359442149512078 => { - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(*allocuserpwd as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - *allocuserpwd as *mut libc::c_void, - 255, - b"http_ntlm.c\0" as *const u8 as *const libc::c_char, - ); - *allocuserpwd = 0 as *mut libc::c_char; - (*authp).set_done(1 as bit);} - } - _ => {} - } - unsafe{Curl_bufref_free(&mut ntlmmsg);} - return result; - - } - #[no_mangle] - pub extern "C" fn Curl_http_auth_cleanup_ntlm(mut conn: *mut connectdata) { - unsafe{ - Curl_auth_cleanup_ntlm(&mut (*conn).ntlm); - Curl_auth_cleanup_ntlm(&mut (*conn).proxyntlm); - #[cfg(NTLM_WB_ENABLED)] - Curl_http_auth_cleanup_ntlm_wb(conn); - } - } - /* !CURL_DISABLE_HTTP && USE_NTLM */ \ No newline at end of file +} +/* !CURL_DISABLE_HTTP && USE_NTLM */ diff --git a/rust/rust_project/src/http_proxy.rs b/rust/rust_project/src/http_proxy.rs index 25c3827..28b4e28 100755 --- a/rust/rust_project/src/http_proxy.rs +++ b/rust/rust_project/src/http_proxy.rs @@ -27,304 +27,292 @@ * proxy_ssl_connected connection bit when complete. Can be * called multiple times. */ - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - extern "C" fn https_proxy_connect( - mut data: *mut Curl_easy, - mut sockindex: i32, - ) -> CURLcode { - - if cfg!(USE_SSL) { - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut result: CURLcode = CURLE_OK; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*conn).http_proxy.proxytype as u32 - == CURLPROXY_HTTPS as u32 - { - } else { - __assert_fail( - b"conn->http_proxy.proxytype == CURLPROXY_HTTPS\0" as *const u8 - as *const libc::c_char, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 60 as u32, - (*::std::mem::transmute::<&[u8; 54], &[libc::c_char; 54]>( - b"CURLcode https_proxy_connect(struct Curl_easy *, int)\0", - )) - .as_ptr(), - ); - } - if unsafe{!(*conn).bits.proxy_ssl_connected[sockindex as usize]} { - /* perform SSL initialization for this socket */ - result = unsafe{Curl_ssl_connect_nonblocking( - data, - conn, - 1 as i32 != 0, - sockindex, - &mut *((*conn).bits.proxy_ssl_connected) - .as_mut_ptr() - .offset(sockindex as isize), - )}; - if result as u64 != 0 { - /* a failed connection is marked for closure to prevent (bad) re-use or - similar */ - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 1 as i32, - b"TLS handshake failed\0" as *const u8 as *const libc::c_char, - ); - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - unsafe{Curl_conncontrol(conn, 1 as i32);} - } - } - return result; - } else { - return CURLE_NOT_BUILT_IN; - } - - } - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - #[no_mangle] - pub extern "C" fn Curl_proxy_connect( - mut data: *mut Curl_easy, - mut sockindex: i32, - ) -> CURLcode { - let mut conn: *mut connectdata = unsafe{(*data).conn}; - if unsafe{(*conn).http_proxy.proxytype as u32} - == CURLPROXY_HTTPS as u32 - { - let result: CURLcode = https_proxy_connect(data, sockindex); - if result as u64 != 0 { - return result; - } - if unsafe{!(*conn).bits.proxy_ssl_connected[sockindex as usize]} { - return result; /* wait for HTTPS proxy SSL initialization to complete */ - } - } - if unsafe{ ((*conn).bits).tunnel_proxy() as i32} != 0 - && unsafe{((*conn).bits).httpproxy() as i32 }!= 0 - { - if cfg!(not(CURL_DISABLE_PROXY)) { - /* for [protocol] tunneled through HTTP proxy */ - let mut hostname: *const libc::c_char = 0 as *const libc::c_char; - let mut remote_port: i32 = 0; - let mut result_0: CURLcode = CURLE_OK; - /* We want "seamless" operations through HTTP proxy tunnel */ - - /* for the secondary socket (FTP), use the "connect to host" - * but ignore the "connect to port" (use the secondary port) - */ - if unsafe{((*conn).bits).conn_to_host() }!= 0 { - hostname = unsafe{(*conn).conn_to_host.name}; - } else if sockindex == 1 as i32 { - hostname = unsafe{(*conn).secondaryhostname}; - } else { - hostname = unsafe{(*conn).host.name}; - } - if sockindex == 1 as i32 { - remote_port = unsafe{(*conn).secondary_port as i32}; - } else if unsafe{((*conn).bits).conn_to_port() }!= 0 { - remote_port = unsafe{(*conn).conn_to_port}; - } else { - remote_port = unsafe{(*conn).remote_port}; - } - result_0 = Curl_proxyCONNECT(data, sockindex, hostname, remote_port); - if CURLE_OK as u32 != result_0 as u32 { - return result_0; - } - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - );} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - 120 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh0 = (*data).state.aptr.proxyuserpwd; - (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char;} - } else { - return CURLE_NOT_BUILT_IN; - } - } - /* no HTTP tunnel proxy, just return */ - return CURLE_OK; - - } + #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] + extern "C" fn https_proxy_connect(mut data: *mut Curl_easy, mut sockindex: i32) -> CURLcode { + if cfg!(USE_SSL) { + let mut conn: *mut connectdata = unsafe {(*data).conn}; + let mut result: CURLcode = CURLE_OK; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if unsafe {(*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32} { + } else { + unsafe { + __assert_fail( + b"conn->http_proxy.proxytype == CURLPROXY_HTTPS\0" as *const u8 + as *const libc::c_char, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + 60 as u32, + (*::std::mem::transmute::<&[u8; 54], &[libc::c_char; 54]>( + b"CURLcode https_proxy_connect(struct Curl_easy *, int)\0", + )) + .as_ptr(), + );} + } + if unsafe {!(*conn).bits.proxy_ssl_connected[sockindex as usize]} { + /* perform SSL initialization for this socket */ + result =unsafe { Curl_ssl_connect_nonblocking( + data, + conn, + 1 as i32 != 0, + sockindex, + &mut *((*conn).bits.proxy_ssl_connected) + .as_mut_ptr() + .offset(sockindex as isize), + )}; + if result as u64 != 0 { + /* a failed connection is marked for closure to prevent (bad) re-use or + similar */ + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + unsafe {Curl_conncontrol( + conn, + 1 as i32, + b"TLS handshake failed\0" as *const u8 as *const libc::c_char, + );} + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + unsafe {Curl_conncontrol(conn, 1 as i32);} + } + } + return result; + } else { + return CURLE_NOT_BUILT_IN; + } + + } + + #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] + #[no_mangle] + pub extern "C" fn Curl_proxy_connect(mut data: *mut Curl_easy, mut sockindex: i32) -> CURLcode { + let mut conn: *mut connectdata = unsafe {(*data).conn}; + if unsafe {(*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32} { + let result: CURLcode = https_proxy_connect(data, sockindex); + if result as u64 != 0 { + return result; + } + if unsafe {!(*conn).bits.proxy_ssl_connected[sockindex as usize]} { + return result; /* wait for HTTPS proxy SSL initialization to complete */ + } + } + if unsafe {((*conn).bits).tunnel_proxy() as i32 != 0 && ((*conn).bits).httpproxy() as i32 != 0} { + if cfg!(not(CURL_DISABLE_PROXY)) { + /* for [protocol] tunneled through HTTP proxy */ + let mut hostname: *const libc::c_char = 0 as *const libc::c_char; + let mut remote_port: i32 = 0; + let mut result_0: CURLcode = CURLE_OK; + /* We want "seamless" operations through HTTP proxy tunnel */ + + /* for the secondary socket (FTP), use the "connect to host" + * but ignore the "connect to port" (use the secondary port) + */ + if unsafe {((*conn).bits).conn_to_host() != 0} { + hostname =unsafe { (*conn).conn_to_host.name}; + } else if sockindex == 1 as i32 { + hostname = unsafe {(*conn).secondaryhostname}; + } else { + hostname = unsafe {(*conn).host.name}; + } + if sockindex == 1 as i32 { + remote_port = unsafe {(*conn).secondary_port as i32}; + } else if unsafe {((*conn).bits).conn_to_port() != 0 }{ + remote_port = unsafe {(*conn).conn_to_port}; + } else { + remote_port = unsafe {(*conn).remote_port}; + } + result_0 = Curl_proxyCONNECT(data, sockindex, hostname, remote_port); + if CURLE_OK as u32 != result_0 as u32 { + return result_0; + } + #[cfg(not(CURLDEBUG))] + unsafe {Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + );} + #[cfg(CURLDEBUG)] + unsafe {curl_dbg_free( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + 120 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + );} + // let ref mut fresh0 = (*data).state.aptr.proxyuserpwd; + unsafe {(*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char;} + } else { + return CURLE_NOT_BUILT_IN; + } + } + /* no HTTP tunnel proxy, just return */ + return CURLE_OK; + + } + #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] #[no_mangle] pub extern "C" fn Curl_connect_complete(mut conn: *mut connectdata) -> bool { - unsafe{ - return ((*conn).connect_state).is_null() - || (*(*conn).connect_state).tunnel_state as u32 - >= TUNNEL_COMPLETE as u32; + unsafe { + return ((*conn).connect_state).is_null() + || (*(*conn).connect_state).tunnel_state as u32 >= TUNNEL_COMPLETE as u32; } } #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] #[no_mangle] pub extern "C" fn Curl_connect_ongoing(mut conn: *mut connectdata) -> bool { - unsafe{ - return !((*conn).connect_state).is_null() - && (*(*conn).connect_state).tunnel_state as u32 - <= TUNNEL_COMPLETE as u32; + unsafe { + return !((*conn).connect_state).is_null() + && (*(*conn).connect_state).tunnel_state as u32 <= TUNNEL_COMPLETE as u32; } } /* when we've sent a CONNECT to a proxy, we should rather either wait for the - socket to become readable to be able to get the response headers or if - we're still sending the request, wait for write. */ + socket to become readable to be able to get the response headers or if + we're still sending the request, wait for write. */ + #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] #[no_mangle] pub extern "C" fn Curl_connect_getsock(mut conn: *mut connectdata) -> i32 { - let mut http: *mut HTTP = 0 as *mut HTTP; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !conn.is_null() { - } else { - unsafe{ - __assert_fail( - b"conn\0" as *const u8 as *const libc::c_char, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 147 as u32, - (*::std::mem::transmute::<&[u8; 47], &[libc::c_char; 47]>( - b"int Curl_connect_getsock(struct connectdata *)\0", - )) - .as_ptr(), - );} - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{ !((*conn).connect_state).is_null()} { - } else { - unsafe{ - __assert_fail( - b"conn->connect_state\0" as *const u8 as *const libc::c_char, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 148 as u32, - (*::std::mem::transmute::<&[u8; 47], &[libc::c_char; 47]>( - b"int Curl_connect_getsock(struct connectdata *)\0", - )) - .as_ptr(), - );} - } - http = unsafe{&mut (*(*conn).connect_state).http_proxy}; - if unsafe{(*http).sending as u32} == HTTPSEND_REQUEST as u32 { - return (1 as i32) << 16 as i32 + 0 as i32; - } - return (1 as i32) << 0 as i32; - } - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - extern "C" fn connect_init(mut data: *mut Curl_easy, mut reinit: bool) -> CURLcode { - let mut s: *mut http_connect_state = 0 as *mut http_connect_state; - let mut conn: *mut connectdata = unsafe{(*data).conn}; - if !reinit { - let mut result: CURLcode = CURLE_OK; + let mut http: *mut HTTP = 0 as *mut HTTP; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{((*conn).connect_state).is_null()}{ - } else {unsafe{ - __assert_fail( - b"!conn->connect_state\0" as *const u8 as *const libc::c_char, + if !conn.is_null() { + } else { + unsafe {__assert_fail( + b"conn\0" as *const u8 as *const libc::c_char, b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 163 as u32, - (*::std::mem::transmute::<&[u8; 49], &[libc::c_char; 49]>( - b"CURLcode connect_init(struct Curl_easy *, _Bool)\0", + 147 as u32, + (*::std::mem::transmute::<&[u8; 47], &[libc::c_char; 47]>( + b"int Curl_connect_getsock(struct connectdata *)\0", )) .as_ptr(), );} } - /* we might need the upload buffer for streaming a partial request */ - result = unsafe{Curl_get_upload_buffer(data)}; - if result as u64 != 0 { - return result; - } - #[cfg(not(CURLDEBUG))] - let news: *mut http_connect_state = unsafe{Curl_ccalloc.expect("non-null function pointer")( - 1 as size_t, - ::std::mem::size_of::() as u64, - ) as *mut http_connect_state}; - #[cfg(CURLDEBUG)] - let news: *mut http_connect_state =unsafe{ curl_dbg_calloc( - 1 as size_t, - ::std::mem::size_of::() as u64, - 169 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ) as *mut http_connect_state}; - s = news; - if s.is_null() { - return CURLE_OUT_OF_MEMORY; - } - unsafe{ - Curl_infof( - data, - b"allocate connect buffer!\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh1 = (*conn).connect_state; - (*conn).connect_state = s; - Curl_dyn_init(&mut (*s).rcvbuf, 16384 as size_t); - // let ref mut fresh2 = (*s).prot_save; - (*s).prot_save = (*data).req.p.http; - // let ref mut fresh3 = (*data).req.p.http; - (*data).req.p.http = &mut (*s).http_proxy;} - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - unsafe{Curl_conncontrol(conn, 0 as i32);} - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - unsafe{Curl_conncontrol( - conn, - 0 as i32, - b"HTTP proxy CONNECT\0" as *const u8 as *const libc::c_char, - );} - /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the - * member conn->proto.http; we want [protocol] through HTTP and we have - * to change the member temporarily for connecting to the HTTP - * proxy. After Curl_proxyCONNECT we have to set back the member to the - * original pointer - * - * This function might be called several times in the multi interface case - * if the proxy's CONNECT response is not instant. - */ - } else { #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{!((*conn).connect_state).is_null()} { + if unsafe {!((*conn).connect_state).is_null()} { } else { - unsafe{ - __assert_fail( + unsafe {__assert_fail( b"conn->connect_state\0" as *const u8 as *const libc::c_char, b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 190 as u32, - (*::std::mem::transmute::<&[u8; 49], &[libc::c_char; 49]>( - b"CURLcode connect_init(struct Curl_easy *, _Bool)\0", + 148 as u32, + (*::std::mem::transmute::<&[u8; 47], &[libc::c_char; 47]>( + b"int Curl_connect_getsock(struct connectdata *)\0", )) .as_ptr(), );} } - s = unsafe{(*conn).connect_state}; - unsafe{ Curl_dyn_reset(&mut (*s).rcvbuf);} - } - unsafe{ - (*s).tunnel_state = TUNNEL_INIT; - (*s).keepon = KEEPON_CONNECT; - (*s).cl = 0 as curl_off_t; - (*s).set_close_connection(0 as bit); + http =unsafe { &mut (*(*conn).connect_state).http_proxy}; + if unsafe {(*http).sending as u32 == HTTPSEND_REQUEST as u32} { + return (1 as i32) << 16 as i32 + 0 as i32; + } + return (1 as i32) << 0 as i32; + + } + + + #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] + extern "C" fn connect_init(mut data: *mut Curl_easy, mut reinit: bool) -> CURLcode { + unsafe { + let mut s: *mut http_connect_state = 0 as *mut http_connect_state; + let mut conn: *mut connectdata = (*data).conn; + if !reinit { + let mut result: CURLcode = CURLE_OK; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ((*conn).connect_state).is_null() { + } else { + __assert_fail( + b"!conn->connect_state\0" as *const u8 as *const libc::c_char, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + 163 as u32, + (*::std::mem::transmute::<&[u8; 49], &[libc::c_char; 49]>( + b"CURLcode connect_init(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), + ); + } + /* we might need the upload buffer for streaming a partial request */ + result = Curl_get_upload_buffer(data); + if result as u64 != 0 { + return result; + } + #[cfg(not(CURLDEBUG))] + let news: *mut http_connect_state = Curl_ccalloc.expect("non-null function pointer")( + 1 as size_t, + ::std::mem::size_of::() as u64, + ) as *mut http_connect_state; + #[cfg(CURLDEBUG)] + let news: *mut http_connect_state = curl_dbg_calloc( + 1 as size_t, + ::std::mem::size_of::() as u64, + 169 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ) as *mut http_connect_state; + s = news; + if s.is_null() { + return CURLE_OUT_OF_MEMORY; + } + Curl_infof( + data, + b"allocate connect buffer!\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh1 = (*conn).connect_state; + (*conn).connect_state = s; + Curl_dyn_init(&mut (*s).rcvbuf, 16384 as size_t); + // let ref mut fresh2 = (*s).prot_save; + (*s).prot_save = (*data).req.p.http; + // let ref mut fresh3 = (*data).req.p.http; + (*data).req.p.http = &mut (*s).http_proxy; + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 0 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 0 as i32, + b"HTTP proxy CONNECT\0" as *const u8 as *const libc::c_char, + ); + /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the + * member conn->proto.http; we want [protocol] through HTTP and we have + * to change the member temporarily for connecting to the HTTP + * proxy. After Curl_proxyCONNECT we have to set back the member to the + * original pointer + * + * This function might be called several times in the multi interface case + * if the proxy's CONNECT response is not instant. + */ + } else { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !((*conn).connect_state).is_null() { + } else { + __assert_fail( + b"conn->connect_state\0" as *const u8 as *const libc::c_char, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + 190 as u32, + (*::std::mem::transmute::<&[u8; 49], &[libc::c_char; 49]>( + b"CURLcode connect_init(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), + ); + } + s = (*conn).connect_state; + Curl_dyn_reset(&mut (*s).rcvbuf); + } + (*s).tunnel_state = TUNNEL_INIT; + (*s).keepon = KEEPON_CONNECT; + (*s).cl = 0 as curl_off_t; + (*s).set_close_connection(0 as bit); + return CURLE_OK; } - return CURLE_OK; - } #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] extern "C" fn connect_done(mut data: *mut Curl_easy) { - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut s: *mut http_connect_state = unsafe{(*conn).connect_state}; - if unsafe{(*s).tunnel_state as u32} != TUNNEL_EXIT as u32 { - unsafe{ - (*s).tunnel_state = TUNNEL_EXIT; - Curl_dyn_free(&mut (*s).rcvbuf); - Curl_dyn_free(&mut (*s).req); - // let ref mut fresh4 = (*data).req.p.http; - (*data).req.p.http = (*s).prot_save; - // let ref mut fresh5 = (*s).prot_save; - /* retore the protocol pointer */ - (*s).prot_save = 0 as *mut HTTP; - Curl_infof( - data, - b"CONNECT phase completed!\0" as *const u8 as *const libc::c_char, - );} + unsafe { + let mut conn: *mut connectdata = (*data).conn; + let mut s: *mut http_connect_state = (*conn).connect_state; + if (*s).tunnel_state as u32 != TUNNEL_EXIT as u32 { + (*s).tunnel_state = TUNNEL_EXIT; + Curl_dyn_free(&mut (*s).rcvbuf); + Curl_dyn_free(&mut (*s).req); + // let ref mut fresh4 = (*data).req.p.http; + (*data).req.p.http = (*s).prot_save; + // let ref mut fresh5 = (*s).prot_save; + /* retore the protocol pointer */ + (*s).prot_save = 0 as *mut HTTP; + Curl_infof( + data, + b"CONNECT phase completed!\0" as *const u8 as *const libc::c_char, + ); + } } } #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] @@ -336,735 +324,730 @@ mut connecthostp: *mut *mut libc::c_char, mut hostp: *mut *mut libc::c_char, ) -> CURLcode { - let mut hostheader: *mut libc::c_char = 0 as *mut libc::c_char; /* for CONNECT */ - let mut host: *mut libc::c_char = 0 as *mut libc::c_char; /* Host: */ - let mut ipv6_ip: bool = unsafe{((*conn).bits).ipv6_ip() }!= 0; - /* the hostname may be different */ - if hostname != unsafe{(*conn).host.name as *const libc::c_char }{ - ipv6_ip = unsafe{!(strchr(hostname, ':' as i32)).is_null()}; - } - /* host:port with IPv6 support */ - hostheader = unsafe{curl_maprintf( - b"%s%s%s:%d\0" as *const u8 as *const libc::c_char, - if ipv6_ip as i32 != 0 { - b"[\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - hostname, - if ipv6_ip as i32 != 0 { - b"]\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - remote_port, - )}; - if hostheader.is_null() { - return CURLE_OUT_OF_MEMORY; - } - if unsafe{(Curl_checkProxyheaders(data, conn, b"Host\0" as *const u8 as *const libc::c_char)).is_null()} - { - host = unsafe{curl_maprintf( - b"Host: %s\r\n\0" as *const u8 as *const libc::c_char, - hostheader, - )}; - if host.is_null() { - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - hostheader as *mut libc::c_void, - 240 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - );} + let mut hostheader: *mut libc::c_char = unsafe {0 as *mut libc::c_char}; /* for CONNECT */ + let mut host: *mut libc::c_char =unsafe { 0 as *mut libc::c_char}; /* Host: */ + let mut ipv6_ip: bool = unsafe {((*conn).bits).ipv6_ip() != 0}; + /* the hostname may be different */ + unsafe { + if hostname != (*conn).host.name as *const libc::c_char { + ipv6_ip = !(strchr(hostname, ':' as i32)).is_null(); + } + /* host:port with IPv6 support */ + hostheader = curl_maprintf( + b"%s%s%s:%d\0" as *const u8 as *const libc::c_char, + if ipv6_ip as i32 != 0 { + b"[\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + hostname, + if ipv6_ip as i32 != 0 { + b"]\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + remote_port, + ); + if hostheader.is_null() { return CURLE_OUT_OF_MEMORY; } + if (Curl_checkProxyheaders(data, conn, b"Host\0" as *const u8 as *const libc::c_char)) + .is_null() + { + host = curl_maprintf( + b"Host: %s\r\n\0" as *const u8 as *const libc::c_char, + hostheader, + ); + if host.is_null() { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + hostheader as *mut libc::c_void, + 240 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OUT_OF_MEMORY; + } + } + *connecthostp = hostheader; + *hostp = host; + return CURLE_OK; } - unsafe{ - *connecthostp = hostheader; - *hostp = host;} - return CURLE_OK; } -// #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP), not(USE_HYPER)))] -#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP), not(USE_HYPER)))] + #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP), not(USE_HYPER)))] extern "C" fn CONNECT( mut data: *mut Curl_easy, mut sockindex: i32, mut hostname: *const libc::c_char, mut remote_port: i32, ) -> CURLcode { - let mut subversion: i32 = 0 as i32; - let mut k: *mut SingleRequest = unsafe{&mut (*data).req}; - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut tunnelsocket: curl_socket_t = unsafe{(*conn).sock[sockindex as usize]}; - let mut s: *mut http_connect_state =unsafe{ (*conn).connect_state}; - let mut http: *mut HTTP =unsafe{ (*data).req.p.http}; - let mut linep: *mut libc::c_char = 0 as *mut libc::c_char; - let mut perline: size_t = 0; - if Curl_connect_complete(conn) { - return CURLE_OK; /* CONNECT is already completed */ - } - // let ref mut fresh6 = (*conn).bits; - unsafe{((*conn).bits).set_proxy_connect_closed(0 as bit)}; - loop { - let mut check: timediff_t = 0; - if TUNNEL_INIT as u32 == unsafe{(*s).tunnel_state as u32} { - /* BEGIN CONNECT PHASE */ - let mut req: *mut dynbuf = unsafe{&mut (*s).req}; - let mut hostheader: *mut libc::c_char = 0 as *mut libc::c_char; - let mut host: *mut libc::c_char = 0 as *mut libc::c_char; - unsafe{Curl_infof( - data, - b"Establish HTTP proxy tunnel to %s:%d\0" as *const u8 as *const libc::c_char, - hostname, - remote_port, - );} - /* This only happens if we've looped here due to authentication - reasons, and we don't really use the newly cloned URL here - then. Just free() it. */ - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")((*data).req.newurl as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - (*data).req.newurl as *mut libc::c_void, - 287 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - );} - // let ref mut fresh7 = (*data).req.newurl; - unsafe{(*data).req.newurl = 0 as *mut libc::c_char; - /* initialize send-buffer */ - Curl_dyn_init(req, (1024 as i32 * 1024 as i32) as size_t)}; - /* Setup the proxy-authorization header, if any */ - result = CONNECT_host( - data, - conn, - hostname, - remote_port, - &mut hostheader, - &mut host, - ); - if result as u64 != 0 { - return result; - } - result = unsafe{Curl_http_output_auth( - data, - conn, - b"CONNECT\0" as *const u8 as *const libc::c_char, - HTTPREQ_GET, - hostheader, - 1 as i32 != 0, - )}; - if result as u64 == 0 { - let mut httpv: *const libc::c_char = if unsafe{ (*conn).http_proxy.proxytype as u32} - == CURLPROXY_HTTP_1_0 as u32 - { - b"1.0\0" as *const u8 as *const libc::c_char - } else { - b"1.1\0" as *const u8 as *const libc::c_char - }; - result = unsafe{Curl_dyn_addf( - req, - b"CONNECT %s HTTP/%s\r\n%s%s\0" as *const u8 as *const libc::c_char, - hostheader, /* Host: */ - httpv,/* Proxy-Authorization */ - if !host.is_null() { - host as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !((*data).state.aptr.proxyuserpwd).is_null() { - (*data).state.aptr.proxyuserpwd as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - )}; - if result as u64 == 0 - && unsafe{(Curl_checkProxyheaders( - data, - conn, - b"User-Agent\0" as *const u8 as *const libc::c_char, - )) - .is_null()} - && unsafe{!((*data).set.str_0[STRING_USERAGENT as usize]).is_null()} - { - result = unsafe{Curl_dyn_addf( - req, - b"User-Agent: %s\r\n\0" as *const u8 as *const libc::c_char, - (*data).set.str_0[STRING_USERAGENT as usize], - )}; - } - if result as u64 == 0 - && unsafe{(Curl_checkProxyheaders( - data, - conn, - b"Proxy-Connection\0" as *const u8 as *const libc::c_char, - )) - .is_null()} - { /* CRLF terminate the request */ - result = unsafe{Curl_dyn_add( - req, - b"Proxy-Connection: Keep-Alive\r\n\0" as *const u8 as *const libc::c_char, - )}; - } - if result as u64 == 0 { - /* Send the connect request to the proxy */ - result = unsafe{Curl_add_custom_headers(data, 1 as i32 != 0, req)}; - } - if result as u64 == 0 { - result = unsafe{Curl_dyn_add(req, b"\r\n\0" as *const u8 as *const libc::c_char)}; - } - if result as u64 == 0 { - result = unsafe{Curl_buffer_send( - req, - data, - &mut (*data).info.request_size, - 0 as curl_off_t, - sockindex, - )}; - } - if result as u64 != 0 { - unsafe{Curl_failf( - data, - b"Failed sending CONNECT to proxy\0" as *const u8 as *const libc::c_char, - );} - } - } - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(host as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - host as *mut libc::c_void, - 340 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - hostheader as *mut libc::c_void, - 341 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - );} - if result as u64 != 0 { - return result; - } - unsafe{(*s).tunnel_state = TUNNEL_CONNECT;}/* END CONNECT PHASE */ - } - check = unsafe{Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0)}; - if check <= 0 as i64 { - unsafe{ Curl_failf( - data, - b"Proxy CONNECT aborted due to timeout\0" as *const u8 as *const libc::c_char, - );} - return CURLE_OPERATION_TIMEDOUT; - } - if unsafe{!Curl_conn_data_pending(conn, sockindex)} && unsafe{(*http).sending as u64 }== 0 { - return CURLE_OK; /* return so we'll be called again polling-style */ + let mut subversion: i32 = 0 as i32; + let mut k: *mut SingleRequest = unsafe {&mut (*data).req}; + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata =unsafe { (*data).conn}; + let mut tunnelsocket: curl_socket_t = unsafe {(*conn).sock[sockindex as usize]}; + let mut s: *mut http_connect_state =unsafe { (*conn).connect_state}; + let mut http: *mut HTTP =unsafe { (*data).req.p.http}; + let mut linep: *mut libc::c_char = 0 as *mut libc::c_char; + let mut perline: size_t = 0; + unsafe { + if Curl_connect_complete(conn) { + return CURLE_OK; /* CONNECT is already completed */ } - /* at this point, the tunnel_connecting phase is over. */ - if unsafe{(*http).sending as u32 }== HTTPSEND_REQUEST as u32 { - if unsafe{(*s).nsend} == 0 { - let mut fillcount: size_t = 0; - // let ref mut fresh8 = (*k).upload_fromhere; - unsafe{(*k).upload_fromhere = (*data).state.ulbuf; - result = Curl_fillreadbuffer( + // let ref mut fresh6 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(0 as bit); + loop { + let mut check: timediff_t = 0; + if TUNNEL_INIT as u32 == (*s).tunnel_state as u32 { + /* BEGIN CONNECT PHASE */ + let mut req: *mut dynbuf = &mut (*s).req; + let mut hostheader: *mut libc::c_char = 0 as *mut libc::c_char; + let mut host: *mut libc::c_char = 0 as *mut libc::c_char; + Curl_infof( + data, + b"Establish HTTP proxy tunnel to %s:%d\0" as *const u8 as *const libc::c_char, + hostname, + remote_port, + ); + /* This only happens if we've looped here due to authentication + reasons, and we don't really use the newly cloned URL here + then. Just free() it. */ + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).req.newurl as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).req.newurl as *mut libc::c_void, + 287 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh7 = (*data).req.newurl; + (*data).req.newurl = 0 as *mut libc::c_char; + /* initialize send-buffer */ + Curl_dyn_init(req, (1024 as i32 * 1024 as i32) as size_t); + /* Setup the proxy-authorization header, if any */ + result = CONNECT_host( data, - (*data).set.upload_buffer_size as size_t, - &mut fillcount, - );} + conn, + hostname, + remote_port, + &mut hostheader, + &mut host, + ); if result as u64 != 0 { return result; } - unsafe{(*s).nsend = fillcount;} - } - if unsafe{(*s).nsend }!= 0 { - let mut bytes_written: ssize_t = 0; /* write to socket (send away data) */ - result = unsafe{Curl_write( + result = Curl_http_output_auth( data, - (*conn).writesockfd, /* socket to send to */ - (*k).upload_fromhere as *const libc::c_void, /* buffer pointer */ - (*s).nsend, /* buffer size */ - &mut bytes_written, /* actually sent */ - )}; + conn, + b"CONNECT\0" as *const u8 as *const libc::c_char, + HTTPREQ_GET, + hostheader, + 1 as i32 != 0, + ); if result as u64 == 0 { - /* send to debug callback! */ - result = unsafe{Curl_debug( - data, - CURLINFO_HEADER_OUT, - (*k).upload_fromhere, - bytes_written as size_t, - ) as CURLcode}; + let mut httpv: *const libc::c_char = + if (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTP_1_0 as u32 { + b"1.0\0" as *const u8 as *const libc::c_char + } else { + b"1.1\0" as *const u8 as *const libc::c_char + }; + result = Curl_dyn_addf( + req, + b"CONNECT %s HTTP/%s\r\n%s%s\0" as *const u8 as *const libc::c_char, + hostheader, /* Host: */ + httpv, /* Proxy-Authorization */ + if !host.is_null() { + host as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !((*data).state.aptr.proxyuserpwd).is_null() { + (*data).state.aptr.proxyuserpwd as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + if result as u64 == 0 + && (Curl_checkProxyheaders( + data, + conn, + b"User-Agent\0" as *const u8 as *const libc::c_char, + )) + .is_null() + && !((*data).set.str_0[STRING_USERAGENT as usize]).is_null() + { + result = Curl_dyn_addf( + req, + b"User-Agent: %s\r\n\0" as *const u8 as *const libc::c_char, + (*data).set.str_0[STRING_USERAGENT as usize], + ); + } + if result as u64 == 0 + && (Curl_checkProxyheaders( + data, + conn, + b"Proxy-Connection\0" as *const u8 as *const libc::c_char, + )) + .is_null() + { + /* CRLF terminate the request */ + result = Curl_dyn_add( + req, + b"Proxy-Connection: Keep-Alive\r\n\0" as *const u8 + as *const libc::c_char, + ); + } + if result as u64 == 0 { + /* Send the connect request to the proxy */ + result = Curl_add_custom_headers(data, 1 as i32 != 0, req); + } + if result as u64 == 0 { + result = Curl_dyn_add(req, b"\r\n\0" as *const u8 as *const libc::c_char); + } + if result as u64 == 0 { + result = Curl_buffer_send( + req, + data, + &mut (*data).info.request_size, + 0 as curl_off_t, + sockindex, + ); + } + if result as u64 != 0 { + Curl_failf( + data, + b"Failed sending CONNECT to proxy\0" as *const u8 + as *const libc::c_char, + ); + } } - // let ref mut fresh9 = (*s).nsend; - unsafe{(*s).nsend = ((*s).nsend as u64).wrapping_sub(bytes_written as u64) - as size_t as size_t; - // let ref mut fresh10 = (*k).upload_fromhere; - (*k).upload_fromhere = ((*k).upload_fromhere).offset(bytes_written as isize);} - return result; + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(host as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + host as *mut libc::c_void, + 340 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + hostheader as *mut libc::c_void, + 341 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + if result as u64 != 0 { + return result; + } + (*s).tunnel_state = TUNNEL_CONNECT; /* END CONNECT PHASE */ } - unsafe{(*http).sending = HTTPSEND_NADA;} - /* if nothing left to send, continue */ - } - /* READING RESPONSE PHASE */ - let mut error: i32 = 0 as i32; - while unsafe{(*s).keepon as u64} != 0 { - let mut gotbytes: ssize_t = 0; - let mut byte: libc::c_char = 0; - /* Read one byte at a time to avoid a race condition. Wait at most one - second before looping to ensure continuous pgrsUpdates. */ - result = unsafe{Curl_read( - data, - tunnelsocket, - &mut byte, - 1 as size_t, - &mut gotbytes, - )}; - if result as u32 == CURLE_AGAIN as u32 { - /* socket buffer drained, return */ - return CURLE_OK; + check = Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0); + if check <= 0 as i64 { + Curl_failf( + data, + b"Proxy CONNECT aborted due to timeout\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OPERATION_TIMEDOUT; } - if unsafe{Curl_pgrsUpdate(data)} != 0 { - return CURLE_ABORTED_BY_CALLBACK; + if !Curl_conn_data_pending(conn, sockindex) && (*http).sending as u64 == 0 { + return CURLE_OK; /* return so we'll be called again polling-style */ } - if result as u64 != 0 { - unsafe{(*s).keepon = KEEPON_DONE;} - break; - } else if gotbytes <= 0 as i64 { - if unsafe{(*data).set.proxyauth} != 0 - && unsafe{(*data).state.authproxy.avail} != 0 - && unsafe{!((*data).state.aptr.proxyuserpwd).is_null()} - { /* proxy auth was requested and there was proxy auth available, - then deem this as "mere" proxy disconnect */ - // let ref mut fresh11 = (*conn).bits; - unsafe{((*conn).bits).set_proxy_connect_closed(1 as bit); - Curl_infof( - data, - b"Proxy CONNECT connection closed\0" as *const u8 as *const libc::c_char, - );} - } else { - error = 1 as i32; - unsafe{ - Curl_failf( + /* at this point, the tunnel_connecting phase is over. */ + if (*http).sending as u32 == HTTPSEND_REQUEST as u32 { + if (*s).nsend == 0 { + let mut fillcount: size_t = 0; + // let ref mut fresh8 = (*k).upload_fromhere; + (*k).upload_fromhere = (*data).state.ulbuf; + result = Curl_fillreadbuffer( data, - b"Proxy CONNECT aborted\0" as *const u8 as *const libc::c_char, - );} - } - unsafe{ (*s).keepon = KEEPON_DONE;} - break; - } else if unsafe{(*s).keepon as u32} == KEEPON_IGNORE as u32 { - /* This means we are currently ignoring a response-body */ - if unsafe{(*s).cl} != 0 { - // let ref mut fresh12 = (*s).cl; - /* A Content-Length based body: simply count down the counter - and make sure to break out of the loop when we're done! */ - unsafe{(*s).cl -= 1; - if !((*s).cl <= 0 as i64) { - continue; + (*data).set.upload_buffer_size as size_t, + &mut fillcount, + ); + if result as u64 != 0 { + return result; } - (*s).keepon = KEEPON_DONE; - (*s).tunnel_state = TUNNEL_COMPLETE;} - break; - } else { - /* chunked-encoded body, so we need to do the chunked dance - properly to know when the end of the body is reached */ - let mut r: CHUNKcode = CHUNKE_OK; - let mut extra: CURLcode = CURLE_OK; - let mut tookcareof: ssize_t = 0 as ssize_t; - /* now parse the chunked piece of data so that we can - properly tell when the stream ends */ - r = unsafe{Curl_httpchunk_read( + (*s).nsend = fillcount; + } + if (*s).nsend != 0 { + let mut bytes_written: ssize_t = 0; /* write to socket (send away data) */ + result = Curl_write( data, - &mut byte, - 1 as ssize_t, - &mut tookcareof, - &mut extra, - )}; - if r as i32 == CHUNKE_STOP as i32 { - /* we're done reading chunks! */ - unsafe{ - Curl_infof( + (*conn).writesockfd, /* socket to send to */ + (*k).upload_fromhere as *const libc::c_void, /* buffer pointer */ + (*s).nsend, /* buffer size */ + &mut bytes_written, /* actually sent */ + ); + if result as u64 == 0 { + /* send to debug callback! */ + result = Curl_debug( data, - b"chunk reading DONE\0" as *const u8 as *const libc::c_char, - ); - (*s).keepon = KEEPON_DONE; - /* we did the full CONNECT treatment, go COMPLETE */ - (*s).tunnel_state = TUNNEL_COMPLETE; - } + CURLINFO_HEADER_OUT, + (*k).upload_fromhere, + bytes_written as size_t, + ) as CURLcode; } + // let ref mut fresh9 = (*s).nsend; + (*s).nsend = + ((*s).nsend as u64).wrapping_sub(bytes_written as u64) as size_t as size_t; + // let ref mut fresh10 = (*k).upload_fromhere; + (*k).upload_fromhere = ((*k).upload_fromhere).offset(bytes_written as isize); + return result; } - } else { - if unsafe{Curl_dyn_addn( - &mut (*s).rcvbuf, - &mut byte as *mut libc::c_char as *const libc::c_void, - 1 as size_t, - ) as u64} - != 0 - { - unsafe{ Curl_failf( - data, - b"CONNECT response too large!\0" as *const u8 as *const libc::c_char, - );} - return CURLE_RECV_ERROR; + (*http).sending = HTTPSEND_NADA; + /* if nothing left to send, continue */ + } + /* READING RESPONSE PHASE */ + let mut error: i32 = 0 as i32; + while (*s).keepon as u64 != 0 { + let mut gotbytes: ssize_t = 0; + let mut byte: libc::c_char = 0; + /* Read one byte at a time to avoid a race condition. Wait at most one + second before looping to ensure continuous pgrsUpdates. */ + result = Curl_read(data, tunnelsocket, &mut byte, 1 as size_t, &mut gotbytes); + if result as u32 == CURLE_AGAIN as u32 { + /* socket buffer drained, return */ + return CURLE_OK; } - /* if this is not the end of a header line then continue */ - if byte as i32 != 0xa as i32 { - continue; + if Curl_pgrsUpdate(data) != 0 { + return CURLE_ABORTED_BY_CALLBACK; } - linep = unsafe{Curl_dyn_ptr(&mut (*s).rcvbuf)}; - perline = unsafe{Curl_dyn_len(&mut (*s).rcvbuf)};/* amount of bytes in this line */ - /* convert from the network encoding */ - result = CURLE_OK as CURLcode; - /* Curl_convert_from_network calls failf if unsuccessful */ if result as u64 != 0 { - return result; - } - /* output debug if that is requested */ - unsafe{ Curl_debug(data, CURLINFO_HEADER_IN, linep, perline); - if ((*data).set).suppress_connect_headers() == 0 { - /* send the header to the callback */ - let mut writetype: i32 = (1 as i32) << 1 as i32; - if ((*data).set).include_header() != 0 { - writetype |= (1 as i32) << 0 as i32; - } - result = Curl_client_write(data, writetype, linep, perline); - if result as u64 != 0 { - return result; + (*s).keepon = KEEPON_DONE; + break; + } else if gotbytes <= 0 as i64 { + if (*data).set.proxyauth != 0 + && (*data).state.authproxy.avail != 0 + && !((*data).state.aptr.proxyuserpwd).is_null() + { + /* proxy auth was requested and there was proxy auth available, + then deem this as "mere" proxy disconnect */ + // let ref mut fresh11 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(1 as bit); + Curl_infof( + data, + b"Proxy CONNECT connection closed\0" as *const u8 + as *const libc::c_char, + ); + } else { + error = 1 as i32; + Curl_failf( + data, + b"Proxy CONNECT aborted\0" as *const u8 as *const libc::c_char, + ); } - } - // let ref mut fresh13 = (*data).info.header_size; - (*data).info.header_size += perline as i64; - } - /* Newlines are CRLF, so the CR is ignored as the line isn't - really terminated until the LF comes. Treat a following CR - as end-of-headers as well.*/ - if '\r' as i32 == unsafe{*linep.offset(0 as isize) as i32} - || '\n' as i32 == unsafe{*linep.offset(0 as isize) as i32} - { /* end of response-headers from the proxy */ - if 407 as i32 == unsafe{(*k).httpcode} && unsafe{((*data).state).authproblem()} == 0 { - unsafe{ - /* If we get a 407 response code with content length - when we have no auth problem, we must ignore the - whole response-body */ - (*s).keepon = KEEPON_IGNORE; - if (*s).cl != 0 { - Curl_infof( - data, - b"Ignore %ld bytes of response-body\0" as *const u8 - as *const libc::c_char, - (*s).cl, - ); - /* We set ignorebody true here since the chunked decoder - function will acknowledge that. Pay attention so that this is - cleared again when this function returns! */ - } else if (*s).chunked_encoding() != 0 { - let mut r_0: CHUNKcode = CHUNKE_OK; - let mut extra_0: CURLcode = CURLE_OK; + (*s).keepon = KEEPON_DONE; + break; + } else if (*s).keepon as u32 == KEEPON_IGNORE as u32 { + /* This means we are currently ignoring a response-body */ + if (*s).cl != 0 { + // let ref mut fresh12 = (*s).cl; + /* A Content-Length based body: simply count down the counter + and make sure to break out of the loop when we're done! */ + (*s).cl -= 1; + if !((*s).cl <= 0 as i64) { + continue; + } + (*s).keepon = KEEPON_DONE; + (*s).tunnel_state = TUNNEL_COMPLETE; + break; + } else { + /* chunked-encoded body, so we need to do the chunked dance + properly to know when the end of the body is reached */ + let mut r: CHUNKcode = CHUNKE_OK; + let mut extra: CURLcode = CURLE_OK; + let mut tookcareof: ssize_t = 0 as ssize_t; + /* now parse the chunked piece of data so that we can + properly tell when the stream ends */ + r = Curl_httpchunk_read( + data, + &mut byte, + 1 as ssize_t, + &mut tookcareof, + &mut extra, + ); + if r as i32 == CHUNKE_STOP as i32 { + /* we're done reading chunks! */ Curl_infof( data, - b"Ignore chunked response-body\0" as *const u8 - as *const libc::c_char, - ); - (*k).set_ignorebody(1 as bit); - if *linep.offset(1 as isize) as i32 - == '\n' as i32 - { - /* this can only be a LF if the letter at index 0 was a CR */ - linep = linep.offset(1); - } - /* now parse the chunked piece of data so that we can properly - tell when the stream ends */ - r_0 = Curl_httpchunk_read( - data, - linep.offset(1 as isize), - 1 as ssize_t, - &mut gotbytes, - &mut extra_0, + b"chunk reading DONE\0" as *const u8 as *const libc::c_char, ); - if r_0 as i32 == CHUNKE_STOP as i32 { - /* we're done reading chunks! */ - Curl_infof( - data, - b"chunk reading DONE\0" as *const u8 as *const libc::c_char, - ); - (*s).keepon = KEEPON_DONE; - /* we did the full CONNECT treatment, go to COMPLETE */ - (*s).tunnel_state = TUNNEL_COMPLETE; - } - } else { - /* without content-length or chunked encoding, we - can't keep the connection alive since the close is - the end signal so we bail out at once instead */ (*s).keepon = KEEPON_DONE; + /* we did the full CONNECT treatment, go COMPLETE */ + (*s).tunnel_state = TUNNEL_COMPLETE; } - } - } else { - unsafe{ - (*s).keepon = KEEPON_DONE;} } - if unsafe{(*s).keepon as u32} == KEEPON_DONE as u32 - && unsafe{(*s).cl }== 0 - { unsafe{ - /* we did the full CONNECT treatment, go to COMPLETE */ - (*s).tunnel_state = TUNNEL_COMPLETE;} - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe{(*s).keepon as u32} == KEEPON_IGNORE as u32 - || unsafe{(*s).keepon as u32} == KEEPON_DONE as u32 + } else { + if Curl_dyn_addn( + &mut (*s).rcvbuf, + &mut byte as *mut libc::c_char as *const libc::c_void, + 1 as size_t, + ) as u64 + != 0 { - } else { - unsafe{ - __assert_fail( - b"s->keepon == KEEPON_IGNORE || s->keepon == KEEPON_DONE\0" as *const u8 - as *const libc::c_char, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 555 as u32, - (*::std::mem::transmute::<&[u8; 61], &[libc::c_char; 61]>( - b"CURLcode CONNECT(struct Curl_easy *, int, const char *, int)\0", - )) - .as_ptr(), + Curl_failf( + data, + b"CONNECT response too large!\0" as *const u8 as *const libc::c_char, ); - } + return CURLE_RECV_ERROR; } - } else { - unsafe{ - if curl_strnequal( - b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char, - linep, - strlen(b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char), - ) != 0 - && 401 as i32 == (*k).httpcode - || curl_strnequal( - b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char, - linep, - strlen(b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char), - ) != 0 - && 407 as i32 == (*k).httpcode - { - let mut proxy: bool = if (*k).httpcode == 407 as i32 { - 1 as i32 - } else { - 0 as i32 - } != 0; - let mut auth: *mut libc::c_char = Curl_copy_header_value(linep); - if auth.is_null() { - return CURLE_OUT_OF_MEMORY; + /* if this is not the end of a header line then continue */ + if byte as i32 != 0xa as i32 { + continue; + } + linep = Curl_dyn_ptr(&mut (*s).rcvbuf); + perline = Curl_dyn_len(&mut (*s).rcvbuf); /* amount of bytes in this line */ + /* convert from the network encoding */ + result = CURLE_OK as CURLcode; + /* Curl_convert_from_network calls failf if unsuccessful */ + if result as u64 != 0 { + return result; + } + /* output debug if that is requested */ + Curl_debug(data, CURLINFO_HEADER_IN, linep, perline); + if ((*data).set).suppress_connect_headers() == 0 { + /* send the header to the callback */ + let mut writetype: i32 = (1 as i32) << 1 as i32; + if ((*data).set).include_header() != 0 { + writetype |= (1 as i32) << 0 as i32; } - result = Curl_http_input_auth(data, proxy, auth); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(auth as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - auth as *mut libc::c_void, - 571 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); + result = Curl_client_write(data, writetype, linep, perline); if result as u64 != 0 { return result; } - } else if curl_strnequal( - b"Content-Length:\0" as *const u8 as *const libc::c_char, - linep, - strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char), - ) != 0 + } + // let ref mut fresh13 = (*data).info.header_size; + (*data).info.header_size += perline as i64; + /* Newlines are CRLF, so the CR is ignored as the line isn't + really terminated until the LF comes. Treat a following CR + as end-of-headers as well.*/ + if '\r' as i32 == *linep.offset(0 as isize) as i32 + || '\n' as i32 == *linep.offset(0 as isize) as i32 { - if (*k).httpcode / 100 as i32 == 2 as i32 { - /* A client MUST ignore any Content-Length or Transfer-Encoding - header fields received in a successful response to CONNECT. - "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ - Curl_infof( - data, - b"Ignoring Content-Length in CONNECT %03d response\0" as *const u8 - as *const libc::c_char, - (*k).httpcode, - ); + /* end of response-headers from the proxy */ + if 407 as i32 == (*k).httpcode && ((*data).state).authproblem() == 0 { + /* If we get a 407 response code with content length + when we have no auth problem, we must ignore the + whole response-body */ + (*s).keepon = KEEPON_IGNORE; + if (*s).cl != 0 { + Curl_infof( + data, + b"Ignore %ld bytes of response-body\0" as *const u8 + as *const libc::c_char, + (*s).cl, + ); + /* We set ignorebody true here since the chunked decoder + function will acknowledge that. Pay attention so that this is + cleared again when this function returns! */ + } else if (*s).chunked_encoding() != 0 { + let mut r_0: CHUNKcode = CHUNKE_OK; + let mut extra_0: CURLcode = CURLE_OK; + Curl_infof( + data, + b"Ignore chunked response-body\0" as *const u8 + as *const libc::c_char, + ); + (*k).set_ignorebody(1 as bit); + if *linep.offset(1 as isize) as i32 == '\n' as i32 { + /* this can only be a LF if the letter at index 0 was a CR */ + linep = linep.offset(1); + } + /* now parse the chunked piece of data so that we can properly + tell when the stream ends */ + r_0 = Curl_httpchunk_read( + data, + linep.offset(1 as isize), + 1 as ssize_t, + &mut gotbytes, + &mut extra_0, + ); + if r_0 as i32 == CHUNKE_STOP as i32 { + /* we're done reading chunks! */ + Curl_infof( + data, + b"chunk reading DONE\0" as *const u8 as *const libc::c_char, + ); + (*s).keepon = KEEPON_DONE; + /* we did the full CONNECT treatment, go to COMPLETE */ + (*s).tunnel_state = TUNNEL_COMPLETE; + } + } else { + /* without content-length or chunked encoding, we + can't keep the connection alive since the close is + the end signal so we bail out at once instead */ + (*s).keepon = KEEPON_DONE; + } } else { - curlx_strtoofft( - linep.offset(strlen( - b"Content-Length:\0" as *const u8 as *const libc::c_char, - ) as isize), - 0 as *mut *mut libc::c_char, - 10 as i32, - &mut (*s).cl, - ); + (*s).keepon = KEEPON_DONE; } - } else if Curl_compareheader( - linep, - b"Connection:\0" as *const u8 as *const libc::c_char, - b"close\0" as *const u8 as *const libc::c_char, - ) { - (*s).set_close_connection(1 as bit); - } else if curl_strnequal( - b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, - linep, - strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char), - ) != 0 - { - if (*k).httpcode / 100 as i32 == 2 as i32 { - /* A client MUST ignore any Content-Length or Transfer-Encoding - header fields received in a successful response to CONNECT. - "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ - Curl_infof( - data, - b"Ignoring Transfer-Encoding in CONNECT %03d response\0" - as *const u8 - as *const libc::c_char, - (*k).httpcode, + if (*s).keepon as u32 == KEEPON_DONE as u32 && (*s).cl == 0 { + /* we did the full CONNECT treatment, go to COMPLETE */ + (*s).tunnel_state = TUNNEL_COMPLETE; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*s).keepon as u32 == KEEPON_IGNORE as u32 + || (*s).keepon as u32 == KEEPON_DONE as u32 + { + } else { + __assert_fail( + b"s->keepon == KEEPON_IGNORE || s->keepon == KEEPON_DONE\0" as *const u8 + as *const libc::c_char, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + 555 as u32, + (*::std::mem::transmute::<&[u8; 61], &[libc::c_char; 61]>( + b"CURLcode CONNECT(struct Curl_easy *, int, const char *, int)\0", + )) + .as_ptr(), + ); + } + } else { + if curl_strnequal( + b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char, + linep, + strlen(b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char), + ) != 0 + && 401 as i32 == (*k).httpcode + || curl_strnequal( + b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char, + linep, + strlen( + b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char, + ), + ) != 0 + && 407 as i32 == (*k).httpcode + { + let mut proxy: bool = if (*k).httpcode == 407 as i32 { + 1 as i32 + } else { + 0 as i32 + } != 0; + let mut auth: *mut libc::c_char = Curl_copy_header_value(linep); + if auth.is_null() { + return CURLE_OUT_OF_MEMORY; + } + result = Curl_http_input_auth(data, proxy, auth); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + auth as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + auth as *mut libc::c_void, + 571 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, ); + if result as u64 != 0 { + return result; + } + } else if curl_strnequal( + b"Content-Length:\0" as *const u8 as *const libc::c_char, + linep, + strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char), + ) != 0 + { + if (*k).httpcode / 100 as i32 == 2 as i32 { + /* A client MUST ignore any Content-Length or Transfer-Encoding + header fields received in a successful response to CONNECT. + "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ + Curl_infof( + data, + b"Ignoring Content-Length in CONNECT %03d response\0" + as *const u8 + as *const libc::c_char, + (*k).httpcode, + ); + } else { + curlx_strtoofft( + linep.offset(strlen( + b"Content-Length:\0" as *const u8 as *const libc::c_char, + ) as isize), + 0 as *mut *mut libc::c_char, + 10 as i32, + &mut (*s).cl, + ); + } } else if Curl_compareheader( linep, + b"Connection:\0" as *const u8 as *const libc::c_char, + b"close\0" as *const u8 as *const libc::c_char, + ) { + (*s).set_close_connection(1 as bit); + } else if curl_strnequal( b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, - b"chunked\0" as *const u8 as *const libc::c_char, + linep, + strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char), + ) != 0 + { + if (*k).httpcode / 100 as i32 == 2 as i32 { + /* A client MUST ignore any Content-Length or Transfer-Encoding + header fields received in a successful response to CONNECT. + "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ + Curl_infof( + data, + b"Ignoring Transfer-Encoding in CONNECT %03d response\0" + as *const u8 + as *const libc::c_char, + (*k).httpcode, + ); + } else if Curl_compareheader( + linep, + b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, + b"chunked\0" as *const u8 as *const libc::c_char, + ) { + Curl_infof( + data, + b"CONNECT responded chunked\0" as *const u8 + as *const libc::c_char, + ); /* init our chunky engine */ + (*s).set_chunked_encoding(1 as i32 as bit); + Curl_httpchunk_init(data); + } + } else if Curl_compareheader( + linep, + b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, + b"close\0" as *const u8 as *const libc::c_char, ) { - Curl_infof( - data, - b"CONNECT responded chunked\0" as *const u8 as *const libc::c_char, - ); /* init our chunky engine */ - (*s).set_chunked_encoding(1 as i32 as bit); - Curl_httpchunk_init(data); + (*s).set_close_connection(1 as i32 as bit); + } else if 2 as i32 + == sscanf( + linep, + b"HTTP/1.%d %d\0" as *const u8 as *const libc::c_char, + &mut subversion as *mut i32, + &mut (*k).httpcode as *mut i32, + ) + { + /* store the HTTP code from the proxy */ + (*data).info.httpproxycode = (*k).httpcode; } - } else if Curl_compareheader( - linep, - b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, - b"close\0" as *const u8 as *const libc::c_char, - ) { - (*s).set_close_connection(1 as i32 as bit); - } else if 2 as i32 - == sscanf( - linep, - b"HTTP/1.%d %d\0" as *const u8 as *const libc::c_char, - &mut subversion as *mut i32, - &mut (*k).httpcode as *mut i32, - ) - {/* store the HTTP code from the proxy */ - (*data).info.httpproxycode = (*k).httpcode; - } - Curl_dyn_reset(&mut (*s).rcvbuf); - } - } /* while there's buffer left and loop is requested */ + Curl_dyn_reset(&mut (*s).rcvbuf); + } /* while there's buffer left and loop is requested */ + } } - } - if unsafe{Curl_pgrsUpdate(data)} != 0 { - return CURLE_ABORTED_BY_CALLBACK; - } - if error != 0 { - return CURLE_RECV_ERROR; - } - if unsafe{(*data).info.httpproxycode / 100 as i32 }!= 2 as i32 { - /* Deal with the possibly already received authenticate - headers. 'newurl' is set to a new URL if we must loop. */ - result = unsafe{Curl_http_auth_act(data)}; - if result as u64 != 0 { - return result; + if Curl_pgrsUpdate(data) != 0 { + return CURLE_ABORTED_BY_CALLBACK; } - if unsafe{ ((*conn).bits).close() }!= 0 { - /* the connection has been marked for closure, most likely in the - Curl_http_auth_act() function and thus we can kill it at once - below */ - unsafe{(*s).set_close_connection(1 as bit);} + if error != 0 { + return CURLE_RECV_ERROR; } + if (*data).info.httpproxycode / 100 as i32 != 2 as i32 { + /* Deal with the possibly already received authenticate + headers. 'newurl' is set to a new URL if we must loop. */ + result = Curl_http_auth_act(data); + if result as u64 != 0 { + return result; + } + if ((*conn).bits).close() != 0 { + /* the connection has been marked for closure, most likely in the + Curl_http_auth_act() function and thus we can kill it at once + below */ + (*s).set_close_connection(1 as bit); + } + } + if (*s).close_connection() as i32 != 0 && !((*data).req.newurl).is_null() { + /* Connection closed by server. Don't use it anymore */ + Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); + (*conn).sock[sockindex as usize] = -(1 as i32); + break; + } else { + if !((*data).req.newurl).is_null() + && TUNNEL_COMPLETE as u32 == (*s).tunnel_state as u32 + { + connect_init(data, 1 as i32 != 0); + } + if ((*data).req.newurl).is_null() { + break; + } + } /* END READING RESPONSE PHASE */ } - if unsafe{(*s).close_connection() as i32} != 0 && unsafe{!((*data).req.newurl).is_null()} { - unsafe{ - /* Connection closed by server. Don't use it anymore */ - Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); - (*conn).sock[sockindex as usize] = -(1 as i32); - } - break; - } else { - if unsafe{!((*data).req.newurl).is_null()} - && TUNNEL_COMPLETE as u32 - == unsafe{(*s).tunnel_state as u32} - { - connect_init(data, 1 as i32 != 0); + /* If we are supposed to continue and request a new URL, which basically + * means the HTTP authentication is still going on so if the tunnel + * is complete we start over in INIT state */ + if (*data).info.httpproxycode / 100 as i32 != 2 as i32 { + if (*s).close_connection() as i32 != 0 && !((*data).req.newurl).is_null() { + // let ref mut fresh14 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(1 as bit); + Curl_infof( + data, + b"Connect me again please\0" as *const u8 as *const libc::c_char, + ); + connect_done(data); + } else { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).req.newurl as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).req.newurl as *mut libc::c_void, + 663 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh15 = (*data).req.newurl; + (*data).req.newurl = 0 as *mut libc::c_char; + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 2 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 2 as i32, + b"proxy CONNECT failure\0" as *const u8 as *const libc::c_char, + ); + Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); + (*conn).sock[sockindex as usize] = -(1 as i32); } - if unsafe{((*data).req.newurl).is_null()} { - break; + (*s).tunnel_state = TUNNEL_INIT; /* to back to init state */ + if ((*conn).bits).proxy_connect_closed() != 0 { + /* this is not an error, just part of the connection negotiation */ + return CURLE_OK; } - } /* END READING RESPONSE PHASE */ - } - /* If we are supposed to continue and request a new URL, which basically - * means the HTTP authentication is still going on so if the tunnel - * is complete we start over in INIT state */ - if unsafe{(*data).info.httpproxycode / 100 as i32} != 2 as i32 { - if unsafe{(*s).close_connection() as i32} != 0 && unsafe{!((*data).req.newurl).is_null()} { - // let ref mut fresh14 = (*conn).bits; - unsafe{((*conn).bits).set_proxy_connect_closed(1 as bit); - Curl_infof( + Curl_dyn_free(&mut (*s).rcvbuf); + Curl_failf( data, - b"Connect me again please\0" as *const u8 as *const libc::c_char, - ); - connect_done(data); - } - } else { - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")((*data).req.newurl as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - (*data).req.newurl as *mut libc::c_void, - 663 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh15 = (*data).req.newurl; - (*data).req.newurl = 0 as *mut libc::c_char;} - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - unsafe{Curl_conncontrol(conn, 2 as i32);} - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - unsafe{Curl_conncontrol( - conn, - 2 as i32, - b"proxy CONNECT failure\0" as *const u8 as *const libc::c_char, + b"Received HTTP code %d from proxy after CONNECT\0" as *const u8 + as *const libc::c_char, + (*data).req.httpcode, ); - Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); - (*conn).sock[sockindex as usize] = -(1 as i32);} - } - unsafe{(*s).tunnel_state = TUNNEL_INIT;}/* to back to init state */ - if unsafe{((*conn).bits).proxy_connect_closed()} != 0 { - /* this is not an error, just part of the connection negotiation */ - return CURLE_OK; + return CURLE_RECV_ERROR; } - unsafe{Curl_dyn_free(&mut (*s).rcvbuf); - Curl_failf( + (*s).tunnel_state = TUNNEL_COMPLETE; + /* If a proxy-authorization header was used for the proxy, then we should + make sure that it isn't accidentally used for the document request + after we've connected. So let's free and clear it here. */ + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + 688 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh16 = (*data).state.aptr.proxyuserpwd; + (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; + // let ref mut fresh17 = (*data).state.aptr.proxyuserpwd; + (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; + // let ref mut fresh18 = (*data).state.authproxy; + ((*data).state.authproxy).set_done(1 as bit); + // let ref mut fresh19 = (*data).state.authproxy; + ((*data).state.authproxy).set_multipass(0 as bit); + Curl_infof( data, - b"Received HTTP code %d from proxy after CONNECT\0" as *const u8 as *const libc::c_char, - (*data).req.httpcode, - );} - return CURLE_RECV_ERROR; + b"Proxy replied %d to CONNECT request\0" as *const u8 as *const libc::c_char, + (*data).info.httpproxycode, + ); + // let ref mut fresh20 = (*data).req; + ((*data).req).set_ignorebody(0 as bit); /* put it (back) to non-ignore state */ + // let ref mut fresh21 = (*conn).bits; + ((*conn).bits).set_rewindaftersend(0 as bit); /* make sure this isn't set for the + document request */ + Curl_dyn_free(&mut (*s).rcvbuf); + return CURLE_OK; } - unsafe{(*s).tunnel_state = TUNNEL_COMPLETE;} - /* If a proxy-authorization header was used for the proxy, then we should - make sure that it isn't accidentally used for the document request - after we've connected. So let's free and clear it here. */ - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - );} - #[cfg(CURLDEBUG)] - unsafe{ curl_dbg_free( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - 688 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh16 = (*data).state.aptr.proxyuserpwd; - (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; - // let ref mut fresh17 = (*data).state.aptr.proxyuserpwd; - (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; - // let ref mut fresh18 = (*data).state.authproxy; - ((*data).state.authproxy).set_done(1 as bit); - // let ref mut fresh19 = (*data).state.authproxy; - ((*data).state.authproxy).set_multipass(0 as bit); - Curl_infof( - data, - b"Proxy replied %d to CONNECT request\0" as *const u8 as *const libc::c_char, - (*data).info.httpproxycode, - ); - // let ref mut fresh20 = (*data).req; - ((*data).req).set_ignorebody(0 as bit);/* put it (back) to non-ignore state */ - // let ref mut fresh21 = (*conn).bits; - ((*conn).bits).set_rewindaftersend(0 as bit);/* make sure this isn't set for the - document request */ - Curl_dyn_free(&mut (*s).rcvbuf);} - return CURLE_OK; } /* The Hyper version of CONNECT */ #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP), USE_HYPER))] @@ -1074,288 +1057,324 @@ mut hostname: *const libc::c_char, mut remote_port: i32, ) -> CURLcode { - let mut current_block: u64; - let mut conn: *mut connectdata = unsafe {(*data).conn}; - let mut h: *mut hyptransfer = unsafe {&mut (*data).hyp}; - let mut tunnelsocket: curl_socket_t = unsafe {(*conn).sock[sockindex as usize]}; - let mut s: *mut http_connect_state = unsafe {(*conn).connect_state}; - let mut result: CURLcode = CURLE_OUT_OF_MEMORY; - let mut io: *mut hyper_io = 0 as *mut hyper_io; - let mut req: *mut hyper_request = 0 as *mut hyper_request; - let mut headers: *mut hyper_headers = 0 as *mut hyper_headers; - let mut options: *mut hyper_clientconn_options = 0 as *mut hyper_clientconn_options; - let mut handshake: *mut hyper_task = 0 as *mut hyper_task; - let mut task: *mut hyper_task = 0 as *mut hyper_task; /* for the handshake */ - let mut sendtask: *mut hyper_task = 0 as *mut hyper_task;/* for the send */ - let mut client: *mut hyper_clientconn = 0 as *mut hyper_clientconn; - let mut hypererr: *mut hyper_error = 0 as *mut hyper_error; - let mut hostheader: *mut libc::c_char = 0 as *mut libc::c_char; /* for CONNECT */ - let mut host: *mut libc::c_char = 0 as *mut libc::c_char;/* Host: */ - if Curl_connect_complete(conn) { - return CURLE_OK;/* CONNECT is already completed */ - } - // let ref mut fresh6 = (*conn).bits; - unsafe {((*conn).bits).set_proxy_connect_closed(0 as bit);} - 's_65: loop { - unsafe { - match (*s).tunnel_state as u32 { - 0 => { - /* BEGIN CONNECT PHASE */ - io = hyper_io_new(); - if io.is_null() { - Curl_failf( - data, - b"Couldn't create hyper IO\0" as *const u8 as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - /* tell Hyper how to read/write network data */ - hyper_io_set_userdata(io, data as *mut libc::c_void); - hyper_io_set_read( - io, - Some( - Curl_hyper_recv - as unsafe extern "C" fn( - *mut libc::c_void, - *mut hyper_context, - *mut uint8_t, - size_t, - ) -> size_t, - ), - ); - hyper_io_set_write( - io, - Some( - Curl_hyper_send - as unsafe extern "C" fn( - *mut libc::c_void, - *mut hyper_context, - *const uint8_t, - size_t, - ) -> size_t, - ), - ); - (*conn).sockfd = tunnelsocket; - (*data).state.hconnect = 1 as i32 != 0; - /* create an executor to poll futures */ - if ((*h).exec).is_null() { - // let ref mut fresh7 = (*h).exec; - (*h).exec = hyper_executor_new(); - if ((*h).exec).is_null() { - Curl_failf( - data, - b"Couldn't create hyper executor\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } - } - options = hyper_clientconn_options_new(); - if options.is_null() { + let mut current_block: u64; + let mut conn: *mut connectdata =unsafe { (*data).conn}; + let mut h: *mut hyptransfer =unsafe { &mut (*data).hyp}; + let mut tunnelsocket: curl_socket_t = unsafe {(*conn).sock[sockindex as usize]}; + let mut s: *mut http_connect_state = unsafe {(*conn).connect_state}; + let mut result: CURLcode = CURLE_OUT_OF_MEMORY; + let mut io: *mut hyper_io =unsafe { 0 as *mut hyper_io}; + let mut req: *mut hyper_request =unsafe { 0 as *mut hyper_request}; + let mut headers: *mut hyper_headers = unsafe {0 as *mut hyper_headers}; + let mut options: *mut hyper_clientconn_options = unsafe {0 as *mut hyper_clientconn_options}; + let mut handshake: *mut hyper_task =unsafe { 0 as *mut hyper_task}; + let mut task: *mut hyper_task =unsafe { 0 as *mut hyper_task}; /* for the handshake */ + let mut sendtask: *mut hyper_task =unsafe { 0 as *mut hyper_task}; /* for the send */ + let mut client: *mut hyper_clientconn =unsafe { 0 as *mut hyper_clientconn}; + let mut hypererr: *mut hyper_error =unsafe { 0 as *mut hyper_error}; + let mut hostheader: *mut libc::c_char =unsafe { 0 as *mut libc::c_char}; /* for CONNECT */ + let mut host: *mut libc::c_char = unsafe {0 as *mut libc::c_char}; /* Host: */ + unsafe { + if Curl_connect_complete(conn) { + return CURLE_OK; /* CONNECT is already completed */ + } + // let ref mut fresh6 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(0 as bit); + 's_65: loop { + match (*s).tunnel_state as u32 { + 0 => { + /* BEGIN CONNECT PHASE */ + io = hyper_io_new(); + if io.is_null() { Curl_failf( data, - b"Couldn't create hyper client options\0" as *const u8 - as *const libc::c_char, + b"Couldn't create hyper IO\0" as *const u8 as *const libc::c_char, ); current_block = 14523688961733284890; break; } else { - hyper_clientconn_options_exec(options, (*h).exec); - /* "Both the `io` and the `options` are consumed in this function - call" */ - handshake = hyper_clientconn_handshake(io, options); /* ownership passed on */ - if handshake.is_null() { + /* tell Hyper how to read/write network data */ + hyper_io_set_userdata(io, data as *mut libc::c_void); + hyper_io_set_read( + io, + Some( + Curl_hyper_recv + as unsafe extern "C" fn( + *mut libc::c_void, + *mut hyper_context, + *mut uint8_t, + size_t, + ) + -> size_t, + ), + ); + hyper_io_set_write( + io, + Some( + Curl_hyper_send + as unsafe extern "C" fn( + *mut libc::c_void, + *mut hyper_context, + *const uint8_t, + size_t, + ) + -> size_t, + ), + ); + (*conn).sockfd = tunnelsocket; + (*data).state.hconnect = 1 as i32 != 0; + /* create an executor to poll futures */ + if ((*h).exec).is_null() { + // let ref mut fresh7 = (*h).exec; + (*h).exec = hyper_executor_new(); + if ((*h).exec).is_null() { + Curl_failf( + data, + b"Couldn't create hyper executor\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } + } + options = hyper_clientconn_options_new(); + if options.is_null() { Curl_failf( data, - b"Couldn't create hyper client handshake\0" as *const u8 + b"Couldn't create hyper client options\0" as *const u8 as *const libc::c_char, ); current_block = 14523688961733284890; break; } else { - io = 0 as *mut hyper_io; - options = 0 as *mut hyper_clientconn_options; - if HYPERE_OK as u32 - != hyper_executor_push((*h).exec, handshake) as u32 - { + hyper_clientconn_options_exec(options, (*h).exec); + /* "Both the `io` and the `options` are consumed in this function + call" */ + handshake = hyper_clientconn_handshake(io, options); /* ownership passed on */ + if handshake.is_null() { Curl_failf( data, - b"Couldn't hyper_executor_push the handshake\0" as *const u8 + b"Couldn't create hyper client handshake\0" as *const u8 as *const libc::c_char, ); current_block = 14523688961733284890; break; } else { - handshake = 0 as *mut hyper_task; - task = hyper_executor_poll((*h).exec); - if task.is_null() { + io = 0 as *mut hyper_io; + options = 0 as *mut hyper_clientconn_options; + if HYPERE_OK as u32 + != hyper_executor_push((*h).exec, handshake) as u32 + { Curl_failf( data, - b"Couldn't hyper_executor_poll the handshake\0" as *const u8 + b"Couldn't hyper_executor_push the handshake\0" as *const u8 as *const libc::c_char, ); current_block = 14523688961733284890; break; } else { - client = hyper_task_value(task) as *mut hyper_clientconn; - hyper_task_free(task); - req = hyper_request_new(); - if req.is_null() { + handshake = 0 as *mut hyper_task; + task = hyper_executor_poll((*h).exec); + if task.is_null() { Curl_failf( data, - b"Couldn't hyper_request_new\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else if hyper_request_set_method( - req, - b"CONNECT\0" as *const u8 as *const libc::c_char - as *mut uint8_t, - strlen(b"CONNECT\0" as *const u8 as *const libc::c_char), - ) as u64 - != 0 - { - Curl_failf( - data, - b"error setting method\0" as *const u8 + b"Couldn't hyper_executor_poll the handshake\0" + as *const u8 as *const libc::c_char, ); current_block = 14523688961733284890; break; } else { - result = CONNECT_host( - data, - conn, - hostname, - remote_port, - &mut hostheader, - &mut host, - ); - if result as u64 != 0 { - current_block = 14523688961733284890; - break; - } - if hyper_request_set_uri( - req, - hostheader as *mut uint8_t, - strlen(hostheader), - ) as u64 - != 0 - { + client = hyper_task_value(task) as *mut hyper_clientconn; + hyper_task_free(task); + req = hyper_request_new(); + if req.is_null() { Curl_failf( data, - b"error setting path\0" as *const u8 + b"Couldn't hyper_request_new\0" as *const u8 as *const libc::c_char, ); - result = CURLE_OUT_OF_MEMORY; - } - /* Setup the proxy-authorization header, if any */ - result = Curl_http_output_auth( - data, - conn, - b"CONNECT\0" as *const u8 as *const libc::c_char, - HTTPREQ_GET, - hostheader, - 1 as i32 != 0, - ); - if result as u64 != 0 { current_block = 14523688961733284890; break; - } - Curl_cfree.expect("non-null function pointer")( - hostheader as *mut libc::c_void, - ); - hostheader = 0 as *mut libc::c_char; - /* default is 1.1 */ - if (*conn).http_proxy.proxytype as u32 - == CURLPROXY_HTTP_1_0 as u32 - && HYPERE_OK as u32 - != hyper_request_set_version(req, 10 as i32) - as u32 + } else if hyper_request_set_method( + req, + b"CONNECT\0" as *const u8 as *const libc::c_char + as *mut uint8_t, + strlen( + b"CONNECT\0" as *const u8 as *const libc::c_char, + ), + ) as u64 + != 0 { Curl_failf( data, - b"error setting HTTP version\0" as *const u8 + b"error setting method\0" as *const u8 as *const libc::c_char, ); current_block = 14523688961733284890; break; } else { - headers = hyper_request_headers(req); - if headers.is_null() { + result = CONNECT_host( + data, + conn, + hostname, + remote_port, + &mut hostheader, + &mut host, + ); + if result as u64 != 0 { + current_block = 14523688961733284890; + break; + } + if hyper_request_set_uri( + req, + hostheader as *mut uint8_t, + strlen(hostheader), + ) as u64 + != 0 + { Curl_failf( data, - b"hyper_request_headers\0" as *const u8 + b"error setting path\0" as *const u8 as *const libc::c_char, ); + result = CURLE_OUT_OF_MEMORY; + } + /* Setup the proxy-authorization header, if any */ + result = Curl_http_output_auth( + data, + conn, + b"CONNECT\0" as *const u8 as *const libc::c_char, + HTTPREQ_GET, + hostheader, + 1 as i32 != 0, + ); + if result as u64 != 0 { current_block = 14523688961733284890; break; - } else { - if !host.is_null() - && Curl_hyper_header(data, headers, host) + } + Curl_cfree.expect("non-null function pointer")( + hostheader as *mut libc::c_void, + ); + hostheader = 0 as *mut libc::c_char; + /* default is 1.1 */ + if (*conn).http_proxy.proxytype as u32 + == CURLPROXY_HTTP_1_0 as u32 + && HYPERE_OK as u32 + != hyper_request_set_version(req, 10 as i32) as u32 - != 0 - { - current_block = 14523688961733284890; - break; - } - Curl_cfree.expect("non-null function pointer")( - host as *mut libc::c_void, + { + Curl_failf( + data, + b"error setting HTTP version\0" as *const u8 + as *const libc::c_char, ); - host = 0 as *mut libc::c_char; - if !((*data).state.aptr.proxyuserpwd).is_null() - && Curl_hyper_header( + current_block = 14523688961733284890; + break; + } else { + headers = hyper_request_headers(req); + if headers.is_null() { + Curl_failf( data, - headers, - (*data).state.aptr.proxyuserpwd, - ) - as u32 - != 0 - { + b"hyper_request_headers\0" as *const u8 + as *const libc::c_char, + ); current_block = 14523688961733284890; break; - } - if (Curl_checkProxyheaders( - data, - conn, - b"User-Agent\0" as *const u8 - as *const libc::c_char, - )) - .is_null() - && !((*data).set.str_0 - [STRING_USERAGENT as usize]) - .is_null() - { - let mut ua: dynbuf = dynbuf { - bufr: 0 as *mut libc::c_char, - leng: 0, - allc: 0, - toobig: 0, - }; - Curl_dyn_init( - &mut ua, - (1024 as i32 * 1024 as i32) - as size_t, + } else { + if !host.is_null() + && Curl_hyper_header(data, headers, host) + as u32 + != 0 + { + current_block = 14523688961733284890; + break; + } + Curl_cfree.expect("non-null function pointer")( + host as *mut libc::c_void, ); - result = Curl_dyn_addf( - &mut ua as *mut dynbuf, - b"User-Agent: %s\r\n\0" as *const u8 + host = 0 as *mut libc::c_char; + if !((*data).state.aptr.proxyuserpwd).is_null() + && Curl_hyper_header( + data, + headers, + (*data).state.aptr.proxyuserpwd, + ) + as u32 + != 0 + { + current_block = 14523688961733284890; + break; + } + if (Curl_checkProxyheaders( + data, + conn, + b"User-Agent\0" as *const u8 as *const libc::c_char, - (*data).set.str_0[STRING_USERAGENT - as i32 - as usize], - ); - if result as u64 != 0 { + )) + .is_null() + && !((*data).set.str_0 + [STRING_USERAGENT as usize]) + .is_null() + { + let mut ua: dynbuf = dynbuf { + bufr: 0 as *mut libc::c_char, + leng: 0, + allc: 0, + toobig: 0, + }; + Curl_dyn_init( + &mut ua, + (1024 as i32 * 1024 as i32) as size_t, + ); + result = Curl_dyn_addf( + &mut ua as *mut dynbuf, + b"User-Agent: %s\r\n\0" as *const u8 + as *const libc::c_char, + (*data).set.str_0 + [STRING_USERAGENT as i32 as usize], + ); + if result as u64 != 0 { + current_block = 14523688961733284890; + break; + } + if Curl_hyper_header( + data, + headers, + Curl_dyn_ptr(&mut ua), + ) + as u64 + != 0 + { + current_block = 14523688961733284890; + break; + } + Curl_dyn_free(&mut ua); + } + if (Curl_checkProxyheaders( + data, + conn, + b"Proxy-Connection\0" as *const u8 + as *const libc::c_char, + )) + .is_null() + && Curl_hyper_header( + data, + headers, + b"Proxy-Connection: Keep-Alive\0" + as *const u8 + as *const libc::c_char, + ) + as u32 + != 0 + { current_block = 14523688961733284890; break; } - if Curl_hyper_header( + if Curl_add_custom_headers( data, - headers, - Curl_dyn_ptr(&mut ua), + 1 as i32 != 0, + headers as *mut libc::c_void, ) as u64 != 0 @@ -1363,86 +1382,53 @@ current_block = 14523688961733284890; break; } - Curl_dyn_free(&mut ua); - } - if (Curl_checkProxyheaders( - data, - conn, - b"Proxy-Connection\0" as *const u8 - as *const libc::c_char, - )) - .is_null() - && Curl_hyper_header( - data, - headers, - b"Proxy-Connection: Keep-Alive\0" - as *const u8 - as *const libc::c_char, - ) - as u32 - != 0 - { - current_block = 14523688961733284890; - break; - } - if Curl_add_custom_headers( - data, - 1 as i32 != 0, - headers as *mut libc::c_void, - ) - as u64 - != 0 - { - current_block = 14523688961733284890; - break; - } - sendtask = hyper_clientconn_send(client, req); - if sendtask.is_null() { - Curl_failf( - data, - b"hyper_clientconn_send\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else if HYPERE_OK as u32 - != hyper_executor_push((*h).exec, sendtask) - as u32 - { - Curl_failf( - data, - b"Couldn't hyper_executor_push the send\0" - as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - hyper_clientconn_free(client); - loop { - task = hyper_executor_poll((*h).exec); - if !task.is_null() { - let mut error: bool = - hyper_task_type(task) - as u32 - == HYPER_TASK_ERROR - as u32; - if error { - hypererr = hyper_task_value(task) - as *mut hyper_error; + sendtask = hyper_clientconn_send(client, req); + if sendtask.is_null() { + Curl_failf( + data, + b"hyper_clientconn_send\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else if HYPERE_OK as u32 + != hyper_executor_push((*h).exec, sendtask) + as u32 + { + Curl_failf( + data, + b"Couldn't hyper_executor_push the send\0" + as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else { + hyper_clientconn_free(client); + loop { + task = hyper_executor_poll((*h).exec); + if !task.is_null() { + let mut error: bool = + hyper_task_type(task) as u32 + == HYPER_TASK_ERROR as u32; + if error { + hypererr = + hyper_task_value(task) + as *mut hyper_error; + } + hyper_task_free(task); + if error { + current_block = + 14523688961733284890; + break 's_65; + } } - hyper_task_free(task); - if error { - current_block = - 14523688961733284890; - break 's_65; + if task.is_null() { + break; } } - if task.is_null() { - break; - } + (*s).tunnel_state = TUNNEL_CONNECT; } - (*s).tunnel_state = TUNNEL_CONNECT; } } } @@ -1451,158 +1437,143 @@ } } } + current_block = 2945622622075328793; + } + 1 => { + current_block = 2945622622075328793; + } + _ => { + current_block = 1841672684692190573; } - current_block = 2945622622075328793; } - 1 => { - current_block = 2945622622075328793; + match current_block { + 2945622622075328793 => { + let mut didwhat: i32 = 0; + let mut done: bool = 0 as i32 != 0; + result = Curl_hyper_stream( + data, + conn, + &mut didwhat, + &mut done, + 0x1 as i32 | 0x2 as i32, + ); + if result as u64 != 0 { + current_block = 14523688961733284890; + break; + } + if done { + (*s).tunnel_state = TUNNEL_COMPLETE; + if !((*h).exec).is_null() { + hyper_executor_free((*h).exec); + // let ref mut fresh8 = (*h).exec; + (*h).exec = 0 as *const hyper_executor; + } + if !((*h).read_waker).is_null() { + hyper_waker_free((*h).read_waker); + // let ref mut fresh9 = (*h).read_waker; + (*h).read_waker = 0 as *mut hyper_waker; + } + if !((*h).write_waker).is_null() { + hyper_waker_free((*h).write_waker); + // let ref mut fresh10 = (*h).write_waker; + (*h).write_waker = 0 as *mut hyper_waker; + } + } + } + _ => {} } - _ => { - current_block = 1841672684692190573; + if ((*data).req.newurl).is_null() { + current_block = 14027225908442187354; + break; } } match current_block { - 2945622622075328793 => { - let mut didwhat: i32 = 0; - let mut done: bool = 0 as i32 != 0; - result = Curl_hyper_stream( - data, - conn, - &mut didwhat, - &mut done, - 0x1 as i32 | 0x2 as i32, - ); - if result as u64 != 0 { - current_block = 14523688961733284890; - break; - } - if done { - (*s).tunnel_state = TUNNEL_COMPLETE; - if !((*h).exec).is_null() { - hyper_executor_free((*h).exec); - // let ref mut fresh8 = (*h).exec; - (*h).exec = 0 as *const hyper_executor; - } - if !((*h).read_waker).is_null() { - hyper_waker_free((*h).read_waker); - // let ref mut fresh9 = (*h).read_waker; - (*h).read_waker = 0 as *mut hyper_waker; - } - if !((*h).write_waker).is_null() { - hyper_waker_free((*h).write_waker); - // let ref mut fresh10 = (*h).write_waker; - (*h).write_waker = 0 as *mut hyper_waker; + 14027225908442187354 => { + result = CURLE_OK; + if (*s).tunnel_state as u32 == TUNNEL_COMPLETE as u32 { + (*data).info.httpproxycode = (*data).req.httpcode; + if (*data).info.httpproxycode / 100 as i32 != 2 as i32 { + if ((*conn).bits).close() as i32 != 0 && !((*data).req.newurl).is_null() { + // let ref mut fresh11 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(1 as bit); + Curl_infof( + data, + b"Connect me again please\0" as *const u8 as *const libc::c_char, + ); + connect_done(data); + } else { + Curl_cfree.expect("non-null function pointer")( + (*data).req.newurl as *mut libc::c_void, + ); + // let ref mut fresh12 = (*data).req.newurl; + (*data).req.newurl = 0 as *mut libc::c_char; + Curl_conncontrol(conn, 2 as i32); + Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); + (*conn).sock[sockindex as usize] = -(1 as i32); + } + (*s).tunnel_state = TUNNEL_INIT; + if ((*conn).bits).proxy_connect_closed() == 0 { + Curl_failf( + data, + b"Received HTTP code %d from proxy after CONNECT\0" as *const u8 + as *const libc::c_char, + (*data).req.httpcode, + ); + result = CURLE_RECV_ERROR; + } } } } _ => {} } - if ((*data).req.newurl).is_null() { - current_block = 14027225908442187354; - break; + Curl_cfree.expect("non-null function pointer")(host as *mut libc::c_void); + Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); + if !io.is_null() { + hyper_io_free(io); } - } - } - match current_block { - 14027225908442187354 => { - result = CURLE_OK; - if unsafe {(*s).tunnel_state as u32} == TUNNEL_COMPLETE as u32 { - unsafe { - (*data).info.httpproxycode = (*data).req.httpcode;} - if unsafe {(*data).info.httpproxycode / 100 as i32} != 2 as i32 { - if unsafe {((*conn).bits).close() as i32} != 0 &&unsafe { !((*data).req.newurl).is_null()} - {unsafe { - // let ref mut fresh11 = (*conn).bits; - ((*conn).bits).set_proxy_connect_closed(1 as bit); - Curl_infof( - data, - b"Connect me again please\0" as *const u8 as *const libc::c_char, - ); - connect_done(data); - } - } else { - unsafe { - Curl_cfree.expect("non-null function pointer")( - (*data).req.newurl as *mut libc::c_void, - ); - // let ref mut fresh12 = (*data).req.newurl; - (*data).req.newurl = 0 as *mut libc::c_char; - Curl_conncontrol(conn, 2 as i32); - Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); - (*conn).sock[sockindex as usize] = -(1 as i32); - } - } - unsafe { - (*s).tunnel_state = TUNNEL_INIT;} - if unsafe {((*conn).bits).proxy_connect_closed()} == 0 { - unsafe { - Curl_failf( - data, - b"Received HTTP code %d from proxy after CONNECT\0" as *const u8 - as *const libc::c_char, - (*data).req.httpcode, - );} - result = CURLE_RECV_ERROR; - } - } - } + if !options.is_null() { + hyper_clientconn_options_free(options); } - _ => {} - } - unsafe { - Curl_cfree.expect("non-null function pointer")(host as *mut libc::c_void); - Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); - } - if !io.is_null() { - unsafe { - hyper_io_free(io); - } - } - if !options.is_null() { - unsafe { - hyper_clientconn_options_free(options);} - } - if !handshake.is_null() { - unsafe { - hyper_task_free(handshake);} - } - if !hypererr.is_null() { - let mut errbuf: [uint8_t; 256] = [0; 256]; - let mut errlen: size_t = unsafe {hyper_error_print( - hypererr, - errbuf.as_mut_ptr(), - ::std::mem::size_of::<[uint8_t; 256]>() as u64, - )}; - unsafe { - Curl_failf( - data, - b"Hyper: %.*s\0" as *const u8 as *const libc::c_char, - errlen as i32, - errbuf.as_mut_ptr(), - ); - hyper_error_free(hypererr);} + if !handshake.is_null() { + hyper_task_free(handshake); + } + if !hypererr.is_null() { + let mut errbuf: [uint8_t; 256] = [0; 256]; + let mut errlen: size_t = hyper_error_print( + hypererr, + errbuf.as_mut_ptr(), + ::std::mem::size_of::<[uint8_t; 256]>() as u64, + ); + Curl_failf( + data, + b"Hyper: %.*s\0" as *const u8 as *const libc::c_char, + errlen as i32, + errbuf.as_mut_ptr(), + ); + hyper_error_free(hypererr); + } + return result; } - return result; } - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] #[no_mangle] pub extern "C" fn Curl_connect_free(mut data: *mut Curl_easy) { - let mut conn: *mut connectdata = unsafe{ (*data).conn}; - let mut s: *mut http_connect_state = unsafe{ (*conn).connect_state}; - if !s.is_null() { - #[cfg(not(CURLDEBUG))] - unsafe{ Curl_cfree.expect("non-null function pointer")(s as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{ curl_dbg_free( - s as *mut libc::c_void, - 968 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh22 = (*conn).connect_state; - (*conn).connect_state = 0 as *mut http_connect_state;} + let mut conn: *mut connectdata = unsafe {(*data).conn}; + let mut s: *mut http_connect_state =unsafe { (*conn).connect_state}; + unsafe { + if !s.is_null() { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(s as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + s as *mut libc::c_void, + 968 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh22 = (*conn).connect_state; + (*conn).connect_state = 0 as *mut http_connect_state; + } } - } #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] #[no_mangle] @@ -1612,21 +1583,21 @@ mut hostname: *const libc::c_char, mut remote_port: i32, ) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = unsafe{ (*data).conn}; - if unsafe{ ((*conn).connect_state).is_null() }{ - result = unsafe{ connect_init(data, 0 as i32 != 0)}; - if result as u64 != 0 { - return result; + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe {(*data).conn}; + unsafe { + if ((*conn).connect_state).is_null() { + result = connect_init(data, 0 as i32 != 0); + if result as u64 != 0 { + return result; + } } + result = CONNECT(data, sockindex, hostname, remote_port); + if result as u32 != 0 || Curl_connect_complete(conn) as i32 != 0 { + connect_done(data); + } + return result; } - result = unsafe{ CONNECT(data, sockindex, hostname, remote_port)}; - if result as u32 != 0 || unsafe{ Curl_connect_complete(conn) as i32} != 0 { - connect_done(data); - } - return result; - } /* @@ -1642,25 +1613,22 @@ mut hostname: *const libc::c_char, mut remote_port: i32, ) -> CURLcode { - unsafe{ - return CURLE_NOT_BUILT_IN; + unsafe { + return CURLE_NOT_BUILT_IN; } } #[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] #[no_mangle] - pub extern "C" fn Curl_proxy_connect( - mut data: *mut Curl_easy, - mut sockindex: i32, - ) -> CURLcode { - unsafe{ - return CURLE_OK; + pub extern "C" fn Curl_proxy_connect(mut data: *mut Curl_easy, mut sockindex: i32) -> CURLcode { + unsafe { + return CURLE_OK; } } #[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] #[no_mangle] pub extern "C" fn Curl_connect_ongoing(mut conn: *mut connectdata) -> bool { - unsafe{ - return false; + unsafe { + return false; } } #[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] diff --git a/rust/rust_project/src/vtls/gtls.rs b/rust/rust_project/src/vtls/gtls.rs index 60196a2..c9bb782 100644 --- a/rust/rust_project/src/vtls/gtls.rs +++ b/rust/rust_project/src/vtls/gtls.rs @@ -12,3350 +12,3330 @@ * Create: 2022-10-31 * Description: support gnutls backend ******************************************************************************/ - use crate::src::vtls::vtls::*; - use libc; - use rust_ffi::src::ffi_alias::type_alias::*; - use rust_ffi::src::ffi_fun::fun_call::*; - use rust_ffi::src::ffi_struct::struct_define::*; - - static mut gtls_inited: bool = 0 as i32 != 0; - extern "C" fn gtls_push( - mut s: *mut libc::c_void, - mut buf: *const libc::c_void, - mut len: size_t, - ) -> ssize_t { - let mut sock: curl_socket_t = unsafe{*(s as *mut curl_socket_t)}; - #[cfg(not(CURLDEBUG))] - let mut ret: ssize_t = unsafe{send(sock, buf, len, MSG_NOSIGNAL as i32)}; - - #[cfg(CURLDEBUG)] - let mut ret: ssize_t = unsafe{curl_dbg_send( - sock, - buf, - len, - MSG_NOSIGNAL as i32, - 86 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - )}; - return ret; - } - extern "C" fn gtls_pull( - mut s: *mut libc::c_void, - mut buf: *mut libc::c_void, - mut len: size_t, - ) -> ssize_t { - let mut sock: curl_socket_t = unsafe{*(s as *mut curl_socket_t)}; - #[cfg(not(CURLDEBUG))] - let mut ret: ssize_t = unsafe{recv(sock, buf, len, 0 as i32)}; - - #[cfg(CURLDEBUG)] - let mut ret: ssize_t = unsafe{curl_dbg_recv( - sock, - buf, - len, - 0 as i32, - 93 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - )}; - return ret; - } - extern "C" fn gtls_push_ssl( - mut s: *mut libc::c_void, - mut buf: *const libc::c_void, - mut len: size_t, - ) -> ssize_t { - unsafe { - return gnutls_record_send(s as gnutls_session_t, buf, len); - } - } - extern "C" fn gtls_pull_ssl( - mut s: *mut libc::c_void, - mut buf: *mut libc::c_void, - mut len: size_t, - ) -> ssize_t { - unsafe { - return gnutls_record_recv(s as gnutls_session_t, buf, len); - } - } - - /* gtls_init() - * - * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that - * are not thread-safe and thus this function itself is not thread-safe and - * must only be called from within curl_global_init() to keep the thread - * situation under control! - */ - extern "C" fn gtls_init() -> i32 { - - let mut ret: i32 = 1 as i32; - if unsafe{!gtls_inited} { - ret = if unsafe{gnutls_global_init()} != 0 { - 0 as i32 - } else { - 1 as i32 - }; - - // #[cfg(GTLSDEBUG)] - unsafe{gtls_inited = 1 as i32 != 0;} - } - return ret; - } - - extern "C" fn gtls_cleanup() { - - if unsafe{gtls_inited} { - unsafe{gnutls_global_deinit(); - gtls_inited = 0 as i32 != 0;} - } - - } - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - extern "C" fn showtime(mut data: *mut Curl_easy, mut text: *const libc::c_char, mut stamp: time_t) { - let mut buffer: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *const libc::c_char, - }; - let mut tm: *const tm = &mut buffer; - let mut str: [libc::c_char; 96] = [0; 96]; - let mut result: CURLcode = unsafe{Curl_gmtime(stamp, &mut buffer)}; - if result as u64 != 0 { - return; - } - unsafe{ curl_msnprintf( - str.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 96]>() as u64, - b" %s: %s, %02d %s %4d %02d:%02d:%02d GMT\0" as *const u8 as *const libc::c_char, - text, - Curl_wkday[(if (*tm).tm_wday != 0 { - (*tm).tm_wday - 1 as i32 - } else { - 6 as i32 - }) as usize], - (*tm).tm_mday, - Curl_month[(*tm).tm_mon as usize], - (*tm).tm_year + 1900 as i32, - (*tm).tm_hour, - (*tm).tm_min, - (*tm).tm_sec, - ); - Curl_infof( - data, - b"%s\0" as *const u8 as *const libc::c_char, - str.as_mut_ptr(), - );} - - } - extern "C" fn load_file(mut file: *const libc::c_char) -> gnutls_datum_t { - let mut f: *mut FILE = 0 as *mut FILE; - let mut loaded_file: gnutls_datum_t = { - gnutls_datum_t { - data: 0 as *mut u8, - size: 0 as u32, - } - }; - let mut filelen: i64 = 0; - let mut ptr: *mut libc::c_void = 0 as *mut libc::c_void; - unsafe{ - match () { - #[cfg(not(CURLDEBUG))] - _ => { - f = fopen(file, b"rb\0" as *const u8 as *const libc::c_char); - } - #[cfg(CURLDEBUG)] - _ => { - f = curl_dbg_fopen( - file, - b"rb\0" as *const u8 as *const libc::c_char, - 170 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - } - } - } - if f.is_null() { - return loaded_file; - } - unsafe{ - 'out: loop { - if !(fseek(f, 0 as i64, 2 as i32) != 0 as i32 - || { - filelen = ftell(f); - filelen < 0 as i64 - } - || fseek(f, 0 as i64, 0 as i32) != 0 as i32 - || { - match () { - #[cfg(not(CURLDEBUG))] - _ => { - ptr = - Curl_cmalloc.expect("non-null function pointer")(filelen as size_t); - } - #[cfg(CURLDEBUG)] - _ => { - ptr = curl_dbg_malloc( - filelen as size_t, - 176 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - } - } - - ptr.is_null() - }) - { - break 'out; - } - - if fread(ptr, 1 as u64, filelen as size_t, f) < filelen as size_t { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(ptr); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - ptr, - 179 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - - break 'out; - } else { - loaded_file.data = ptr as *mut u8; - loaded_file.size = filelen as u32; - } - - break 'out; - } - } - #[cfg(not(CURLDEBUG))] - unsafe{fclose(f);} - - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_fclose( - f, - 186 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - );} - return loaded_file; - - } - extern "C" fn unload_file(mut data: gnutls_datum_t) { - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(data.data as *mut libc::c_void);} - - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - data.data as *mut libc::c_void, - 192 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - );} - } - - /* this function does a SSL/TLS (re-)handshake */ - extern "C" fn handshake( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut duringconnect: bool, - mut nonblocking: bool, - ) -> CURLcode { - let mut connssl: *mut ssl_connect_data =unsafe{ - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - let mut session: gnutls_session_t = unsafe{(*backend).session}; - let mut sockfd: curl_socket_t = unsafe{(*conn).sock[sockindex as usize]}; - loop { - let mut timeout_ms: timediff_t = 0; - let mut rc: i32 = 0; - /* check allowed time left */ - timeout_ms = unsafe{Curl_timeleft(data, 0 as *mut curltime, duringconnect)}; - if timeout_ms < 0 as i64 { - /* no need to continue if time already is up */ - unsafe{Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - )}; - return CURLE_OPERATION_TIMEDOUT; - } - /* if ssl is expecting something, check if it's available. */ - if unsafe{(*connssl).connecting_state as u32} == ssl_connect_2_reading as u32 - || unsafe{(*connssl).connecting_state as u32} == ssl_connect_2_writing as u32 - { - let mut what: i32 = 0; - let mut writefd: curl_socket_t = - if ssl_connect_2_writing as u32 == unsafe{(*connssl).connecting_state as u32} { - sockfd - } else { - -(1 as i32) - }; - let mut readfd: curl_socket_t = - if ssl_connect_2_reading as u32 == unsafe{(*connssl).connecting_state as u32} { - sockfd - } else { - -(1 as i32) - }; - what = unsafe{Curl_socket_check( - readfd, - -(1 as i32), - writefd, - if nonblocking as i32 != 0 { - 0 as i64 - } else if timeout_ms != 0 { - timeout_ms - } else { - 1000 as i64 - }, - )}; - if what < 0 as i32 { - /* fatal error */ - unsafe{Curl_failf( - data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, - *__errno_location(), - );} - return CURLE_SSL_CONNECT_ERROR; - } else { - if 0 as i32 == what { - if nonblocking { - return CURLE_OK; - } else { - if timeout_ms != 0 { - /* timeout */ - unsafe{Curl_failf( - data, - b"SSL connection timeout at %ld\0" as *const u8 - as *const libc::c_char, - timeout_ms, - );} - return CURLE_OPERATION_TIMEDOUT; - } - } - } - } - /* socket is readable or writable */ - } - rc = unsafe{gnutls_handshake(session)}; - if rc == -(28 as i32) || rc == -(52 as i32) { - unsafe{ - (*connssl).connecting_state = (if gnutls_record_get_direction(session) != 0 { - ssl_connect_2_writing as i32 - } else { - ssl_connect_2_reading as i32 - }) as ssl_connect_state; - } - } else if rc < 0 as i32 && unsafe{gnutls_error_is_fatal(rc) }== 0 { - let mut strerr: *const libc::c_char = 0 as *const libc::c_char; - if rc == -(16 as i32) { - let mut alert: i32 = unsafe{gnutls_alert_get(session) as i32}; - strerr = unsafe{gnutls_alert_get_name(alert as gnutls_alert_description_t)}; - } - if strerr.is_null() { - strerr = unsafe{gnutls_strerror(rc)}; - } - unsafe{Curl_infof( - data, - b"gnutls_handshake() warning: %s\0" as *const u8 as *const libc::c_char, - strerr, - );} - } else { - if rc < 0 as i32 { - let mut strerr_0: *const libc::c_char = 0 as *const libc::c_char; - if rc == -(12 as i32) { - let mut alert_0: i32 = unsafe{gnutls_alert_get(session) as i32}; - strerr_0 = unsafe{gnutls_alert_get_name(alert_0 as gnutls_alert_description_t)}; - } - if strerr_0.is_null() { - strerr_0 = unsafe{gnutls_strerror(rc)}; - } - unsafe{Curl_failf( - data, - b"gnutls_handshake() failed: %s\0" as *const u8 as *const libc::c_char, - strerr_0, - );} - return CURLE_SSL_CONNECT_ERROR; - } - /* Reset our connect state machine */ - unsafe{ (*connssl).connecting_state = ssl_connect_1;} - return CURLE_OK; - } - } - } - extern "C" fn do_file_type(mut type_0: *const libc::c_char) -> gnutls_x509_crt_fmt_t { - if type_0.is_null() || unsafe{*type_0.offset(0 as isize)} == 0 { - return GNUTLS_X509_FMT_PEM; - } - if unsafe{Curl_strcasecompare(type_0, b"PEM\0" as *const u8 as *const libc::c_char)} != 0 { - return GNUTLS_X509_FMT_PEM; - } - if unsafe{Curl_strcasecompare(type_0, b"DER\0" as *const u8 as *const libc::c_char)} != 0 { - return GNUTLS_X509_FMT_DER; - } - return GNUTLS_X509_FMT_PEM; - - } - extern "C" fn set_ssl_version_min_max( - mut data: *mut Curl_easy, - mut prioritylist: *mut *const libc::c_char, - mut tls13support: *const libc::c_char, - ) -> CURLcode { - let mut conn: *mut connectdata = unsafe{(*data).conn}; - #[cfg(not(CURL_DISABLE_PROXY))] - unsafe{let mut ssl_version: i64 = if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.version - } else { - (*conn).ssl_config.version - };} - #[cfg(CURL_DISABLE_PROXY)] - unsafe{let mut ssl_version: i64 = (*conn).ssl_config.version;} - - #[cfg(not(CURL_DISABLE_PROXY))] - unsafe{let mut ssl_version_max: i64 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.version_max - } else { - (*conn).ssl_config.version_max - };} - #[cfg(CURL_DISABLE_PROXY)] - unsafe{let mut ssl_version_max: i64 = (*conn).ssl_config.version_max; - - if ssl_version == CURL_SSLVERSION_DEFAULT as i64 - || ssl_version == CURL_SSLVERSION_TLSv1 as i64 - { - ssl_version = CURL_SSLVERSION_TLSv1_0 as i64; - } - if ssl_version_max == CURL_SSLVERSION_MAX_NONE as i64 { - ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT as i64; - } - if tls13support.is_null() { - /* If the running GnuTLS doesn't support TLS 1.3, we must not specify a - prioritylist involving that since it will make GnuTLS return an en - error back at us */ - if ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3 as i64 - || ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT as i64 - { - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2 as i64; - } - } else if ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT as i64 { - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3 as i64; - } - match ssl_version | ssl_version_max { - 262148 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.0\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 327684 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.0\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 393220 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 327685 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.1\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 393221 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.1\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 393222 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 458759 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 458756 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 458757 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 458758 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3:+VERS-TLS1.2\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - _ => {} - } - Curl_failf( - data, - b"GnuTLS: cannot set ssl protocol\0" as *const u8 as *const libc::c_char, - );} - return CURLE_SSL_CONNECT_ERROR; - - } - - extern "C" fn gtls_connect_step1( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) -> CURLcode { - let mut connssl: *mut ssl_connect_data =unsafe{ - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; - let mut init_flags: u32 = 0; - let mut session: gnutls_session_t = 0 as *mut gnutls_session_int; - let mut rc: i32 = 0; - let mut sni: bool = 1 as i32 != 0; /* default is SNI enabled */ - let mut transport_ptr: *mut libc::c_void = 0 as *mut libc::c_void; - let mut gnutls_transport_push: gnutls_push_func = None; - let mut gnutls_transport_pull: gnutls_pull_func = None; - #[cfg(ENABLE_IPV6)] - let mut addr: in6_addr = in6_addr { - __in6_u: C2RustUnnamed_8 { - __u6_addr8: [0; 16], - }, - }; - // 选项 - 不开启 ENABLE_IPV6 - #[cfg(not(ENABLE_IPV6))] - let mut addr: in_addr = in_addr { s_addr: 0 }; - let mut prioritylist: *const libc::c_char = 0 as *const libc::c_char; - let mut err: *const libc::c_char = 0 as *const libc::c_char; - #[cfg(not(CURL_DISABLE_PROXY))] - let hostname: *const libc::c_char = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).http_proxy.host.name - } else { - (*conn).host.name - }}; - #[cfg(CURL_DISABLE_PROXY)] - let hostname: *const libc::c_char = unsafe{(*conn).host.name}; - - #[cfg(not(CURL_DISABLE_PROXY))] - let certverifyresult: *mut i64 = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - &mut (*data).set.proxy_ssl.certverifyresult - } else { - &mut (*data).set.ssl.certverifyresult - }}; - #[cfg(CURL_DISABLE_PROXY)] - let certverifyresult: *mut i64 =unsafe{ &mut (*data).set.ssl.certverifyresult}; - - let mut tls13support: *const libc::c_char = 0 as *const libc::c_char; - if unsafe{(*connssl).state as u32 == ssl_connection_complete as u32 }{ - /* to make us tolerant against being called more than once for the - same connection */ - return CURLE_OK; - } - if unsafe{ !gtls_inited }{ - gtls_init(); - } - /* Initialize certverifyresult to OK */ - unsafe{*certverifyresult = 0 as i64;} - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_version = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.version - } else { - (*conn).ssl_config.version - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_version = unsafe{(*conn).ssl_config.version}; - if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv2 as i64 { - unsafe{ - Curl_failf( - data, - b"GnuTLS does not support SSLv2\0" as *const u8 as *const libc::c_char, - );} - return CURLE_SSL_CONNECT_ERROR; - } else { - if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv3 as i64 { - sni = 0 as i32 != 0; /* SSLv3 has no SNI */ - } - } - /* allocate a cred struct */ - rc = unsafe{gnutls_certificate_allocate_credentials(&mut (*backend).cred)}; - if rc != 0 as i32 { - unsafe{ Curl_failf( - data, - b"gnutls_cert_all_cred() failed: %s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - );} - return CURLE_SSL_CONNECT_ERROR; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_authtype = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.authtype as u32 - } else { - (*data).set.ssl.authtype as u32 - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_authtype = unsafe{(*data).set.ssl.authtype as u32}; - #[cfg(HAVE_GNUTLS_SRP)] - if SSL_SET_OPTION_authtype == CURL_TLSAUTH_SRP as u32 { - #[cfg(not(CURL_DISABLE_PROXY))] - unsafe{Curl_infof( - data, - b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }, - );} - #[cfg(CURL_DISABLE_PROXY)] - unsafe{Curl_infof( - data, - b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, - (*data).set.ssl.username, - ); - rc = gnutls_srp_allocate_client_credentials(&mut (*backend).srp_client_cred); - if rc != 0 as i32 { - Curl_failf( - data, - b"gnutls_srp_allocate_client_cred() failed: %s\0" as *const u8 - as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_OUT_OF_MEMORY; - }} - #[cfg(not(CURL_DISABLE_PROXY))] - if true { - unsafe{rc = gnutls_srp_set_client_credentials( - (*backend).srp_client_cred, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.password - } else { - (*data).set.ssl.password - }, - ); - } - } - #[cfg(CURL_DISABLE_PROXY)] - if true { - unsafe{ - rc = gnutls_srp_set_client_credentials( - (*backend).srp_client_cred, - (*data).set.ssl.username, - (*data).set.ssl.password, - ); - } - } - if rc != 0 as i32 { - unsafe{Curl_failf( - data, - b"gnutls_srp_set_client_cred() failed: %s\0" as *const u8 - as *const libc::c_char, - gnutls_strerror(rc), - );} - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - #[cfg(not(CURL_DISABLE_PROXY))] - if !if CURLPROXY_HTTPS as u32 == unsafe{(*conn).http_proxy.proxytype as u32} - && ssl_connection_complete as u32 - != unsafe{(*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32} - { - unsafe{(*conn).proxy_ssl_config.CAfile} - } else { - unsafe{(*conn).ssl_config.CAfile} - } - .is_null() - { - unsafe{gnutls_certificate_set_verify_flags((*backend).cred, 0 as u32); - rc = gnutls_certificate_set_x509_trust_file( - (*backend).cred, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - }, - GNUTLS_X509_FMT_PEM, - );} - if rc < 0 as i32 { - unsafe{ - Curl_infof( - data, - b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - }, - gnutls_strerror(rc), - );} - if if CURLPROXY_HTTPS as u32 == unsafe{(*conn).http_proxy.proxytype as u32} - && ssl_connection_complete as u32 - != unsafe{(*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32} - { - unsafe{ ((*conn).proxy_ssl_config).verifypeer() as i32} - } else { - unsafe{((*conn).ssl_config).verifypeer() as i32} - } != 0 - { - unsafe{*certverifyresult = rc as i64;} - return CURLE_SSL_CACERT_BADFILE; - } - } else { - unsafe{Curl_infof( - data, - b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, - rc, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - }, - );} - } - } - // #[cfg(CURL_DISABLE_PROXY)] - if unsafe{!((*conn).ssl_config.CAfile).is_null()} { - /* set the trusted CA cert bundle file */ - unsafe{gnutls_certificate_set_verify_flags((*backend).cred, 0 as u32); - rc = gnutls_certificate_set_x509_trust_file( - (*backend).cred, - (*conn).ssl_config.CAfile, - GNUTLS_X509_FMT_PEM, - );} - if rc < 0 as i32 { - unsafe{Curl_infof( - data, - b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, - (*conn).ssl_config.CAfile, - gnutls_strerror(rc), - );} - if unsafe{((*conn).ssl_config).verifypeer() != 0} { - unsafe{ *certverifyresult = rc as i64;} - return CURLE_SSL_CACERT_BADFILE; - } - } else { - unsafe{Curl_infof( - data, - b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, - rc, - (*conn).ssl_config.CAfile, - );} - } - } - - #[cfg(not(CURL_DISABLE_PROXY))] - if !if CURLPROXY_HTTPS as u32 == unsafe{(*conn).http_proxy.proxytype as u32} - && ssl_connection_complete as u32 - != unsafe{(*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32} - { - unsafe{(*conn).proxy_ssl_config.CApath} - } else { - unsafe{(*conn).ssl_config.CApath} - } - .is_null() - { - rc =unsafe{gnutls_certificate_set_x509_trust_dir( - (*backend).cred, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CApath - } else { - (*conn).ssl_config.CApath - }, - GNUTLS_X509_FMT_PEM, - )}; - if rc < 0 as i32 { - unsafe{Curl_infof( - data, - b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CApath - } else { - (*conn).ssl_config.CApath - }, - gnutls_strerror(rc), - )}; - unsafe{ - if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - } != 0 - { - *certverifyresult = rc as i64; - return CURLE_SSL_CACERT_BADFILE; - }} - } else { - unsafe{Curl_infof( - data, - b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, - rc, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CApath - } else { - (*conn).ssl_config.CApath - }, - );} - } - } - // #[cfg(CURL_DISABLE_PROXY)] - if unsafe{!((*conn).ssl_config.CApath).is_null()} { - /* set the trusted CA cert directory */ - rc = unsafe{gnutls_certificate_set_x509_trust_dir( - (*backend).cred, - (*conn).ssl_config.CApath, - GNUTLS_X509_FMT_PEM, - )}; - if rc < 0 as i32 { - unsafe{Curl_infof( - data, - b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, - (*conn).ssl_config.CApath, - gnutls_strerror(rc), - ); - if ((*conn).ssl_config).verifypeer() != 0 { - *certverifyresult = rc as i64; - return CURLE_SSL_CACERT_BADFILE; - }} - } else { - unsafe{Curl_infof( - data, - b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, - rc, - (*conn).ssl_config.CApath, - );} - } - } - - // todo - 497 - // #[cfg(CURL_CA_FALLBACK)] - #[cfg(not(CURL_DISABLE_PROXY))] - if !if CURLPROXY_HTTPS as u32 == unsafe{(*conn).http_proxy.proxytype as u32} - && unsafe{ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32} - { - unsafe{(*data).set.proxy_ssl.CRLfile} - } else { - unsafe{(*data).set.ssl.CRLfile} - } - .is_null() - { - rc = unsafe{gnutls_certificate_set_x509_crl_file( - (*backend).cred, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - }, - GNUTLS_X509_FMT_PEM, - )}; - if rc < 0 as i32 { - unsafe{Curl_failf( - data, - b"error reading crl file %s (%s)\0" as *const u8 as *const libc::c_char, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - }, - gnutls_strerror(rc), - )}; - return CURLE_SSL_CRL_BADFILE; - } else { - unsafe{Curl_infof( - data, - b"found %d CRL in %s\0" as *const u8 as *const libc::c_char, - rc, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - }, - )}; - } - } - // #[cfg(CURL_DISABLE_PROXY)] - if unsafe{!((*data).set.ssl.CRLfile).is_null()} { - /* set the CRL list file */ - rc = unsafe{gnutls_certificate_set_x509_crl_file( - (*backend).cred, - (*data).set.ssl.CRLfile, - GNUTLS_X509_FMT_PEM, - )}; - if rc < 0 as i32 { - unsafe{Curl_failf( - data, - b"error reading crl file %s (%s)\0" as *const u8 as *const libc::c_char, - (*data).set.ssl.CRLfile, - gnutls_strerror(rc), - );} - return CURLE_SSL_CRL_BADFILE; - } else { - unsafe{Curl_infof( - data, - b"found %d CRL in %s\0" as *const u8 as *const libc::c_char, - rc, - (*data).set.ssl.CRLfile, - );} - } - } - /* Initialize TLS session as a client */ - init_flags = ((1 as i32) << 1 as i32) as u32; - #[cfg(GNUTLS_FORCE_CLIENT_CERT)] - if true { - init_flags |= ((1 as i32) << 9 as i32) as u32; - } - #[cfg(GNUTLS_NO_TICKETS)] - if true { - /* Disable TLS session tickets */ - init_flags |= ((1 as i32) << 10 as i32) as u32; - } - rc = unsafe{gnutls_init(&mut (*backend).session, init_flags)}; - if rc != 0 as i32 { - unsafe{Curl_failf( - data, - b"gnutls_init() failed: %d\0" as *const u8 as *const libc::c_char, - rc, - );} - return CURLE_SSL_CONNECT_ERROR; - } - /* convenient assign */ - session = unsafe{(*backend).session}; - // done - 条件编译 - 542 - #[cfg(ENABLE_IPV6)] - if 0 as i32 - == unsafe{inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in6_addr as *mut libc::c_void, - )} - && 0 as i32 - == unsafe{inet_pton( - 10 as i32, - hostname, - &mut addr as *mut in6_addr as *mut libc::c_void, - )} - && sni as i32 != 0 - && unsafe{gnutls_server_name_set( - session, - GNUTLS_NAME_DNS, - hostname as *const libc::c_void, - strlen(hostname), - ) < 0 as i32} - { - unsafe{ Curl_infof( - data, - b"WARNING: failed to configure server name indication (SNI) TLS extension\0" - as *const u8 as *const libc::c_char, - ); - } - #[cfg(not(ENABLE_IPV6))] - if unsafe{0 as i32 - == inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in_addr as *mut libc::c_void, - ) - && sni as i32 != 0 - && gnutls_server_name_set( - session, - GNUTLS_NAME_DNS, - hostname as *const libc::c_void, - strlen(hostname), - ) < 0 as i32} - { - unsafe{Curl_infof( - data, - b"WARNING: failed to configure server name indication (SNI) TLS extension\0" - as *const u8 as *const libc::c_char, - );} - } - /* Use default priorities */ - rc = unsafe{gnutls_set_default_priority(session)}; - if rc != 0 as i32 { - return CURLE_SSL_CONNECT_ERROR; - } - /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */ - tls13support = unsafe{gnutls_check_version(b"3.6.5\0" as *const u8 as *const libc::c_char)}; - /* Ensure +SRP comes at the *end* of all relevant strings so that it can be - * removed if a run-time error indicates that SRP is not supported by this - * GnuTLS version */ - unsafe{ - match SSL_CONN_CONFIG_version { - 7 => { - if tls13support.is_null() { - Curl_failf( - data, - b"This GnuTLS installation does not support TLS 1.3\0" as *const u8 - as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } - } - 0 | 1 | 4 | 5 | 6 => {} - 2 | 3 | _ => { - Curl_failf( - data, - b"GnuTLS does not support SSLv2 or SSLv3\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } - } - } - let mut result: CURLcode = set_ssl_version_min_max(data, &mut prioritylist, tls13support); - if result as u64 != 0 { - return result; - } - /* Only add SRP to the cipher list if SRP is requested. Otherwise - * GnuTLS will disable TLS 1.3 support. */ - #[cfg(HAVE_GNUTLS_SRP)] - if SSL_SET_OPTION_authtype as u32 == CURL_TLSAUTH_SRP as i32 as u32 { - let mut len: size_t = unsafe{strlen(prioritylist)}; - #[cfg(not(CURLDEBUG))] - let mut prioritysrp: *mut libc::c_char = unsafe{Curl_cmalloc - .expect("non-null function pointer")( - len.wrapping_add(::std::mem::size_of::<[libc::c_char; 5]>() as u64) - .wrapping_add(1 as u64), - ) as *mut libc::c_char}; - #[cfg(CURLDEBUG)] - let mut prioritysrp: *mut libc::c_char = unsafe{curl_dbg_malloc( - len.wrapping_add(::std::mem::size_of::<[libc::c_char; 5]>() as u64) - .wrapping_add(1 as u64), - 591 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char}; - if prioritysrp.is_null() { - return CURLE_OUT_OF_MEMORY; - } - unsafe{strcpy(prioritysrp, prioritylist); - strcpy( - prioritysrp.offset(len as isize), - b":+SRP\0" as *const u8 as *const libc::c_char, - ); - rc = gnutls_priority_set_direct(session, prioritysrp, &mut err);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(prioritysrp as *mut libc::c_void);} - - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - prioritysrp as *mut libc::c_void, - 597 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - );} - if rc == -(50 as i32) && !err.is_null() { - unsafe{Curl_infof( - data, - b"This GnuTLS does not support SRP\0" as *const u8 as *const libc::c_char, - );} - } - } else { - unsafe{Curl_infof( - data, - b"GnuTLS ciphers: %s\0" as *const u8 as *const libc::c_char, - prioritylist, - );} - rc = unsafe{gnutls_priority_set_direct(session, prioritylist, &mut err)}; - } - #[cfg(not(HAVE_GNUTLS_SRP))] - if true { - unsafe{Curl_infof( - data, - b"GnuTLS ciphers: %s\0" as *const u8 as *const libc::c_char, - prioritylist, - ); - rc = gnutls_priority_set_direct(session, prioritylist, &mut err);} - } - if rc != 0 as i32 { - unsafe{Curl_failf( - data, - b"Error %d setting GnuTLS cipher list starting with %s\0" as *const u8 - as *const libc::c_char, - rc, - err, - );} - return CURLE_SSL_CONNECT_ERROR; - } - if unsafe{((*conn).bits).tls_enable_alpn() != 0 }{ - let mut cur: i32 = 0 as i32; - let mut protocols: [gnutls_datum_t; 2] = [gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; 2]; - // done - 623 - #[cfg(not(CURL_DISABLE_PROXY))] - let CURL_DISABLE_PROXY_flag = unsafe{(!(CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32) - || ((*conn).bits).tunnel_proxy() == 0)}; - - #[cfg(CURL_DISABLE_PROXY)] - let CURL_DISABLE_PROXY_flag = true; - #[cfg(USE_HTTP2)] - if unsafe{(*data).state.httpwant as i32} >= CURL_HTTP_VERSION_2_0 as i32 - && CURL_DISABLE_PROXY_flag - { - protocols[cur as usize].data = - b"h2\0" as *const u8 as *const libc::c_char as *mut u8; - protocols[cur as usize].size = 2 as u32; - cur += 1; - unsafe{Curl_infof( - data, - b"ALPN, offering %.*s\0" as *const u8 as *const libc::c_char, - 2 as i32, - b"h2\0" as *const u8 as *const libc::c_char, - );} - } - protocols[cur as usize].data = - b"http/1.1\0" as *const u8 as *const libc::c_char as *mut u8; - protocols[cur as usize].size = 8 as u32; - cur += 1; - unsafe{ Curl_infof( - data, - b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, - b"http/1.1\0" as *const u8 as *const libc::c_char, - ); - gnutls_alpn_set_protocols(session, protocols.as_mut_ptr(), cur as u32, 0 as u32);}} - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_clientcert = if CURLPROXY_HTTPS as u32 - == unsafe{(*conn).http_proxy.proxytype as u32} - && ssl_connection_complete as u32 - != unsafe{(*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32} - { - unsafe{(*data).set.proxy_ssl.primary.clientcert} - } else { - unsafe{(*data).set.ssl.primary.clientcert} - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_clientcert = (*data).set.ssl.primary.clientcert; - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_key_passwd = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key_passwd - } else { - (*data).set.ssl.key_passwd - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_key_passwd = unsafe{(*data).set.ssl.key_passwd}; - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_key = unsafe{if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key - } else { - (*data).set.ssl.key - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_key = unsafe{(*data).set.ssl.key}; - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_cert_type = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.cert_type - } else { - (*data).set.ssl.cert_type - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_cert_type = unsafe{(*data).set.ssl.cert_type}; - unsafe{ - if !SSL_SET_OPTION_primary_clientcert.is_null() { - if !SSL_SET_OPTION_key_passwd.is_null() { - let supported_key_encryption_algorithms: u32 = (GNUTLS_PKCS_PKCS12_3DES as i32 - | GNUTLS_PKCS_PKCS12_ARCFOUR as i32 - | GNUTLS_PKCS_PKCS12_RC2_40 as i32 - | GNUTLS_PKCS_PBES2_3DES as i32 - | GNUTLS_PKCS_PBES2_AES_128 as i32 - | GNUTLS_PKCS_PBES2_AES_192 as i32 - | GNUTLS_PKCS_PBES2_AES_256 as i32) - as u32; - rc = gnutls_certificate_set_x509_key_file2( - (*backend).cred, - SSL_SET_OPTION_primary_clientcert, - if !SSL_SET_OPTION_key.is_null() { - SSL_SET_OPTION_key - } else { - SSL_SET_OPTION_primary_clientcert - }, - do_file_type(SSL_SET_OPTION_cert_type), - SSL_SET_OPTION_key_passwd, - supported_key_encryption_algorithms, - ); - if rc != 0 as i32 { - Curl_failf( - data, - b"error reading X.509 potentially-encrypted key file: %s\0" as *const u8 - as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_SSL_CONNECT_ERROR; - } - } else if gnutls_certificate_set_x509_key_file( - (*backend).cred, - SSL_SET_OPTION_primary_clientcert, - if !(SSL_SET_OPTION_key).is_null() { - SSL_SET_OPTION_key - } else { - SSL_SET_OPTION_primary_clientcert - }, - do_file_type(SSL_SET_OPTION_cert_type), - ) != 0 as i32 - { - Curl_failf( - data, - b"error reading X.509 key or certificate file\0" as *const u8 - as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } - - } - } - /* put the credentials to the current session */ - #[cfg(HAVE_GNUTLS_SRP)] - if SSL_SET_OPTION_authtype == CURL_TLSAUTH_SRP as u32 { - rc = unsafe{gnutls_credentials_set( - session, - GNUTLS_CRD_SRP, - (*backend).srp_client_cred as *mut libc::c_void, - )}; - if rc != 0 as i32 { - unsafe{ - Curl_failf( - data, - b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_SSL_CONNECT_ERROR; - }} - } else { - rc = unsafe{gnutls_credentials_set( - session, - GNUTLS_CRD_CERTIFICATE, - (*backend).cred as *mut libc::c_void, - )}; - if rc != 0 as i32 { - unsafe{Curl_failf( - data, - b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - );} - return CURLE_SSL_CONNECT_ERROR; - } - } - #[cfg(not(HAVE_GNUTLS_SRP))] - if true { - rc = unsafe{gnutls_credentials_set( - session, - GNUTLS_CRD_CERTIFICATE, - (*backend).cred as *mut libc::c_void, - )}; - if rc != 0 as i32 { - unsafe{Curl_failf( - data, - b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - );} - return CURLE_SSL_CONNECT_ERROR; - } - } - - #[cfg(not(CURL_DISABLE_PROXY))] - if unsafe{((*conn).proxy_ssl[sockindex as usize]).use_0()} != 0 { - unsafe{ - transport_ptr = - (*(*conn).proxy_ssl[sockindex as usize].backend).session as *mut libc::c_void; - gnutls_transport_push = Some( - gtls_push_ssl - as unsafe extern "C" fn( - *mut libc::c_void, - *const libc::c_void, - size_t, - ) -> ssize_t, - ); - gnutls_transport_pull = Some( - gtls_pull_ssl - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_void, - size_t, - ) -> ssize_t, - );} - } else { - unsafe{ - transport_ptr = &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) - as *mut curl_socket_t as *mut libc::c_void; - gnutls_transport_push = Some( - gtls_push - as unsafe extern "C" fn( - *mut libc::c_void, - *const libc::c_void, - size_t, - ) -> ssize_t, - ); - gnutls_transport_pull = Some( - gtls_pull - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_void, - size_t, - ) -> ssize_t, - );} - } - #[cfg(CURL_DISABLE_PROXY)] - if true { - unsafe{ - /* file descriptor for the socket */ - transport_ptr = &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) - as *mut curl_socket_t as *mut libc::c_void; - gnutls_transport_push = Some( - gtls_push - as unsafe extern "C" fn( - *mut libc::c_void, - *const libc::c_void, - size_t, - ) -> ssize_t, - ); - gnutls_transport_pull = Some( - gtls_pull - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_void, - size_t, - ) -> ssize_t, - ); - } - } - unsafe{ - /* set the connection handle */ - gnutls_transport_set_ptr(session, transport_ptr); - /* register callback functions to send and receive data. */ - gnutls_transport_set_push_function(session, gnutls_transport_push); - gnutls_transport_set_pull_function(session, gnutls_transport_pull);} - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifystatus = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifystatus() as i32 - } else { - ((*conn).ssl_config).verifystatus() as i32 - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifystatus = ((*conn).ssl_config).verifystatus(); - if SSL_CONN_CONFIG_verifystatus != 0 { - rc = unsafe{gnutls_ocsp_status_request_enable_client( - session, - 0 as *mut gnutls_datum_t, - 0 as size_t, - 0 as *mut gnutls_datum_t, - )}; - if rc != 0 as i32 { - unsafe{ Curl_failf( - data, - b"gnutls_ocsp_status_request_enable_client() failed: %d\0" as *const u8 - as *const libc::c_char, - rc, - );} - return CURLE_SSL_CONNECT_ERROR; - } - } - /* This might be a reconnect, so we check for a session ID in the cache - to speed up things */ - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*data).set.proxy_ssl.primary).sessionid() as i32 - } else { - ((*data).set.ssl.primary).sessionid() as i32 - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = unsafe{((*data).set.ssl.primary).sessionid()}; - unsafe{ - if SSL_SET_OPTION_primary_sessionid != 0 { - let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - let mut ssl_idsize: size_t = 0; - Curl_ssl_sessionid_lock(data); - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_IS_PROXY_void_1 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - 1 as i32 - } else { - 0 as i32 - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_IS_PROXY_void_1 = if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0; - if !Curl_ssl_getsessionid( - data, - conn, - SSL_IS_PROXY_void_1, - &mut ssl_sessionid, - &mut ssl_idsize, - sockindex, - ) { - /* we got a session id, use it! */ - gnutls_session_set_data(session, ssl_sessionid, ssl_idsize); - /* Informational message */ - Curl_infof( - data, - b"SSL re-using session ID\0" as *const u8 as *const libc::c_char, - ); - } - Curl_ssl_sessionid_unlock(data); - } - } - return CURLE_OK; - - } - extern "C" fn pkp_pin_peer_pubkey( - mut data: *mut Curl_easy, - mut cert: gnutls_x509_crt_t, - mut pinnedpubkey: *const libc::c_char, - ) -> CURLcode { - /* Scratch */ - let mut len1: size_t = 0 as size_t; - let mut len2: size_t = 0 as size_t; - let mut buff1: *mut u8 = 0 as *mut u8; - let mut key: gnutls_pubkey_t = 0 as gnutls_pubkey_t; - /* Result is returned to caller */ - let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - /* if a path wasn't specified, don't pin */ - if pinnedpubkey.is_null() { - return CURLE_OK; - } - if cert.is_null() { - return result; - } - let mut ret: i32 = 0; - /* Begin Gyrations to get the public key */ - unsafe{gnutls_pubkey_init(&mut key); - ret = gnutls_pubkey_import_x509(key, cert, 0 as u32);} - if !(ret < 0 as i32) { - ret = unsafe{gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, 0 as *mut libc::c_void, &mut len1)}; - if !(ret != -(51 as i32) || len1 == 0 as u64) { - unsafe{ - match () { - #[cfg(not(CURLDEBUG))] - _ => { - buff1 = Curl_cmalloc.expect("non-null function pointer")(len1) as *mut u8; - } - #[cfg(CURLDEBUG)] - _ => { - buff1 = curl_dbg_malloc( - len1, - 785 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ) as *mut u8; - } - } +use crate::src::vtls::vtls::*; +use libc; +use rust_ffi::src::ffi_alias::type_alias::*; +use rust_ffi::src::ffi_fun::fun_call::*; +use rust_ffi::src::ffi_struct::struct_define::*; + +static mut gtls_inited: bool = 0 as i32 != 0; +extern "C" fn gtls_push( + mut s: *mut libc::c_void, + mut buf: *const libc::c_void, + mut len: size_t, +) -> ssize_t { + let mut sock: curl_socket_t =unsafe{ *(s as *mut curl_socket_t)}; + #[cfg(not(CURLDEBUG))] + let mut ret: ssize_t =unsafe{ send(sock, buf, len, MSG_NOSIGNAL as i32)}; + + #[cfg(CURLDEBUG)] + let mut ret: ssize_t =unsafe{ curl_dbg_send( + sock, + buf, + len, + MSG_NOSIGNAL as i32, + 86 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + )}; + return ret; + +} +extern "C" fn gtls_pull( + mut s: *mut libc::c_void, + mut buf: *mut libc::c_void, + mut len: size_t, +) -> ssize_t { + let mut sock: curl_socket_t =unsafe{ *(s as *mut curl_socket_t)}; + #[cfg(not(CURLDEBUG))] + let mut ret: ssize_t =unsafe{ recv(sock, buf, len, 0 as i32)}; + + #[cfg(CURLDEBUG)] + let mut ret: ssize_t =unsafe{ curl_dbg_recv( + sock, + buf, + len, + 0 as i32, + 93 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + )}; + return ret; +} +extern "C" fn gtls_push_ssl( + mut s: *mut libc::c_void, + mut buf: *const libc::c_void, + mut len: size_t, +) -> ssize_t { + unsafe { + return gnutls_record_send(s as gnutls_session_t, buf, len); + } +} +extern "C" fn gtls_pull_ssl( + mut s: *mut libc::c_void, + mut buf: *mut libc::c_void, + mut len: size_t, +) -> ssize_t { + unsafe { + return gnutls_record_recv(s as gnutls_session_t, buf, len); + } +} + +/* gtls_init() + * + * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that + * are not thread-safe and thus this function itself is not thread-safe and + * must only be called from within curl_global_init() to keep the thread + * situation under control! + */ +extern "C" fn gtls_init() -> i32 { + let mut ret: i32 = 1 as i32; + if unsafe{ !gtls_inited} { + ret =unsafe{ if gnutls_global_init() != 0 { + 0 as i32 + } else { + 1 as i32 + }}; + + // #[cfg(GTLSDEBUG)] + unsafe{ gtls_inited = 1 as i32 != 0;} + } + return ret; +} + +extern "C" fn gtls_cleanup() { + unsafe { + if gtls_inited { + gnutls_global_deinit(); + gtls_inited = 0 as i32 != 0; + } + } +} +#[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] +extern "C" fn showtime(mut data: *mut Curl_easy, mut text: *const libc::c_char, mut stamp: time_t) { + let mut buffer: tm = tm { + tm_sec: 0, + tm_min: 0, + tm_hour: 0, + tm_mday: 0, + tm_mon: 0, + tm_year: 0, + tm_wday: 0, + tm_yday: 0, + tm_isdst: 0, + tm_gmtoff: 0, + tm_zone: 0 as *const libc::c_char, + }; + let mut tm: *const tm = &mut buffer; + let mut str: [libc::c_char; 96] = [0; 96]; + let mut result: CURLcode =unsafe{ Curl_gmtime(stamp, &mut buffer)}; + if result as u64 != 0 { + return; + } + unsafe{ curl_msnprintf( + str.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 96]>() as u64, + b" %s: %s, %02d %s %4d %02d:%02d:%02d GMT\0" as *const u8 as *const libc::c_char, + text, + Curl_wkday[(if (*tm).tm_wday != 0 { + (*tm).tm_wday - 1 as i32 + } else { + 6 as i32 + }) as usize], + (*tm).tm_mday, + Curl_month[(*tm).tm_mon as usize], + (*tm).tm_year + 1900 as i32, + (*tm).tm_hour, + (*tm).tm_min, + (*tm).tm_sec, + ); + Curl_infof( + data, + b"%s\0" as *const u8 as *const libc::c_char, + str.as_mut_ptr(), + );} + +} +extern "C" fn load_file(mut file: *const libc::c_char) -> gnutls_datum_t { + let mut f: *mut FILE = 0 as *mut FILE; + let mut loaded_file: gnutls_datum_t =unsafe{ { + gnutls_datum_t { + data: 0 as *mut u8, + size: 0 as u32, + } + }}; + let mut filelen: i64 = 0; + let mut ptr: *mut libc::c_void = 0 as *mut libc::c_void; + unsafe{ + match () { + #[cfg(not(CURLDEBUG))] + _ => { + f = fopen(file, b"rb\0" as *const u8 as *const libc::c_char); + } + #[cfg(CURLDEBUG)] + _ => { + f = curl_dbg_fopen( + file, + b"rb\0" as *const u8 as *const libc::c_char, + 170 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + } + } + + if f.is_null() { + return loaded_file; + } + 'out: loop { + if !(fseek(f, 0 as i64, 2 as i32) != 0 as i32 + || { + filelen = ftell(f); + filelen < 0 as i64 + } + || fseek(f, 0 as i64, 0 as i32) != 0 as i32 + || { + match () { + #[cfg(not(CURLDEBUG))] + _ => { + ptr = + Curl_cmalloc.expect("non-null function pointer")(filelen as size_t); + } + #[cfg(CURLDEBUG)] + _ => { + ptr = curl_dbg_malloc( + filelen as size_t, + 176 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + } + } + + ptr.is_null() + }) + { + break 'out; + } + + if fread(ptr, 1 as u64, filelen as size_t, f) < filelen as size_t { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(ptr); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + ptr, + 179 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + + break 'out; + } else { + loaded_file.data = ptr as *mut u8; + loaded_file.size = filelen as u32; + } + + break 'out; + } + } + #[cfg(not(CURLDEBUG))] + unsafe{ fclose(f);} + + #[cfg(CURLDEBUG)] + unsafe{ curl_dbg_fclose( + f, + 186 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + );} + return loaded_file; + +} +extern "C" fn unload_file(mut data: gnutls_datum_t) { + unsafe { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(data.data as *mut libc::c_void); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + data.data as *mut libc::c_void, + 192 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + } +} + +/* this function does a SSL/TLS (re-)handshake */ +extern "C" fn handshake( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut duringconnect: bool, + mut nonblocking: bool, +) -> CURLcode { + + let mut connssl: *mut ssl_connect_data =unsafe{ + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; + let mut session: gnutls_session_t =unsafe{ (*backend).session}; + let mut sockfd: curl_socket_t =unsafe{ (*conn).sock[sockindex as usize]}; + unsafe{ + loop { + let mut timeout_ms: timediff_t = 0; + let mut rc: i32 = 0; + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, 0 as *mut curltime, duringconnect); + if timeout_ms < 0 as i64 { + /* no need to continue if time already is up */ + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OPERATION_TIMEDOUT; + } + /* if ssl is expecting something, check if it's available. */ + if (*connssl).connecting_state as u32 == ssl_connect_2_reading as u32 + || (*connssl).connecting_state as u32 == ssl_connect_2_writing as u32 + { + let mut what: i32 = 0; + let mut writefd: curl_socket_t = + if ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 { + sockfd + } else { + -(1 as i32) + }; + let mut readfd: curl_socket_t = + if ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 { + sockfd + } else { + -(1 as i32) + }; + what = Curl_socket_check( + readfd, + -(1 as i32), + writefd, + if nonblocking as i32 != 0 { + 0 as i64 + } else if timeout_ms != 0 { + timeout_ms + } else { + 1000 as i64 + }, + ); + if what < 0 as i32 { + /* fatal error */ + Curl_failf( + data, + b"select/poll on SSL socket, errno: %d\0" as *const u8 + as *const libc::c_char, + *__errno_location(), + ); + return CURLE_SSL_CONNECT_ERROR; + } else { + if 0 as i32 == what { + if nonblocking { + return CURLE_OK; + } else { + if timeout_ms != 0 { + /* timeout */ + Curl_failf( + data, + b"SSL connection timeout at %ld\0" as *const u8 + as *const libc::c_char, + timeout_ms, + ); + return CURLE_OPERATION_TIMEDOUT; + } + } + } + } + /* socket is readable or writable */ + } + rc = gnutls_handshake(session); + if rc == -(28 as i32) || rc == -(52 as i32) { + (*connssl).connecting_state = (if gnutls_record_get_direction(session) != 0 { + ssl_connect_2_writing as i32 + } else { + ssl_connect_2_reading as i32 + }) as ssl_connect_state; + } else if rc < 0 as i32 && gnutls_error_is_fatal(rc) == 0 { + let mut strerr: *const libc::c_char = 0 as *const libc::c_char; + if rc == -(16 as i32) { + let mut alert: i32 = gnutls_alert_get(session) as i32; + strerr = gnutls_alert_get_name(alert as gnutls_alert_description_t); + } + if strerr.is_null() { + strerr = gnutls_strerror(rc); + } + Curl_infof( + data, + b"gnutls_handshake() warning: %s\0" as *const u8 as *const libc::c_char, + strerr, + ); + } else { + if rc < 0 as i32 { + let mut strerr_0: *const libc::c_char = 0 as *const libc::c_char; + if rc == -(12 as i32) { + let mut alert_0: i32 = gnutls_alert_get(session) as i32; + strerr_0 = gnutls_alert_get_name(alert_0 as gnutls_alert_description_t); + } + if strerr_0.is_null() { + strerr_0 = gnutls_strerror(rc); + } + Curl_failf( + data, + b"gnutls_handshake() failed: %s\0" as *const u8 as *const libc::c_char, + strerr_0, + ); + return CURLE_SSL_CONNECT_ERROR; + } + /* Reset our connect state machine */ + (*connssl).connecting_state = ssl_connect_1; + return CURLE_OK; + } + } + } +} +extern "C" fn do_file_type(mut type_0: *const libc::c_char) -> gnutls_x509_crt_fmt_t { + unsafe { + if type_0.is_null() || *type_0.offset(0 as isize) == 0 { + return GNUTLS_X509_FMT_PEM; + } + if Curl_strcasecompare(type_0, b"PEM\0" as *const u8 as *const libc::c_char) != 0 { + return GNUTLS_X509_FMT_PEM; + } + if Curl_strcasecompare(type_0, b"DER\0" as *const u8 as *const libc::c_char) != 0 { + return GNUTLS_X509_FMT_DER; + } + return GNUTLS_X509_FMT_PEM; + } +} +extern "C" fn set_ssl_version_min_max( + mut data: *mut Curl_easy, + mut prioritylist: *mut *const libc::c_char, + mut tls13support: *const libc::c_char, +) -> CURLcode { + unsafe{ + let mut conn: *mut connectdata = (*data).conn; + #[cfg(not(CURL_DISABLE_PROXY))] + let mut ssl_version: i64 = if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.version + } else { + (*conn).ssl_config.version + }; + #[cfg(CURL_DISABLE_PROXY)] + let mut ssl_version: i64 = (*conn).ssl_config.version; + + #[cfg(not(CURL_DISABLE_PROXY))] + let mut ssl_version_max: i64 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.version_max + } else { + (*conn).ssl_config.version_max + }; + #[cfg(CURL_DISABLE_PROXY)] + let mut ssl_version_max: i64 = (*conn).ssl_config.version_max; + + if ssl_version == CURL_SSLVERSION_DEFAULT as i64 + || ssl_version == CURL_SSLVERSION_TLSv1 as i64 + { + ssl_version = CURL_SSLVERSION_TLSv1_0 as i64; + } + if ssl_version_max == CURL_SSLVERSION_MAX_NONE as i64 { + ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT as i64; + } + if tls13support.is_null() { + /* If the running GnuTLS doesn't support TLS 1.3, we must not specify a + prioritylist involving that since it will make GnuTLS return an en + error back at us */ + if ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3 as i64 + || ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT as i64 + { + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2 as i64; + } + } else if ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT as i64 { + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3 as i64; + } + match ssl_version | ssl_version_max { + 262148 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.0\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 327684 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.0\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 393220 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 327685 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.1\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 393221 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.1\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 393222 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 458759 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 458756 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 458757 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 458758 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3:+VERS-TLS1.2\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + _ => {} + } + Curl_failf( + data, + b"GnuTLS: cannot set ssl protocol\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } +} + +extern "C" fn gtls_connect_step1( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + unsafe { + let mut connssl: *mut ssl_connect_data = + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; + let mut backend: *mut ssl_backend_data = (*connssl).backend; + let mut init_flags: u32 = 0; + let mut session: gnutls_session_t = 0 as *mut gnutls_session_int; + let mut rc: i32 = 0; + let mut sni: bool = 1 as i32 != 0; /* default is SNI enabled */ + let mut transport_ptr: *mut libc::c_void = 0 as *mut libc::c_void; + let mut gnutls_transport_push: gnutls_push_func = None; + let mut gnutls_transport_pull: gnutls_pull_func = None; + #[cfg(ENABLE_IPV6)] + let mut addr: in6_addr = in6_addr { + __in6_u: C2RustUnnamed_8 { + __u6_addr8: [0; 16], + }, + }; + // 选项 - 不开启 ENABLE_IPV6 + #[cfg(not(ENABLE_IPV6))] + let mut addr: in_addr = in_addr { s_addr: 0 }; + let mut prioritylist: *const libc::c_char = 0 as *const libc::c_char; + let mut err: *const libc::c_char = 0 as *const libc::c_char; + #[cfg(not(CURL_DISABLE_PROXY))] + let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).http_proxy.host.name + } else { + (*conn).host.name + }; + #[cfg(CURL_DISABLE_PROXY)] + let hostname: *const libc::c_char = (*conn).host.name; + + #[cfg(not(CURL_DISABLE_PROXY))] + let certverifyresult: *mut i64 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + &mut (*data).set.proxy_ssl.certverifyresult + } else { + &mut (*data).set.ssl.certverifyresult + }; + #[cfg(CURL_DISABLE_PROXY)] + let certverifyresult: *mut i64 = &mut (*data).set.ssl.certverifyresult; + + let mut tls13support: *const libc::c_char = 0 as *const libc::c_char; + if (*connssl).state as u32 == ssl_connection_complete as u32 { + /* to make us tolerant against being called more than once for the + same connection */ + return CURLE_OK; + } + if !gtls_inited { + gtls_init(); + } + /* Initialize certverifyresult to OK */ + *certverifyresult = 0 as i64; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_version = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.version + } else { + (*conn).ssl_config.version + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_version = (*conn).ssl_config.version; + if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv2 as i64 { + Curl_failf( + data, + b"GnuTLS does not support SSLv2\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } else { + if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv3 as i64 { + sni = 0 as i32 != 0; /* SSLv3 has no SNI */ + } + } + /* allocate a cred struct */ + rc = gnutls_certificate_allocate_credentials(&mut (*backend).cred); + if rc != 0 as i32 { + Curl_failf( + data, + b"gnutls_cert_all_cred() failed: %s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_SSL_CONNECT_ERROR; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_authtype = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.authtype as u32 + } else { + (*data).set.ssl.authtype as u32 + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_authtype = (*data).set.ssl.authtype as u32; + #[cfg(HAVE_GNUTLS_SRP)] + if SSL_SET_OPTION_authtype == CURL_TLSAUTH_SRP as u32 { + #[cfg(not(CURL_DISABLE_PROXY))] + Curl_infof( + data, + b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }, + ); + #[cfg(CURL_DISABLE_PROXY)] + Curl_infof( + data, + b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, + (*data).set.ssl.username, + ); + rc = gnutls_srp_allocate_client_credentials(&mut (*backend).srp_client_cred); + if rc != 0 as i32 { + Curl_failf( + data, + b"gnutls_srp_allocate_client_cred() failed: %s\0" as *const u8 + as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_OUT_OF_MEMORY; + } + #[cfg(not(CURL_DISABLE_PROXY))] + if true { + rc = gnutls_srp_set_client_credentials( + (*backend).srp_client_cred, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.password + } else { + (*data).set.ssl.password + }, + ); + } + #[cfg(CURL_DISABLE_PROXY)] + if true { + rc = gnutls_srp_set_client_credentials( + (*backend).srp_client_cred, + (*data).set.ssl.username, + (*data).set.ssl.password, + ); + } + if rc != 0 as i32 { + Curl_failf( + data, + b"gnutls_srp_set_client_cred() failed: %s\0" as *const u8 + as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + } + #[cfg(not(CURL_DISABLE_PROXY))] + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + } + .is_null() + { + gnutls_certificate_set_verify_flags((*backend).cred, 0 as u32); + rc = gnutls_certificate_set_x509_trust_file( + (*backend).cred, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + }, + GNUTLS_X509_FMT_PEM, + ); + if rc < 0 as i32 { + Curl_infof( + data, + b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + }, + gnutls_strerror(rc), + ); + if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + } != 0 + { + *certverifyresult = rc as i64; + return CURLE_SSL_CACERT_BADFILE; + } + } else { + Curl_infof( + data, + b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, + rc, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + }, + ); + } + } + #[cfg(CURL_DISABLE_PROXY)] + if !((*conn).ssl_config.CAfile).is_null() { + /* set the trusted CA cert bundle file */ + gnutls_certificate_set_verify_flags((*backend).cred, 0 as u32); + rc = gnutls_certificate_set_x509_trust_file( + (*backend).cred, + (*conn).ssl_config.CAfile, + GNUTLS_X509_FMT_PEM, + ); + if rc < 0 as i32 { + Curl_infof( + data, + b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, + (*conn).ssl_config.CAfile, + gnutls_strerror(rc), + ); + if ((*conn).ssl_config).verifypeer() != 0 { + *certverifyresult = rc as i64; + return CURLE_SSL_CACERT_BADFILE; } - if !buff1.is_null() { - len2 = len1; - ret = unsafe{gnutls_pubkey_export( - key, - GNUTLS_X509_FMT_DER, - buff1 as *mut libc::c_void, - &mut len2, - )}; - if !(ret < 0 as i32 || len1 != len2) { - /* End Gyrations */ - - /* The one good exit point */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); - } - } - } - } - if !key.is_null() { - unsafe{ gnutls_pubkey_deinit(key);} - } - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void);} - - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - buff1 as *mut libc::c_void, - 804 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - );} - buff1 = 0 as *mut u8; - return result; - - } - - extern "C" fn gtls_connect_step3( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) -> CURLcode { - let mut cert_list_size: u32 = 0; - let mut chainp: *const gnutls_datum_t = 0 as *const gnutls_datum_t; - let mut verify_status: u32 = 0 as u32; - let mut x509_cert: gnutls_x509_crt_t = 0 as *mut gnutls_x509_crt_int; - let mut x509_issuer: gnutls_x509_crt_t = 0 as *mut gnutls_x509_crt_int; - let mut issuerp: gnutls_datum_t = gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; - let mut certfields: gnutls_datum_t = gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; - let mut certname: [libc::c_char; 65] =unsafe{ *::std::mem::transmute::< - &[u8; 65], - &mut [libc::c_char; 65], - >( - b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - )}; /* limited to 64 chars by ASN.1 */ - let mut size: size_t = 0; - let mut certclock: time_t = 0; - let mut ptr: *const libc::c_char = 0 as *const libc::c_char; - let mut connssl: *mut ssl_connect_data = - unsafe{&mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - let mut session: gnutls_session_t =unsafe{ (*backend).session}; - let mut rc: i32 = 0; - let mut proto: gnutls_datum_t = gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; - let mut result: CURLcode = CURLE_OK; - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - let mut algo: u32 = 0; - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - let mut bits: u32 = 0; - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - let mut version: gnutls_protocol_t = unsafe{gnutls_protocol_get_version(session)}; - #[cfg(not(CURL_DISABLE_PROXY))] - let hostname: *const libc::c_char = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).http_proxy.host.name - } else { - (*conn).host.name - }}; - #[cfg(CURL_DISABLE_PROXY)] - let hostname: *const libc::c_char = unsafe{(*conn).host.name}; - - #[cfg(not(CURL_DISABLE_PROXY))] - let certverifyresult: *mut i64 = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - &mut (*data).set.proxy_ssl.certverifyresult - } else { - &mut (*data).set.ssl.certverifyresult - }}; - #[cfg(CURL_DISABLE_PROXY)] - let certverifyresult: *mut i64 =unsafe{ &mut (*data).set.ssl.certverifyresult}; - /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ - ptr = unsafe{gnutls_cipher_suite_get_name( - gnutls_kx_get(session), - gnutls_cipher_get(session), - gnutls_mac_get(session), - )}; - unsafe{Curl_infof( - data, - b"SSL connection using %s / %s\0" as *const u8 as *const libc::c_char, - gnutls_protocol_get_name(version), - ptr, - );} - - /* This function will return the peer's raw certificate (chain) as sent by - the peer. These certificates are in raw format (DER encoded for - X.509). In case of a X.509 then a certificate list may be present. The - first certificate in the list is the peer's certificate, following the - issuer's certificate, then the issuer's issuer etc. */ - chainp = unsafe{gnutls_certificate_get_peers(session, &mut cert_list_size)}; - unsafe{ - #[cfg(not(CURL_DISABLE_PROXY))] - if chainp.is_null() { - if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - }) != 0 - || (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifyhost() as i32 - } else { - ((*conn).ssl_config).verifyhost() as i32 - }) != 0 - || !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - }) - .is_null() - { - #[cfg(HAVE_GNUTLS_SRP)] - if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.authtype as u32 - } else { - (*data).set.ssl.authtype as u32 - }) == CURL_TLSAUTH_SRP as u32 - && !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }) - .is_null() - && (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - }) == 0 - && gnutls_cipher_get(session) as u32 != 0 - { - /* no peer cert, but auth is ok if we have SRP user and cipher and no - peer verify */ - } else { - Curl_failf( - data, - b"failed to get server cert\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = -(49 as i32) as i64; - return CURLE_PEER_FAILED_VERIFICATION; - } - #[cfg(not(HAVE_GNUTLS_SRP))] - if true { - Curl_failf( - data, - b"failed to get server cert\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = -(49 as i32) as i64; - return CURLE_PEER_FAILED_VERIFICATION; - } - } - Curl_infof( - data, - b" common name: WARNING couldn't obtain\0" as *const u8 as *const libc::c_char, - ); - } - - #[cfg(CURL_DISABLE_PROXY)] - if chainp.is_null() { - if ((*conn).ssl_config).verifypeer() as i32 != 0 - || ((*conn).ssl_config).verifyhost() as i32 != 0 - || !((*conn).ssl_config.issuercert).is_null() - { - #[cfg(HAVE_GNUTLS_SRP)] - if (*data).set.ssl.authtype as u32 == CURL_TLSAUTH_SRP as u32 - && !((*data).set.ssl.username).is_null() - && ((*conn).ssl_config).verifypeer() == 0 - && gnutls_cipher_get(session) as u32 != 0 - { - } else { - Curl_failf( - data, - b"failed to get server cert\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = -(49 as i32) as i64; - return CURLE_PEER_FAILED_VERIFICATION; - } - #[cfg(not(HAVE_GNUTLS_SRP))] - if true { - Curl_failf( - data, - b"failed to get server cert\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = -(49 as i32) as i64; - return CURLE_PEER_FAILED_VERIFICATION; - } - } - Curl_infof( - data, - b" common name: WARNING couldn't obtain\0" as *const u8 as *const libc::c_char, - ); - }} - if unsafe{((*data).set.ssl).certinfo() as i32 }!= 0 &&unsafe{ !chainp.is_null()} { - let mut i: u32 = 0; - result = Curl_ssl_init_certinfo(data, cert_list_size as i32); - if result as u64 != 0 { - return result; - } - i = 0 as i32 as u32; - while i < cert_list_size { - let mut beg: *const libc::c_char = - unsafe{(*chainp.offset(i as isize)).data as *const libc::c_char}; - let mut end: *const libc::c_char = - unsafe{ beg.offset((*chainp.offset(i as isize)).size as isize)}; - result = unsafe{Curl_extract_certinfo(data, i as i32, beg, end)}; - if result as u64 != 0 { - return result; - } - i = i.wrapping_add(1); - } - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifypeer =unsafe{ if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifypeer =unsafe{ ((*conn).ssl_config).verifypeer()}; - - if SSL_CONN_CONFIG_verifypeer != 0 { - /* This function will try to verify the peer's certificate and return its - status (trusted, invalid etc.). The value of status should be one or - more of the gnutls_certificate_status_t enumerated elements bitwise - or'd. To avoid denial of service attacks some default upper limits - regarding the certificate key size and chain size are set. To override - them use gnutls_certificate_set_verify_limits(). */ - rc = unsafe{gnutls_certificate_verify_peers2(session, &mut verify_status)}; - if rc < 0 as i32 {unsafe{ - Curl_failf( - data, - b"server cert verify failed: %d\0" as *const u8 as *const libc::c_char, - rc, - ); - *certverifyresult = rc as i64;} - return CURLE_SSL_CONNECT_ERROR; - } - unsafe{*certverifyresult = verify_status as i64;} - - /* verify_status is a bitmask of gnutls_certificate_status bits */ - if verify_status & GNUTLS_CERT_INVALID as u32 != 0 { - if SSL_CONN_CONFIG_verifypeer != 0 { - unsafe{ - #[cfg(not(CURL_DISABLE_PROXY))] - Curl_failf( - data, - b"server certificate verification failed. CAfile: %s CRLfile: %s\0" - as *const u8 as *const libc::c_char, - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - } - .is_null() - { - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) - { - 0 as i32 - } else { - 1 as i32 - }) - as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - }) as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - } - .is_null() - { - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) - { - 0 as i32 - } else { - 1 as i32 - }) - as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - }) as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - #[cfg(CURL_DISABLE_PROXY)] - Curl_failf( - data, - b"server certificate verification failed. CAfile: %s CRLfile: %s\0" - as *const u8 as *const libc::c_char, - if !((*conn).ssl_config.CAfile).is_null() { - (*conn).ssl_config.CAfile as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - if !((*data).set.ssl.CRLfile).is_null() { - (*data).set.ssl.CRLfile as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - return CURLE_PEER_FAILED_VERIFICATION;} - } else { - unsafe{ - Curl_infof( - data, - b" server certificate verification FAILED\0" as *const u8 - as *const libc::c_char, - );} - } - } else { - unsafe{ - Curl_infof( - data, - b" server certificate verification OK\0" as *const u8 as *const libc::c_char, - );} - } - } else { - unsafe{ - Curl_infof( - data, - b" server certificate verification SKIPPED\0" as *const u8 as *const libc::c_char, - );} - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifystatus_1 = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifystatus() as i32 - } else { - ((*conn).ssl_config).verifystatus() as i32 - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifystatus_1 = unsafe{((*conn).ssl_config).verifystatus()}; - unsafe{ - if SSL_CONN_CONFIG_verifystatus_1 != 0 { - - if gnutls_ocsp_status_request_is_checked(session, 0 as u32) == 0 as u32 { - let mut status_request: gnutls_datum_t = gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; - let mut ocsp_resp: gnutls_ocsp_resp_t = 0 as *mut gnutls_ocsp_resp_int; - let mut status: gnutls_ocsp_cert_status_t = GNUTLS_OCSP_CERT_GOOD; - let mut reason: gnutls_x509_crl_reason_t = GNUTLS_X509_CRLREASON_UNSPECIFIED; - rc = gnutls_ocsp_status_request_get(session, &mut status_request); - Curl_infof( - data, - b" server certificate status verification FAILED\0" as *const u8 - as *const libc::c_char, - ); - if rc == -(56 as i32) { - Curl_failf( - data, - b"No OCSP response received\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_INVALIDCERTSTATUS; - } - if rc < 0 as i32 { - Curl_failf( - data, - b"Invalid OCSP response received\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_INVALIDCERTSTATUS; - } - gnutls_ocsp_resp_init(&mut ocsp_resp); - rc = gnutls_ocsp_resp_import(ocsp_resp, &mut status_request); - if rc < 0 as i32 { - Curl_failf( - data, - b"Invalid OCSP response received\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_INVALIDCERTSTATUS; - } - gnutls_ocsp_resp_get_single( - ocsp_resp as gnutls_ocsp_resp_const_t, - 0 as u32, - 0 as *mut gnutls_digest_algorithm_t, - 0 as *mut gnutls_datum_t, - 0 as *mut gnutls_datum_t, - 0 as *mut gnutls_datum_t, - &mut status as *mut gnutls_ocsp_cert_status_t as *mut u32, - 0 as *mut time_t, - 0 as *mut time_t, - 0 as *mut time_t, - &mut reason as *mut gnutls_x509_crl_reason_t as *mut u32, - ); - match status as u32 { - 0 => {} - 1 => { - let mut crl_reason: *const libc::c_char = 0 as *const libc::c_char; - match reason as u32 { - 1 => { - crl_reason = b"private key compromised\0" as *const u8 - as *const libc::c_char; - } - 2 => { - crl_reason = - b"CA compromised\0" as *const u8 as *const libc::c_char; - } - 3 => { - crl_reason = b"affiliation has changed\0" as *const u8 - as *const libc::c_char; - } - 4 => { - crl_reason = - b"certificate superseded\0" as *const u8 as *const libc::c_char; - } - 5 => { - crl_reason = - b"operation has ceased\0" as *const u8 as *const libc::c_char; - } - 6 => { - crl_reason = - b"certificate is on hold\0" as *const u8 as *const libc::c_char; - } - 8 => { - crl_reason = b"will be removed from delta CRL\0" as *const u8 - as *const libc::c_char; - } - 9 => { - crl_reason = - b"privilege withdrawn\0" as *const u8 as *const libc::c_char; - } - 10 => { - crl_reason = - b"AA compromised\0" as *const u8 as *const libc::c_char; - } - 0 | _ => { - crl_reason = - b"unspecified reason\0" as *const u8 as *const libc::c_char; - } - } - Curl_failf( - data, - b"Server certificate was revoked: %s\0" as *const u8 - as *const libc::c_char, - crl_reason, - ); - } - 2 | _ => { - Curl_failf( - data, - b"Server certificate status is unknown\0" as *const u8 - as *const libc::c_char, - ); - } - } - gnutls_ocsp_resp_deinit(ocsp_resp); - return CURLE_SSL_INVALIDCERTSTATUS; - } else { - Curl_infof( - data, - b" server certificate status verification OK\0" as *const u8 - as *const libc::c_char, - ); - } - } else { - Curl_infof( - data, - b" server certificate status verification SKIPPED\0" as *const u8 - as *const libc::c_char, - ); - }} - - /* initialize an X.509 certificate structure. */ - unsafe{ gnutls_x509_crt_init(&mut x509_cert);} - if !chainp.is_null() { - /* convert the given DER or PEM encoded Certificate to the native - gnutls_x509_crt_t format */ - unsafe{ gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);} - } - unsafe{ - #[cfg(not(CURL_DISABLE_PROXY))] - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - } - .is_null() - { - gnutls_x509_crt_init(&mut x509_issuer); - issuerp = load_file( - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - }, - ); - gnutls_x509_crt_import(x509_issuer, &mut issuerp, GNUTLS_X509_FMT_PEM); - rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer) as i32; - gnutls_x509_crt_deinit(x509_issuer); - unload_file(issuerp); - if rc <= 0 as i32 { - Curl_failf( - data, - b"server certificate issuer check failed (IssuerCert: %s)\0" as *const u8 - as *const libc::c_char, - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - } - .is_null() - { - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - }) as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_ISSUER_ERROR; - } - Curl_infof( - data, - b" server certificate issuer check OK (Issuer Cert: %s)\0" as *const u8 - as *const libc::c_char, - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - } - .is_null() - { - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - }) as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - } - } - unsafe{ - #[cfg(CURL_DISABLE_PROXY)] - if !((*conn).ssl_config.issuercert).is_null() { - gnutls_x509_crt_init(&mut x509_issuer); - issuerp = load_file((*conn).ssl_config.issuercert); - gnutls_x509_crt_import(x509_issuer, &mut issuerp, GNUTLS_X509_FMT_PEM); - rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer) as i32; - gnutls_x509_crt_deinit(x509_issuer); - unload_file(issuerp); - if rc <= 0 as i32 { - Curl_failf( - data, - b"server certificate issuer check failed (IssuerCert: %s)\0" as *const u8 - as *const libc::c_char, - if !((*conn).ssl_config.issuercert).is_null() { - (*conn).ssl_config.issuercert as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_ISSUER_ERROR; - } - Curl_infof( - data, - b" server certificate issuer check OK (Issuer Cert: %s)\0" as *const u8 - as *const libc::c_char, - if !((*conn).ssl_config.issuercert).is_null() { - (*conn).ssl_config.issuercert as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - } - } - size = ::std::mem::size_of::<[libc::c_char; 65]>() as u64; - rc = unsafe{gnutls_x509_crt_get_dn_by_oid( - x509_cert, - b"2.5.4.3\0" as *const u8 as *const libc::c_char, - 0 as u32, - 0 as u32, - certname.as_mut_ptr() as *mut libc::c_void, - &mut size, - )}; - if rc != 0 { - unsafe{Curl_infof( - data, - b"error fetching CN from cert:%s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - );} - } - - /* This function will check if the given certificate's subject matches the - given hostname. This is a basic implementation of the matching described - in RFC2818 (HTTPS), which takes into account wildcards, and the subject - alternative name PKIX extension. Returns non zero on success, and zero on - failure. */ - rc = unsafe{gnutls_x509_crt_check_hostname(x509_cert, hostname) as i32}; - // todo - GNUTLS_VERSION_NUMBER < 0x030306 - // 1079 - /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP - addresses. */ - if rc == 0 { - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_HOST_DISPNAME_void = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).http_proxy.host.dispname - } else { - (*conn).host.dispname - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_HOST_DISPNAME_void = unsafe{(*conn).host.dispname}; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifyhost = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifyhost() as i32 - } else { - ((*conn).ssl_config).verifyhost() as i32 - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifyhost = unsafe{((*conn).ssl_config).verifyhost()}; - if SSL_CONN_CONFIG_verifyhost != 0 { - unsafe{Curl_failf( - data, - b"SSL: certificate subject name (%s) does not match target host name '%s'\0" - as *const u8 as *const libc::c_char, - certname.as_mut_ptr(), - SSL_HOST_DISPNAME_void, - ); - gnutls_x509_crt_deinit(x509_cert);} - return CURLE_PEER_FAILED_VERIFICATION; - } else { - unsafe{Curl_infof( - data, - b" common name: %s (does not match '%s')\0" as *const u8 - as *const libc::c_char, - certname.as_mut_ptr(), - SSL_HOST_DISPNAME_void, - );} - } - } else { - unsafe{Curl_infof( - data, - b" common name: %s (matched)\0" as *const u8 as *const libc::c_char, - certname.as_mut_ptr(), - );} - } - certclock = unsafe{gnutls_x509_crt_get_expiration_time(x509_cert)}; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifypeer_1 = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifypeer_1 = unsafe{((*conn).ssl_config).verifypeer()}; - if certclock == -(1 as i32) as time_t { - if SSL_CONN_CONFIG_verifypeer_1 != 0 { - unsafe{Curl_failf( - data, - b"server cert expiration date verify failed\0" as *const u8 - as *const libc::c_char, - ); - *certverifyresult = GNUTLS_CERT_EXPIRED as i64; - gnutls_x509_crt_deinit(x509_cert);} - return CURLE_SSL_CONNECT_ERROR; - } else { - unsafe{ Curl_infof( - data, - b" server certificate expiration date verify FAILED\0" as *const u8 - as *const libc::c_char, - );} - } - } else if certclock < unsafe{time(0 as *mut time_t) }{ - if SSL_CONN_CONFIG_verifypeer_1 != 0 { - unsafe{Curl_failf( - data, - b"server certificate expiration date has passed.\0" as *const u8 - as *const libc::c_char, - ); - *certverifyresult = GNUTLS_CERT_EXPIRED as i32 as i64; - gnutls_x509_crt_deinit(x509_cert);} - return CURLE_PEER_FAILED_VERIFICATION; - } else { - unsafe{Curl_infof( - data, - b" server certificate expiration date FAILED\0" as *const u8 - as *const libc::c_char, - );} - } - } else { - unsafe{ Curl_infof( - data, - b" server certificate expiration date OK\0" as *const u8 as *const libc::c_char, - );} - } - /* Check for time-based validity */ - certclock = unsafe{gnutls_x509_crt_get_activation_time(x509_cert)}; - if certclock == -(1 as i32) as time_t { - if SSL_CONN_CONFIG_verifypeer_1 != 0 { - unsafe{ Curl_failf( - data, - b"server cert activation date verify failed\0" as *const u8 - as *const libc::c_char, - ); - *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED as i64; - gnutls_x509_crt_deinit(x509_cert);} - return CURLE_SSL_CONNECT_ERROR; - } else { - unsafe{Curl_infof( - data, - b" server certificate activation date verify FAILED\0" as *const u8 - as *const libc::c_char, - );} - } - } else if certclock > unsafe{time(0 as *mut time_t) }{ - if SSL_CONN_CONFIG_verifypeer_1 != 0 { - unsafe{Curl_failf( - data, - b"server certificate not activated yet.\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED as i64; - gnutls_x509_crt_deinit(x509_cert);} - return CURLE_PEER_FAILED_VERIFICATION; - } else { - unsafe{Curl_infof( - data, - b" server certificate activation date FAILED\0" as *const u8 - as *const libc::c_char, - );} - } - } else { - unsafe{ Curl_infof( - data, - b" server certificate activation date OK\0" as *const u8 as *const libc::c_char, - );} - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_PINNED_PUB_KEY_void = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as usize] - } else { - (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_PINNED_PUB_KEY_void = unsafe{(*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize]}; - ptr = SSL_PINNED_PUB_KEY_void; - if !ptr.is_null() { - result = pkp_pin_peer_pubkey(data, x509_cert, ptr); - if result as u32 != CURLE_OK as u32 { - unsafe{Curl_failf( - data, - b"SSL: public key does not match pinned public key!\0" as *const u8 - as *const libc::c_char, - ); - gnutls_x509_crt_deinit(x509_cert);} - return result; - } - } - - /* Show: - - - subject - - start date - - expire date - - common name - - issuer - - */ - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - algo = unsafe{gnutls_x509_crt_get_pk_algorithm(x509_cert, &mut bits) as u32}; /* public key algorithm's parameters */ - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - unsafe{Curl_infof( - data, - b" certificate public key: %s\0" as *const u8 as *const libc::c_char, - gnutls_pk_algorithm_get_name(algo as gnutls_pk_algorithm_t), - );} - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - unsafe{Curl_infof( - data, - b" certificate version: #%d\0" as *const u8 as *const libc::c_char, - gnutls_x509_crt_get_version(x509_cert), - ); /* version of the X.509 certificate. */} - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - rc = unsafe{gnutls_x509_crt_get_dn2(x509_cert, &mut certfields)}; - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - if rc != 0 { - unsafe{ Curl_infof( - data, - b"Failed to get certificate name\0" as *const u8 as *const libc::c_char, - );} - } else { - unsafe{Curl_infof( - data, - b" subject: %s\0" as *const u8 as *const libc::c_char, - certfields.data, - );} - certclock = unsafe{gnutls_x509_crt_get_activation_time(x509_cert)}; - showtime( - data, - b"start date\0" as *const u8 as *const libc::c_char, - certclock, - ); - certclock = unsafe{gnutls_x509_crt_get_expiration_time(x509_cert)}; - showtime( - data, - b"expire date\0" as *const u8 as *const libc::c_char, - certclock, - ); - unsafe{gnutls_free.expect("non-null function pointer")(certfields.data as *mut libc::c_void);} - } - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - rc = unsafe{gnutls_x509_crt_get_issuer_dn2(x509_cert, &mut certfields)}; - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - if rc != 0 { - unsafe{ Curl_infof( - data, - b"Failed to get certificate issuer\0" as *const u8 as *const libc::c_char, - );} - } else { - unsafe{Curl_infof( - data, - b" issuer: %s\0" as *const u8 as *const libc::c_char, - certfields.data, - ); - gnutls_free.expect("non-null function pointer")(certfields.data as *mut libc::c_void);} - } - unsafe{gnutls_x509_crt_deinit(x509_cert);} - if unsafe{((*conn).bits).tls_enable_alpn()} != 0 { - rc = unsafe{gnutls_alpn_get_selected_protocol(session, &mut proto)}; - if rc == 0 as i32 { - unsafe{Curl_infof( - data, - b"ALPN, server accepted to use %.*s\0" as *const u8 as *const libc::c_char, - proto.size, - proto.data, - );} - // done - 1254 - #[cfg(USE_HTTP2)] - let USE_HTTP2_flag = unsafe{proto.size == 2 as u32 - && memcmp( - b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, - proto.data as *const libc::c_void, - 2 as u64, - ) == 0}; - #[cfg(not(USE_HTTP2))] - let USE_HTTP2_flag = false; - if USE_HTTP2_flag { - unsafe{(*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32;} - } else if proto.size == 8 as u32 - && unsafe{memcmp( - b"http/1.1\0" as *const u8 as *const libc::c_char as *const libc::c_void, - proto.data as *const libc::c_void, - 8 as u64, - ) == 0} - { - unsafe{ (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32;} - } - } else { - unsafe{Curl_infof( - data, - b"ALPN, server did not agree to a protocol\0" as *const u8 - as *const libc::c_char, - );} - } - unsafe{Curl_multiuse_state( - data, - if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as i32 { - 2 as i32 - } else { - -(1 as i32) - }, - );} - } - unsafe{ (*conn).ssl[sockindex as usize].state = ssl_connection_complete; - (*conn).recv[sockindex as usize] = Some(gtls_recv as Curl_recv); - (*conn).send[sockindex as usize] = Some(gtls_send as Curl_send);} - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = unsafe{if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*data).set.proxy_ssl.primary).sessionid() as i32 - } else { - ((*data).set.ssl.primary).sessionid() as i32 - }}; - - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid =unsafe{ ((*data).set.ssl.primary).sessionid()}; - if SSL_SET_OPTION_primary_sessionid != 0 { - /* we always unconditionally get the session id here, as even if we - already got it from the cache and asked to use it in the connection, it - might've been rejected and then a new one is in use now and we need to - detect that. */ - let mut connect_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - let mut connect_idsize: size_t = 0 as size_t; - /* get the session ID data size */ - unsafe{gnutls_session_get_data(session, 0 as *mut libc::c_void, &mut connect_idsize);} - /* get a buffer for it */ - unsafe{ - match () { - #[cfg(not(CURLDEBUG))] - _ => { - connect_sessionid = - Curl_cmalloc.expect("non-null function pointer")(connect_idsize); - } - #[cfg(CURLDEBUG)] - _ => { - connect_sessionid = curl_dbg_malloc( - connect_idsize, - 1286 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - } - } - } - if !connect_sessionid.is_null() { - let mut incache: bool = false; - let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - /* extract session ID to the allocated buffer */ - unsafe{gnutls_session_get_data(session, connect_sessionid, &mut connect_idsize);} - Curl_ssl_sessionid_lock(data); - unsafe{ - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_IS_PROXY_void_1 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - 1 as i32 - } else { - 0 as i32 - } != 0; - - #[cfg(CURL_DISABLE_PROXY)] - let SSL_IS_PROXY_void_1 = if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0; - incache = !Curl_ssl_getsessionid( - data, - conn, - SSL_IS_PROXY_void_1, - &mut ssl_sessionid, - 0 as *mut size_t, - sockindex, - ); - if incache { - /* there was one before in the cache, so instead of risking that the - previous one was rejected, we just kill that and store the new */ - Curl_ssl_delsessionid(data, ssl_sessionid); - } - /* store this session id */ - result = Curl_ssl_addsessionid( - data, - conn, - SSL_IS_PROXY_void_1, - connect_sessionid, - connect_idsize, - sockindex, - ); - Curl_ssl_sessionid_unlock(data); - if result as u64 != 0 { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(connect_sessionid); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - connect_sessionid, - 1312 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - result = CURLE_OUT_OF_MEMORY; - } + } else { + Curl_infof( + data, + b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, + rc, + (*conn).ssl_config.CAfile, + ); + } + } + + #[cfg(not(CURL_DISABLE_PROXY))] + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CApath + } else { + (*conn).ssl_config.CApath + } + .is_null() + { + rc = gnutls_certificate_set_x509_trust_dir( + (*backend).cred, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CApath + } else { + (*conn).ssl_config.CApath + }, + GNUTLS_X509_FMT_PEM, + ); + if rc < 0 as i32 { + Curl_infof( + data, + b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CApath + } else { + (*conn).ssl_config.CApath + }, + gnutls_strerror(rc), + ); + if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + } != 0 + { + *certverifyresult = rc as i64; + return CURLE_SSL_CACERT_BADFILE; } - } else { - result = CURLE_OUT_OF_MEMORY; - } - } - return result; - - } - - /* - * This function is called after the TCP connect has completed. Setup the TLS - * layer and do all necessary magic. - */ - /* We use connssl->connecting_state to keep track of the connection status; - there are three states: 'ssl_connect_1' (not started yet or complete), - 'ssl_connect_2_reading' (waiting for data from server), and - 'ssl_connect_2_writing' (waiting to be able to write). + } else { + Curl_infof( + data, + b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, + rc, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CApath + } else { + (*conn).ssl_config.CApath + }, + ); + } + } + #[cfg(CURL_DISABLE_PROXY)] + if !((*conn).ssl_config.CApath).is_null() { + /* set the trusted CA cert directory */ + rc = gnutls_certificate_set_x509_trust_dir( + (*backend).cred, + (*conn).ssl_config.CApath, + GNUTLS_X509_FMT_PEM, + ); + if rc < 0 as i32 { + Curl_infof( + data, + b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, + (*conn).ssl_config.CApath, + gnutls_strerror(rc), + ); + if ((*conn).ssl_config).verifypeer() != 0 { + *certverifyresult = rc as i64; + return CURLE_SSL_CACERT_BADFILE; + } + } else { + Curl_infof( + data, + b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, + rc, + (*conn).ssl_config.CApath, + ); + } + } + + // todo - 497 + // #[cfg(CURL_CA_FALLBACK)] + #[cfg(not(CURL_DISABLE_PROXY))] + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + } + .is_null() + { + rc = gnutls_certificate_set_x509_crl_file( + (*backend).cred, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + }, + GNUTLS_X509_FMT_PEM, + ); + if rc < 0 as i32 { + Curl_failf( + data, + b"error reading crl file %s (%s)\0" as *const u8 as *const libc::c_char, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + }, + gnutls_strerror(rc), + ); + return CURLE_SSL_CRL_BADFILE; + } else { + Curl_infof( + data, + b"found %d CRL in %s\0" as *const u8 as *const libc::c_char, + rc, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + }, + ); + } + } + #[cfg(CURL_DISABLE_PROXY)] + if !((*data).set.ssl.CRLfile).is_null() { + /* set the CRL list file */ + rc = gnutls_certificate_set_x509_crl_file( + (*backend).cred, + (*data).set.ssl.CRLfile, + GNUTLS_X509_FMT_PEM, + ); + if rc < 0 as i32 { + Curl_failf( + data, + b"error reading crl file %s (%s)\0" as *const u8 as *const libc::c_char, + (*data).set.ssl.CRLfile, + gnutls_strerror(rc), + ); + return CURLE_SSL_CRL_BADFILE; + } else { + Curl_infof( + data, + b"found %d CRL in %s\0" as *const u8 as *const libc::c_char, + rc, + (*data).set.ssl.CRLfile, + ); + } + } + /* Initialize TLS session as a client */ + init_flags = ((1 as i32) << 1 as i32) as u32; + #[cfg(GNUTLS_FORCE_CLIENT_CERT)] + if true { + init_flags |= ((1 as i32) << 9 as i32) as u32; + } + #[cfg(GNUTLS_NO_TICKETS)] + if true { + /* Disable TLS session tickets */ + init_flags |= ((1 as i32) << 10 as i32) as u32; + } + rc = gnutls_init(&mut (*backend).session, init_flags); + if rc != 0 as i32 { + Curl_failf( + data, + b"gnutls_init() failed: %d\0" as *const u8 as *const libc::c_char, + rc, + ); + return CURLE_SSL_CONNECT_ERROR; + } + /* convenient assign */ + session = (*backend).session; + // done - 条件编译 - 542 + #[cfg(ENABLE_IPV6)] + if 0 as i32 + == inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in6_addr as *mut libc::c_void, + ) + && 0 as i32 + == inet_pton( + 10 as i32, + hostname, + &mut addr as *mut in6_addr as *mut libc::c_void, + ) + && sni as i32 != 0 + && gnutls_server_name_set( + session, + GNUTLS_NAME_DNS, + hostname as *const libc::c_void, + strlen(hostname), + ) < 0 as i32 + { + Curl_infof( + data, + b"WARNING: failed to configure server name indication (SNI) TLS extension\0" + as *const u8 as *const libc::c_char, + ); + } + #[cfg(not(ENABLE_IPV6))] + if 0 as i32 + == inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in_addr as *mut libc::c_void, + ) + && sni as i32 != 0 + && gnutls_server_name_set( + session, + GNUTLS_NAME_DNS, + hostname as *const libc::c_void, + strlen(hostname), + ) < 0 as i32 + { + Curl_infof( + data, + b"WARNING: failed to configure server name indication (SNI) TLS extension\0" + as *const u8 as *const libc::c_char, + ); + } + /* Use default priorities */ + rc = gnutls_set_default_priority(session); + if rc != 0 as i32 { + return CURLE_SSL_CONNECT_ERROR; + } + /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */ + tls13support = gnutls_check_version(b"3.6.5\0" as *const u8 as *const libc::c_char); + /* Ensure +SRP comes at the *end* of all relevant strings so that it can be + * removed if a run-time error indicates that SRP is not supported by this + * GnuTLS version */ + match SSL_CONN_CONFIG_version { + 7 => { + if tls13support.is_null() { + Curl_failf( + data, + b"This GnuTLS installation does not support TLS 1.3\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } + } + 0 | 1 | 4 | 5 | 6 => {} + 2 | 3 | _ => { + Curl_failf( + data, + b"GnuTLS does not support SSLv2 or SSLv3\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } + } + let mut result: CURLcode = set_ssl_version_min_max(data, &mut prioritylist, tls13support); + if result as u64 != 0 { + return result; + } + /* Only add SRP to the cipher list if SRP is requested. Otherwise + * GnuTLS will disable TLS 1.3 support. */ + #[cfg(HAVE_GNUTLS_SRP)] + if SSL_SET_OPTION_authtype as u32 == CURL_TLSAUTH_SRP as i32 as u32 { + let mut len: size_t = strlen(prioritylist); + #[cfg(not(CURLDEBUG))] + let mut prioritysrp: *mut libc::c_char = Curl_cmalloc + .expect("non-null function pointer")( + len.wrapping_add(::std::mem::size_of::<[libc::c_char; 5]>() as u64) + .wrapping_add(1 as u64), + ) as *mut libc::c_char; + #[cfg(CURLDEBUG)] + let mut prioritysrp: *mut libc::c_char = curl_dbg_malloc( + len.wrapping_add(::std::mem::size_of::<[libc::c_char; 5]>() as u64) + .wrapping_add(1 as u64), + 591 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ) as *mut libc::c_char; + if prioritysrp.is_null() { + return CURLE_OUT_OF_MEMORY; + } + strcpy(prioritysrp, prioritylist); + strcpy( + prioritysrp.offset(len as isize), + b":+SRP\0" as *const u8 as *const libc::c_char, + ); + rc = gnutls_priority_set_direct(session, prioritysrp, &mut err); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(prioritysrp as *mut libc::c_void); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + prioritysrp as *mut libc::c_void, + 597 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + if rc == -(50 as i32) && !err.is_null() { + Curl_infof( + data, + b"This GnuTLS does not support SRP\0" as *const u8 as *const libc::c_char, + ); + } + } else { + Curl_infof( + data, + b"GnuTLS ciphers: %s\0" as *const u8 as *const libc::c_char, + prioritylist, + ); + rc = gnutls_priority_set_direct(session, prioritylist, &mut err); + } + #[cfg(not(HAVE_GNUTLS_SRP))] + if true { + Curl_infof( + data, + b"GnuTLS ciphers: %s\0" as *const u8 as *const libc::c_char, + prioritylist, + ); + rc = gnutls_priority_set_direct(session, prioritylist, &mut err); + } + if rc != 0 as i32 { + Curl_failf( + data, + b"Error %d setting GnuTLS cipher list starting with %s\0" as *const u8 + as *const libc::c_char, + rc, + err, + ); + return CURLE_SSL_CONNECT_ERROR; + } + if ((*conn).bits).tls_enable_alpn() != 0 { + let mut cur: i32 = 0 as i32; + let mut protocols: [gnutls_datum_t; 2] = [gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; 2]; + // done - 623 + #[cfg(not(CURL_DISABLE_PROXY))] + let CURL_DISABLE_PROXY_flag = (!(CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32) + || ((*conn).bits).tunnel_proxy() == 0); + #[cfg(CURL_DISABLE_PROXY)] + let CURL_DISABLE_PROXY_flag = true; + #[cfg(USE_HTTP2)] + if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 + && CURL_DISABLE_PROXY_flag + { + protocols[cur as usize].data = + b"h2\0" as *const u8 as *const libc::c_char as *mut u8; + protocols[cur as usize].size = 2 as u32; + cur += 1; + Curl_infof( + data, + b"ALPN, offering %.*s\0" as *const u8 as *const libc::c_char, + 2 as i32, + b"h2\0" as *const u8 as *const libc::c_char, + ); + } + protocols[cur as usize].data = + b"http/1.1\0" as *const u8 as *const libc::c_char as *mut u8; + protocols[cur as usize].size = 8 as u32; + cur += 1; + Curl_infof( + data, + b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, + b"http/1.1\0" as *const u8 as *const libc::c_char, + ); + gnutls_alpn_set_protocols(session, protocols.as_mut_ptr(), cur as u32, 0 as u32); + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_clientcert = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.primary.clientcert + } else { + (*data).set.ssl.primary.clientcert + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_clientcert = (*data).set.ssl.primary.clientcert; + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_key_passwd = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key_passwd + } else { + (*data).set.ssl.key_passwd + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_key_passwd = (*data).set.ssl.key_passwd; + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_key = if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key + } else { + (*data).set.ssl.key + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_key = (*data).set.ssl.key; + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_cert_type = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.cert_type + } else { + (*data).set.ssl.cert_type + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_cert_type = (*data).set.ssl.cert_type; + + if !SSL_SET_OPTION_primary_clientcert.is_null() { + if !SSL_SET_OPTION_key_passwd.is_null() { + let supported_key_encryption_algorithms: u32 = (GNUTLS_PKCS_PKCS12_3DES as i32 + | GNUTLS_PKCS_PKCS12_ARCFOUR as i32 + | GNUTLS_PKCS_PKCS12_RC2_40 as i32 + | GNUTLS_PKCS_PBES2_3DES as i32 + | GNUTLS_PKCS_PBES2_AES_128 as i32 + | GNUTLS_PKCS_PBES2_AES_192 as i32 + | GNUTLS_PKCS_PBES2_AES_256 as i32) + as u32; + rc = gnutls_certificate_set_x509_key_file2( + (*backend).cred, + SSL_SET_OPTION_primary_clientcert, + if !SSL_SET_OPTION_key.is_null() { + SSL_SET_OPTION_key + } else { + SSL_SET_OPTION_primary_clientcert + }, + do_file_type(SSL_SET_OPTION_cert_type), + SSL_SET_OPTION_key_passwd, + supported_key_encryption_algorithms, + ); + if rc != 0 as i32 { + Curl_failf( + data, + b"error reading X.509 potentially-encrypted key file: %s\0" as *const u8 + as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_SSL_CONNECT_ERROR; + } + } else if gnutls_certificate_set_x509_key_file( + (*backend).cred, + SSL_SET_OPTION_primary_clientcert, + if !(SSL_SET_OPTION_key).is_null() { + SSL_SET_OPTION_key + } else { + SSL_SET_OPTION_primary_clientcert + }, + do_file_type(SSL_SET_OPTION_cert_type), + ) != 0 as i32 + { + Curl_failf( + data, + b"error reading X.509 key or certificate file\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } + } + /* put the credentials to the current session */ + #[cfg(HAVE_GNUTLS_SRP)] + if SSL_SET_OPTION_authtype == CURL_TLSAUTH_SRP as u32 { + rc = gnutls_credentials_set( + session, + GNUTLS_CRD_SRP, + (*backend).srp_client_cred as *mut libc::c_void, + ); + if rc != 0 as i32 { + Curl_failf( + data, + b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_SSL_CONNECT_ERROR; + } + } else { + rc = gnutls_credentials_set( + session, + GNUTLS_CRD_CERTIFICATE, + (*backend).cred as *mut libc::c_void, + ); + if rc != 0 as i32 { + Curl_failf( + data, + b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_SSL_CONNECT_ERROR; + } + } + #[cfg(not(HAVE_GNUTLS_SRP))] + if true { + rc = gnutls_credentials_set( + session, + GNUTLS_CRD_CERTIFICATE, + (*backend).cred as *mut libc::c_void, + ); + if rc != 0 as i32 { + Curl_failf( + data, + b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_SSL_CONNECT_ERROR; + } + } + + #[cfg(not(CURL_DISABLE_PROXY))] + if ((*conn).proxy_ssl[sockindex as usize]).use_0() != 0 { + transport_ptr = + (*(*conn).proxy_ssl[sockindex as usize].backend).session as *mut libc::c_void; + gnutls_transport_push = Some( + gtls_push_ssl + as unsafe extern "C" fn( + *mut libc::c_void, + *const libc::c_void, + size_t, + ) -> ssize_t, + ); + gnutls_transport_pull = Some( + gtls_pull_ssl + as unsafe extern "C" fn( + *mut libc::c_void, + *mut libc::c_void, + size_t, + ) -> ssize_t, + ); + } else { + transport_ptr = &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) + as *mut curl_socket_t as *mut libc::c_void; + gnutls_transport_push = Some( + gtls_push + as unsafe extern "C" fn( + *mut libc::c_void, + *const libc::c_void, + size_t, + ) -> ssize_t, + ); + gnutls_transport_pull = Some( + gtls_pull + as unsafe extern "C" fn( + *mut libc::c_void, + *mut libc::c_void, + size_t, + ) -> ssize_t, + ); + } + #[cfg(CURL_DISABLE_PROXY)] + if true { + /* file descriptor for the socket */ + transport_ptr = &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) + as *mut curl_socket_t as *mut libc::c_void; + gnutls_transport_push = Some( + gtls_push + as unsafe extern "C" fn( + *mut libc::c_void, + *const libc::c_void, + size_t, + ) -> ssize_t, + ); + gnutls_transport_pull = Some( + gtls_pull + as unsafe extern "C" fn( + *mut libc::c_void, + *mut libc::c_void, + size_t, + ) -> ssize_t, + ); + } + /* set the connection handle */ + gnutls_transport_set_ptr(session, transport_ptr); + /* register callback functions to send and receive data. */ + gnutls_transport_set_push_function(session, gnutls_transport_push); + gnutls_transport_set_pull_function(session, gnutls_transport_pull); + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifystatus = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifystatus() as i32 + } else { + ((*conn).ssl_config).verifystatus() as i32 + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifystatus = ((*conn).ssl_config).verifystatus(); + if SSL_CONN_CONFIG_verifystatus != 0 { + rc = gnutls_ocsp_status_request_enable_client( + session, + 0 as *mut gnutls_datum_t, + 0 as size_t, + 0 as *mut gnutls_datum_t, + ); + if rc != 0 as i32 { + Curl_failf( + data, + b"gnutls_ocsp_status_request_enable_client() failed: %d\0" as *const u8 + as *const libc::c_char, + rc, + ); + return CURLE_SSL_CONNECT_ERROR; + } + } + /* This might be a reconnect, so we check for a session ID in the cache + to speed up things */ + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*data).set.proxy_ssl.primary).sessionid() as i32 + } else { + ((*data).set.ssl.primary).sessionid() as i32 + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = ((*data).set.ssl.primary).sessionid(); + if SSL_SET_OPTION_primary_sessionid != 0 { + let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + let mut ssl_idsize: size_t = 0; + Curl_ssl_sessionid_lock(data); + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_IS_PROXY_void_1 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + 1 as i32 + } else { + 0 as i32 + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_IS_PROXY_void_1 = if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0; + if !Curl_ssl_getsessionid( + data, + conn, + SSL_IS_PROXY_void_1, + &mut ssl_sessionid, + &mut ssl_idsize, + sockindex, + ) { + /* we got a session id, use it! */ + gnutls_session_set_data(session, ssl_sessionid, ssl_idsize); + /* Informational message */ + Curl_infof( + data, + b"SSL re-using session ID\0" as *const u8 as *const libc::c_char, + ); + } + Curl_ssl_sessionid_unlock(data); + } + return CURLE_OK; + } +} +extern "C" fn pkp_pin_peer_pubkey( + mut data: *mut Curl_easy, + mut cert: gnutls_x509_crt_t, + mut pinnedpubkey: *const libc::c_char, +) -> CURLcode { + /* Scratch */ + let mut len1: size_t = 0 as size_t; + let mut len2: size_t = 0 as size_t; + let mut buff1: *mut u8 = 0 as *mut u8; + let mut key: gnutls_pubkey_t = 0 as gnutls_pubkey_t; + /* Result is returned to caller */ + let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + /* if a path wasn't specified, don't pin */ + if pinnedpubkey.is_null() { + return CURLE_OK; + } + if cert.is_null() { + return result; + } + let mut ret: i32 = 0; + /* Begin Gyrations to get the public key */ + unsafe{ gnutls_pubkey_init(&mut key);} + ret = unsafe{ gnutls_pubkey_import_x509(key, cert, 0 as u32)}; + if !(ret < 0 as i32) { + ret = unsafe{ gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, 0 as *mut libc::c_void, &mut len1)}; + if !(ret != -(51 as i32) || len1 == 0 as u64) { + unsafe{ + match () { + #[cfg(not(CURLDEBUG))] + _ => { + buff1 = Curl_cmalloc.expect("non-null function pointer")(len1) as *mut u8; + } + #[cfg(CURLDEBUG)] + _ => { + buff1 = curl_dbg_malloc( + len1, + 785 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ) as *mut u8; + } + } + + if !buff1.is_null() { + len2 = len1; + ret = gnutls_pubkey_export( + key, + GNUTLS_X509_FMT_DER, + buff1 as *mut libc::c_void, + &mut len2, + ); + if !(ret < 0 as i32 || len1 != len2) { + /* End Gyrations */ + + /* The one good exit point */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); + } + }} + } + } + if unsafe{ !key.is_null() }{ + unsafe{ + gnutls_pubkey_deinit(key);} + } + #[cfg(not(CURLDEBUG))] + unsafe{ Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void);} + + #[cfg(CURLDEBUG)] + unsafe{ curl_dbg_free( + buff1 as *mut libc::c_void, + 804 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + );} + buff1 = 0 as *mut u8; + return result; + +} + +extern "C" fn gtls_connect_step3( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + unsafe { + let mut cert_list_size: u32 = 0; + let mut chainp: *const gnutls_datum_t = 0 as *const gnutls_datum_t; + let mut verify_status: u32 = 0 as u32; + let mut x509_cert: gnutls_x509_crt_t = 0 as *mut gnutls_x509_crt_int; + let mut x509_issuer: gnutls_x509_crt_t = 0 as *mut gnutls_x509_crt_int; + let mut issuerp: gnutls_datum_t = gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; + let mut certfields: gnutls_datum_t = gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; + let mut certname: [libc::c_char; 65] = *::std::mem::transmute::< + &[u8; 65], + &mut [libc::c_char; 65], + >( + b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + ); /* limited to 64 chars by ASN.1 */ + let mut size: size_t = 0; + let mut certclock: time_t = 0; + let mut ptr: *const libc::c_char = 0 as *const libc::c_char; + let mut connssl: *mut ssl_connect_data = + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; + let mut backend: *mut ssl_backend_data = (*connssl).backend; + let mut session: gnutls_session_t = (*backend).session; + let mut rc: i32 = 0; + let mut proto: gnutls_datum_t = gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; + let mut result: CURLcode = CURLE_OK; + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + let mut algo: u32 = 0; + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + let mut bits: u32 = 0; + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + let mut version: gnutls_protocol_t = gnutls_protocol_get_version(session); + #[cfg(not(CURL_DISABLE_PROXY))] + let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).http_proxy.host.name + } else { + (*conn).host.name + }; + #[cfg(CURL_DISABLE_PROXY)] + let hostname: *const libc::c_char = (*conn).host.name; + + #[cfg(not(CURL_DISABLE_PROXY))] + let certverifyresult: *mut i64 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + &mut (*data).set.proxy_ssl.certverifyresult + } else { + &mut (*data).set.ssl.certverifyresult + }; + #[cfg(CURL_DISABLE_PROXY)] + let certverifyresult: *mut i64 = &mut (*data).set.ssl.certverifyresult; + /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ + ptr = gnutls_cipher_suite_get_name( + gnutls_kx_get(session), + gnutls_cipher_get(session), + gnutls_mac_get(session), + ); + Curl_infof( + data, + b"SSL connection using %s / %s\0" as *const u8 as *const libc::c_char, + gnutls_protocol_get_name(version), + ptr, + ); + + /* This function will return the peer's raw certificate (chain) as sent by + the peer. These certificates are in raw format (DER encoded for + X.509). In case of a X.509 then a certificate list may be present. The + first certificate in the list is the peer's certificate, following the + issuer's certificate, then the issuer's issuer etc. */ + chainp = gnutls_certificate_get_peers(session, &mut cert_list_size); + #[cfg(not(CURL_DISABLE_PROXY))] + if chainp.is_null() { + if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + }) != 0 + || (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifyhost() as i32 + } else { + ((*conn).ssl_config).verifyhost() as i32 + }) != 0 + || !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + }) + .is_null() + { + #[cfg(HAVE_GNUTLS_SRP)] + if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.authtype as u32 + } else { + (*data).set.ssl.authtype as u32 + }) == CURL_TLSAUTH_SRP as u32 + && !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }) + .is_null() + && (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + }) == 0 + && gnutls_cipher_get(session) as u32 != 0 + { + /* no peer cert, but auth is ok if we have SRP user and cipher and no + peer verify */ + } else { + Curl_failf( + data, + b"failed to get server cert\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = -(49 as i32) as i64; + return CURLE_PEER_FAILED_VERIFICATION; + } + #[cfg(not(HAVE_GNUTLS_SRP))] + if true { + Curl_failf( + data, + b"failed to get server cert\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = -(49 as i32) as i64; + return CURLE_PEER_FAILED_VERIFICATION; + } + } + Curl_infof( + data, + b" common name: WARNING couldn't obtain\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(CURL_DISABLE_PROXY)] + if chainp.is_null() { + if ((*conn).ssl_config).verifypeer() as i32 != 0 + || ((*conn).ssl_config).verifyhost() as i32 != 0 + || !((*conn).ssl_config.issuercert).is_null() + { + #[cfg(HAVE_GNUTLS_SRP)] + if (*data).set.ssl.authtype as u32 == CURL_TLSAUTH_SRP as u32 + && !((*data).set.ssl.username).is_null() + && ((*conn).ssl_config).verifypeer() == 0 + && gnutls_cipher_get(session) as u32 != 0 + { + } else { + Curl_failf( + data, + b"failed to get server cert\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = -(49 as i32) as i64; + return CURLE_PEER_FAILED_VERIFICATION; + } + #[cfg(not(HAVE_GNUTLS_SRP))] + if true { + Curl_failf( + data, + b"failed to get server cert\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = -(49 as i32) as i64; + return CURLE_PEER_FAILED_VERIFICATION; + } + } + Curl_infof( + data, + b" common name: WARNING couldn't obtain\0" as *const u8 as *const libc::c_char, + ); + } + if ((*data).set.ssl).certinfo() as i32 != 0 && !chainp.is_null() { + let mut i: u32 = 0; + result = Curl_ssl_init_certinfo(data, cert_list_size as i32); + if result as u64 != 0 { + return result; + } + i = 0 as i32 as u32; + while i < cert_list_size { + let mut beg: *const libc::c_char = + (*chainp.offset(i as isize)).data as *const libc::c_char; + let mut end: *const libc::c_char = + beg.offset((*chainp.offset(i as isize)).size as isize); + result = Curl_extract_certinfo(data, i as i32, beg, end); + if result as u64 != 0 { + return result; + } + i = i.wrapping_add(1); + } + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifypeer = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifypeer = ((*conn).ssl_config).verifypeer(); + + if SSL_CONN_CONFIG_verifypeer != 0 { + /* This function will try to verify the peer's certificate and return its + status (trusted, invalid etc.). The value of status should be one or + more of the gnutls_certificate_status_t enumerated elements bitwise + or'd. To avoid denial of service attacks some default upper limits + regarding the certificate key size and chain size are set. To override + them use gnutls_certificate_set_verify_limits(). */ + rc = gnutls_certificate_verify_peers2(session, &mut verify_status); + if rc < 0 as i32 { + Curl_failf( + data, + b"server cert verify failed: %d\0" as *const u8 as *const libc::c_char, + rc, + ); + *certverifyresult = rc as i64; + return CURLE_SSL_CONNECT_ERROR; + } + *certverifyresult = verify_status as i64; + + /* verify_status is a bitmask of gnutls_certificate_status bits */ + if verify_status & GNUTLS_CERT_INVALID as u32 != 0 { + if SSL_CONN_CONFIG_verifypeer != 0 { + #[cfg(not(CURL_DISABLE_PROXY))] + Curl_failf( + data, + b"server certificate verification failed. CAfile: %s CRLfile: %s\0" + as *const u8 as *const libc::c_char, + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + } + .is_null() + { + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) + { + 0 as i32 + } else { + 1 as i32 + }) + as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + }) as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + } + .is_null() + { + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) + { + 0 as i32 + } else { + 1 as i32 + }) + as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + }) as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + #[cfg(CURL_DISABLE_PROXY)] + Curl_failf( + data, + b"server certificate verification failed. CAfile: %s CRLfile: %s\0" + as *const u8 as *const libc::c_char, + if !((*conn).ssl_config.CAfile).is_null() { + (*conn).ssl_config.CAfile as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + if !((*data).set.ssl.CRLfile).is_null() { + (*data).set.ssl.CRLfile as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + return CURLE_PEER_FAILED_VERIFICATION; + } else { + Curl_infof( + data, + b" server certificate verification FAILED\0" as *const u8 + as *const libc::c_char, + ); + } + } else { + Curl_infof( + data, + b" server certificate verification OK\0" as *const u8 as *const libc::c_char, + ); + } + } else { + Curl_infof( + data, + b" server certificate verification SKIPPED\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifystatus_1 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifystatus() as i32 + } else { + ((*conn).ssl_config).verifystatus() as i32 + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifystatus_1 = ((*conn).ssl_config).verifystatus(); + if SSL_CONN_CONFIG_verifystatus_1 != 0 { + if gnutls_ocsp_status_request_is_checked(session, 0 as u32) == 0 as u32 { + let mut status_request: gnutls_datum_t = gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; + let mut ocsp_resp: gnutls_ocsp_resp_t = 0 as *mut gnutls_ocsp_resp_int; + let mut status: gnutls_ocsp_cert_status_t = GNUTLS_OCSP_CERT_GOOD; + let mut reason: gnutls_x509_crl_reason_t = GNUTLS_X509_CRLREASON_UNSPECIFIED; + rc = gnutls_ocsp_status_request_get(session, &mut status_request); + Curl_infof( + data, + b" server certificate status verification FAILED\0" as *const u8 + as *const libc::c_char, + ); + if rc == -(56 as i32) { + Curl_failf( + data, + b"No OCSP response received\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_INVALIDCERTSTATUS; + } + if rc < 0 as i32 { + Curl_failf( + data, + b"Invalid OCSP response received\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_INVALIDCERTSTATUS; + } + gnutls_ocsp_resp_init(&mut ocsp_resp); + rc = gnutls_ocsp_resp_import(ocsp_resp, &mut status_request); + if rc < 0 as i32 { + Curl_failf( + data, + b"Invalid OCSP response received\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_INVALIDCERTSTATUS; + } + gnutls_ocsp_resp_get_single( + ocsp_resp as gnutls_ocsp_resp_const_t, + 0 as u32, + 0 as *mut gnutls_digest_algorithm_t, + 0 as *mut gnutls_datum_t, + 0 as *mut gnutls_datum_t, + 0 as *mut gnutls_datum_t, + &mut status as *mut gnutls_ocsp_cert_status_t as *mut u32, + 0 as *mut time_t, + 0 as *mut time_t, + 0 as *mut time_t, + &mut reason as *mut gnutls_x509_crl_reason_t as *mut u32, + ); + match status as u32 { + 0 => {} + 1 => { + let mut crl_reason: *const libc::c_char = 0 as *const libc::c_char; + match reason as u32 { + 1 => { + crl_reason = b"private key compromised\0" as *const u8 + as *const libc::c_char; + } + 2 => { + crl_reason = + b"CA compromised\0" as *const u8 as *const libc::c_char; + } + 3 => { + crl_reason = b"affiliation has changed\0" as *const u8 + as *const libc::c_char; + } + 4 => { + crl_reason = + b"certificate superseded\0" as *const u8 as *const libc::c_char; + } + 5 => { + crl_reason = + b"operation has ceased\0" as *const u8 as *const libc::c_char; + } + 6 => { + crl_reason = + b"certificate is on hold\0" as *const u8 as *const libc::c_char; + } + 8 => { + crl_reason = b"will be removed from delta CRL\0" as *const u8 + as *const libc::c_char; + } + 9 => { + crl_reason = + b"privilege withdrawn\0" as *const u8 as *const libc::c_char; + } + 10 => { + crl_reason = + b"AA compromised\0" as *const u8 as *const libc::c_char; + } + 0 | _ => { + crl_reason = + b"unspecified reason\0" as *const u8 as *const libc::c_char; + } + } + Curl_failf( + data, + b"Server certificate was revoked: %s\0" as *const u8 + as *const libc::c_char, + crl_reason, + ); + } + 2 | _ => { + Curl_failf( + data, + b"Server certificate status is unknown\0" as *const u8 + as *const libc::c_char, + ); + } + } + gnutls_ocsp_resp_deinit(ocsp_resp); + return CURLE_SSL_INVALIDCERTSTATUS; + } else { + Curl_infof( + data, + b" server certificate status verification OK\0" as *const u8 + as *const libc::c_char, + ); + } + } else { + Curl_infof( + data, + b" server certificate status verification SKIPPED\0" as *const u8 + as *const libc::c_char, + ); + } + + /* initialize an X.509 certificate structure. */ + gnutls_x509_crt_init(&mut x509_cert); + if !chainp.is_null() { + /* convert the given DER or PEM encoded Certificate to the native + gnutls_x509_crt_t format */ + gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); + } + #[cfg(not(CURL_DISABLE_PROXY))] + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + } + .is_null() + { + gnutls_x509_crt_init(&mut x509_issuer); + issuerp = load_file( + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + }, + ); + gnutls_x509_crt_import(x509_issuer, &mut issuerp, GNUTLS_X509_FMT_PEM); + rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer) as i32; + gnutls_x509_crt_deinit(x509_issuer); + unload_file(issuerp); + if rc <= 0 as i32 { + Curl_failf( + data, + b"server certificate issuer check failed (IssuerCert: %s)\0" as *const u8 + as *const libc::c_char, + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + } + .is_null() + { + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + }) as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_ISSUER_ERROR; + } + Curl_infof( + data, + b" server certificate issuer check OK (Issuer Cert: %s)\0" as *const u8 + as *const libc::c_char, + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + } + .is_null() + { + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + }) as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + } + #[cfg(CURL_DISABLE_PROXY)] + if !((*conn).ssl_config.issuercert).is_null() { + gnutls_x509_crt_init(&mut x509_issuer); + issuerp = load_file((*conn).ssl_config.issuercert); + gnutls_x509_crt_import(x509_issuer, &mut issuerp, GNUTLS_X509_FMT_PEM); + rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer) as i32; + gnutls_x509_crt_deinit(x509_issuer); + unload_file(issuerp); + if rc <= 0 as i32 { + Curl_failf( + data, + b"server certificate issuer check failed (IssuerCert: %s)\0" as *const u8 + as *const libc::c_char, + if !((*conn).ssl_config.issuercert).is_null() { + (*conn).ssl_config.issuercert as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_ISSUER_ERROR; + } + Curl_infof( + data, + b" server certificate issuer check OK (Issuer Cert: %s)\0" as *const u8 + as *const libc::c_char, + if !((*conn).ssl_config.issuercert).is_null() { + (*conn).ssl_config.issuercert as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + } + size = ::std::mem::size_of::<[libc::c_char; 65]>() as u64; + rc = gnutls_x509_crt_get_dn_by_oid( + x509_cert, + b"2.5.4.3\0" as *const u8 as *const libc::c_char, + 0 as u32, + 0 as u32, + certname.as_mut_ptr() as *mut libc::c_void, + &mut size, + ); + if rc != 0 { + Curl_infof( + data, + b"error fetching CN from cert:%s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + ); + } + + /* This function will check if the given certificate's subject matches the + given hostname. This is a basic implementation of the matching described + in RFC2818 (HTTPS), which takes into account wildcards, and the subject + alternative name PKIX extension. Returns non zero on success, and zero on + failure. */ + rc = gnutls_x509_crt_check_hostname(x509_cert, hostname) as i32; + // todo - GNUTLS_VERSION_NUMBER < 0x030306 + // 1079 + /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP + addresses. */ + if rc == 0 { + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_HOST_DISPNAME_void = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).http_proxy.host.dispname + } else { + (*conn).host.dispname + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_HOST_DISPNAME_void = (*conn).host.dispname; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifyhost = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifyhost() as i32 + } else { + ((*conn).ssl_config).verifyhost() as i32 + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifyhost = ((*conn).ssl_config).verifyhost(); + if SSL_CONN_CONFIG_verifyhost != 0 { + Curl_failf( + data, + b"SSL: certificate subject name (%s) does not match target host name '%s'\0" + as *const u8 as *const libc::c_char, + certname.as_mut_ptr(), + SSL_HOST_DISPNAME_void, + ); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_PEER_FAILED_VERIFICATION; + } else { + Curl_infof( + data, + b" common name: %s (does not match '%s')\0" as *const u8 + as *const libc::c_char, + certname.as_mut_ptr(), + SSL_HOST_DISPNAME_void, + ); + } + } else { + Curl_infof( + data, + b" common name: %s (matched)\0" as *const u8 as *const libc::c_char, + certname.as_mut_ptr(), + ); + } + certclock = gnutls_x509_crt_get_expiration_time(x509_cert); + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifypeer_1 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifypeer_1 = ((*conn).ssl_config).verifypeer(); + if certclock == -(1 as i32) as time_t { + if SSL_CONN_CONFIG_verifypeer_1 != 0 { + Curl_failf( + data, + b"server cert expiration date verify failed\0" as *const u8 + as *const libc::c_char, + ); + *certverifyresult = GNUTLS_CERT_EXPIRED as i64; + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_CONNECT_ERROR; + } else { + Curl_infof( + data, + b" server certificate expiration date verify FAILED\0" as *const u8 + as *const libc::c_char, + ); + } + } else if certclock < time(0 as *mut time_t) { + if SSL_CONN_CONFIG_verifypeer_1 != 0 { + Curl_failf( + data, + b"server certificate expiration date has passed.\0" as *const u8 + as *const libc::c_char, + ); + *certverifyresult = GNUTLS_CERT_EXPIRED as i32 as i64; + gnutls_x509_crt_deinit(x509_cert); + return CURLE_PEER_FAILED_VERIFICATION; + } else { + Curl_infof( + data, + b" server certificate expiration date FAILED\0" as *const u8 + as *const libc::c_char, + ); + } + } else { + Curl_infof( + data, + b" server certificate expiration date OK\0" as *const u8 as *const libc::c_char, + ); + } + /* Check for time-based validity */ + certclock = gnutls_x509_crt_get_activation_time(x509_cert); + if certclock == -(1 as i32) as time_t { + if SSL_CONN_CONFIG_verifypeer_1 != 0 { + Curl_failf( + data, + b"server cert activation date verify failed\0" as *const u8 + as *const libc::c_char, + ); + *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED as i64; + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_CONNECT_ERROR; + } else { + Curl_infof( + data, + b" server certificate activation date verify FAILED\0" as *const u8 + as *const libc::c_char, + ); + } + } else if certclock > time(0 as *mut time_t) { + if SSL_CONN_CONFIG_verifypeer_1 != 0 { + Curl_failf( + data, + b"server certificate not activated yet.\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED as i64; + gnutls_x509_crt_deinit(x509_cert); + return CURLE_PEER_FAILED_VERIFICATION; + } else { + Curl_infof( + data, + b" server certificate activation date FAILED\0" as *const u8 + as *const libc::c_char, + ); + } + } else { + Curl_infof( + data, + b" server certificate activation date OK\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_PINNED_PUB_KEY_void = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as usize] + } else { + (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_PINNED_PUB_KEY_void = (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize]; + ptr = SSL_PINNED_PUB_KEY_void; + if !ptr.is_null() { + result = pkp_pin_peer_pubkey(data, x509_cert, ptr); + if result as u32 != CURLE_OK as u32 { + Curl_failf( + data, + b"SSL: public key does not match pinned public key!\0" as *const u8 + as *const libc::c_char, + ); + gnutls_x509_crt_deinit(x509_cert); + return result; + } + } + + /* Show: + + - subject + - start date + - expire date + - common name + - issuer + + */ + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &mut bits) as u32; /* public key algorithm's parameters */ + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + Curl_infof( + data, + b" certificate public key: %s\0" as *const u8 as *const libc::c_char, + gnutls_pk_algorithm_get_name(algo as gnutls_pk_algorithm_t), + ); + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + Curl_infof( + data, + b" certificate version: #%d\0" as *const u8 as *const libc::c_char, + gnutls_x509_crt_get_version(x509_cert), + ); /* version of the X.509 certificate. */ + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + rc = gnutls_x509_crt_get_dn2(x509_cert, &mut certfields); + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + if rc != 0 { + Curl_infof( + data, + b"Failed to get certificate name\0" as *const u8 as *const libc::c_char, + ); + } else { + Curl_infof( + data, + b" subject: %s\0" as *const u8 as *const libc::c_char, + certfields.data, + ); + certclock = gnutls_x509_crt_get_activation_time(x509_cert); + showtime( + data, + b"start date\0" as *const u8 as *const libc::c_char, + certclock, + ); + certclock = gnutls_x509_crt_get_expiration_time(x509_cert); + showtime( + data, + b"expire date\0" as *const u8 as *const libc::c_char, + certclock, + ); + gnutls_free.expect("non-null function pointer")(certfields.data as *mut libc::c_void); + } + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &mut certfields); + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + if rc != 0 { + Curl_infof( + data, + b"Failed to get certificate issuer\0" as *const u8 as *const libc::c_char, + ); + } else { + Curl_infof( + data, + b" issuer: %s\0" as *const u8 as *const libc::c_char, + certfields.data, + ); + gnutls_free.expect("non-null function pointer")(certfields.data as *mut libc::c_void); + } + gnutls_x509_crt_deinit(x509_cert); + if ((*conn).bits).tls_enable_alpn() != 0 { + rc = gnutls_alpn_get_selected_protocol(session, &mut proto); + if rc == 0 as i32 { + Curl_infof( + data, + b"ALPN, server accepted to use %.*s\0" as *const u8 as *const libc::c_char, + proto.size, + proto.data, + ); + // done - 1254 + #[cfg(USE_HTTP2)] + let USE_HTTP2_flag = proto.size == 2 as u32 + && memcmp( + b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, + proto.data as *const libc::c_void, + 2 as u64, + ) == 0; + #[cfg(not(USE_HTTP2))] + let USE_HTTP2_flag = false; + if USE_HTTP2_flag { + (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; + } else if proto.size == 8 as u32 + && memcmp( + b"http/1.1\0" as *const u8 as *const libc::c_char as *const libc::c_void, + proto.data as *const libc::c_void, + 8 as u64, + ) == 0 + { + (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; + } + } else { + Curl_infof( + data, + b"ALPN, server did not agree to a protocol\0" as *const u8 + as *const libc::c_char, + ); + } + Curl_multiuse_state( + data, + if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as i32 { + 2 as i32 + } else { + -(1 as i32) + }, + ); + } + (*conn).ssl[sockindex as usize].state = ssl_connection_complete; + (*conn).recv[sockindex as usize] = Some(gtls_recv as Curl_recv); + (*conn).send[sockindex as usize] = Some(gtls_send as Curl_send); + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*data).set.proxy_ssl.primary).sessionid() as i32 + } else { + ((*data).set.ssl.primary).sessionid() as i32 + }; + + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = ((*data).set.ssl.primary).sessionid(); + if SSL_SET_OPTION_primary_sessionid != 0 { + /* we always unconditionally get the session id here, as even if we + already got it from the cache and asked to use it in the connection, it + might've been rejected and then a new one is in use now and we need to + detect that. */ + let mut connect_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + let mut connect_idsize: size_t = 0 as size_t; + /* get the session ID data size */ + gnutls_session_get_data(session, 0 as *mut libc::c_void, &mut connect_idsize); + /* get a buffer for it */ + match () { + #[cfg(not(CURLDEBUG))] + _ => { + connect_sessionid = + Curl_cmalloc.expect("non-null function pointer")(connect_idsize); + } + #[cfg(CURLDEBUG)] + _ => { + connect_sessionid = curl_dbg_malloc( + connect_idsize, + 1286 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + } + } + + if !connect_sessionid.is_null() { + let mut incache: bool = false; + let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + /* extract session ID to the allocated buffer */ + gnutls_session_get_data(session, connect_sessionid, &mut connect_idsize); + Curl_ssl_sessionid_lock(data); + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_IS_PROXY_void_1 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + 1 as i32 + } else { + 0 as i32 + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_IS_PROXY_void_1 = if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0; + incache = !Curl_ssl_getsessionid( + data, + conn, + SSL_IS_PROXY_void_1, + &mut ssl_sessionid, + 0 as *mut size_t, + sockindex, + ); + if incache { + /* there was one before in the cache, so instead of risking that the + previous one was rejected, we just kill that and store the new */ + Curl_ssl_delsessionid(data, ssl_sessionid); + } + /* store this session id */ + result = Curl_ssl_addsessionid( + data, + conn, + SSL_IS_PROXY_void_1, + connect_sessionid, + connect_idsize, + sockindex, + ); + Curl_ssl_sessionid_unlock(data); + if result as u64 != 0 { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(connect_sessionid); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + connect_sessionid, + 1312 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + result = CURLE_OUT_OF_MEMORY; + } + } else { + result = CURLE_OUT_OF_MEMORY; + } + } + return result; + } +} + +/* + * This function is called after the TCP connect has completed. Setup the TLS + * layer and do all necessary magic. + */ +/* We use connssl->connecting_state to keep track of the connection status; + there are three states: 'ssl_connect_1' (not started yet or complete), + 'ssl_connect_2_reading' (waiting for data from server), and + 'ssl_connect_2_writing' (waiting to be able to write). +*/ +extern "C" fn gtls_connect_common( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut nonblocking: bool, + mut done: *mut bool, +) -> CURLcode { + unsafe { + let mut rc: i32 = 0; + let mut connssl: *mut ssl_connect_data = + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; + /* Initiate the connection, if not already done */ + if ssl_connect_1 as u32 == (*connssl).connecting_state as u32 { + rc = gtls_connect_step1(data, conn, sockindex) as i32; + if rc != 0 { + return rc as CURLcode; + } + } + rc = handshake(data, conn, sockindex, 1 as i32 != 0, nonblocking) as i32; + if rc != 0 { + /* handshake() sets its own error message with failf() */ + return rc as CURLcode; + } + + /* Finish connecting once the handshake is done */ + if ssl_connect_1 as u32 == (*connssl).connecting_state as u32 { + rc = gtls_connect_step3(data, conn, sockindex) as i32; + if rc != 0 { + return rc as CURLcode; + } + } + *done = ssl_connect_1 as u32 == (*connssl).connecting_state as u32; + return CURLE_OK; + } +} +extern "C" fn gtls_connect_nonblocking( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut done: *mut bool, +) -> CURLcode { + unsafe { + return gtls_connect_common(data, conn, sockindex, 1 as i32 != 0, done); + } +} +extern "C" fn gtls_connect( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut done: bool = 0 as i32 != 0; + unsafe{ + result = gtls_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done); + if result as u64 != 0 { + return result; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if done { + } else { + __assert_fail( + b"done\0" as *const u8 as *const libc::c_char, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + 1384 as u32, + (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( + b"CURLcode gtls_connect(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + return CURLE_OK; + } +} +extern "C" fn gtls_data_pending(mut conn: *const connectdata, mut connindex: i32) -> bool { + let mut connssl: *const ssl_connect_data =unsafe{ + &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data}; + let mut res: bool = 0 as i32 != 0; + let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; + if unsafe{ !((*backend).session).is_null() + && 0 as u64 != gnutls_record_check_pending((*backend).session)} + { + res = 1 as i32 != 0; + } + #[cfg(not(CURL_DISABLE_PROXY))] + if true { + connssl = unsafe{ &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) + as *const ssl_connect_data}; + backend = unsafe{ (*connssl).backend}; + if unsafe{ !((*backend).session).is_null() + && 0 as u64 != gnutls_record_check_pending((*backend).session)} + { + res = 1 as i32 != 0; + } + } + + return res; + +} +extern "C" fn gtls_send( + mut data: *mut Curl_easy, + mut sockindex: i32, + mut mem: *const libc::c_void, + mut len: size_t, + mut curlcode: *mut CURLcode, +) -> ssize_t { + + let mut conn: *mut connectdata = unsafe{ (*data).conn}; + let mut connssl: *mut ssl_connect_data =unsafe{ + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data = unsafe{ (*connssl).backend}; + let mut rc: ssize_t =unsafe{ gnutls_record_send((*backend).session, mem, len)}; + unsafe{ + if rc < 0 as i64 { + *curlcode = (if rc == -(28 as i32) as i64 { + CURLE_AGAIN as i32 + } else { + CURLE_SEND_ERROR as i32 + }) as CURLcode; + rc = -(1 as i32) as ssize_t; + } + return rc; + } +} + +extern "C" fn close_one(mut connssl: *mut ssl_connect_data) { + + let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; + unsafe{ + if !((*backend).session).is_null() { + let mut buf: [libc::c_char; 32] = [0; 32]; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + + gnutls_record_recv( + (*backend).session, + buf.as_mut_ptr() as *mut libc::c_void, + ::std::mem::size_of::<[libc::c_char; 32]>() as u64, + ); + gnutls_bye((*backend).session, GNUTLS_SHUT_WR); + gnutls_deinit((*backend).session); + (*backend).session = 0 as gnutls_session_t; + } + if !((*backend).cred).is_null() { + gnutls_certificate_free_credentials((*backend).cred); + (*backend).cred = 0 as gnutls_certificate_credentials_t; + } + #[cfg(HAVE_GNUTLS_SRP)] + if !((*backend).srp_client_cred).is_null() { + gnutls_srp_free_client_credentials((*backend).srp_client_cred); + (*backend).srp_client_cred = 0 as gnutls_srp_client_credentials_t; + } + } +} +extern "C" fn gtls_close(mut data: *mut Curl_easy, mut conn: *mut connectdata, mut sockindex: i32) { + unsafe { + close_one(&mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize)); + #[cfg(not(CURL_DISABLE_PROXY))] + close_one(&mut *((*conn).proxy_ssl).as_mut_ptr().offset(sockindex as isize)); + } +} + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) */ - extern "C" fn gtls_connect_common( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut nonblocking: bool, - mut done: *mut bool, - ) -> CURLcode { - let mut rc: i32 = 0; - let mut connssl: *mut ssl_connect_data =unsafe{ - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; - /* Initiate the connection, if not already done */ - if ssl_connect_1 as u32 ==unsafe{ (*connssl).connecting_state as u32} { - rc = gtls_connect_step1(data, conn, sockindex) as i32; - if rc != 0 { - return rc as CURLcode; - } - } - rc = handshake(data, conn, sockindex, 1 as i32 != 0, nonblocking) as i32; - if rc != 0 { - /* handshake() sets its own error message with failf() */ - return rc as CURLcode; - } - - /* Finish connecting once the handshake is done */ - if ssl_connect_1 as u32 == unsafe{(*connssl).connecting_state as u32 }{ - rc = gtls_connect_step3(data, conn, sockindex) as i32; - if rc != 0 { - return rc as CURLcode; - } - } - unsafe{*done = ssl_connect_1 as u32 == (*connssl).connecting_state as u32;} - return CURLE_OK; - } - extern "C" fn gtls_connect_nonblocking( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut done: *mut bool, - ) -> CURLcode { - unsafe { - return gtls_connect_common(data, conn, sockindex, 1 as i32 != 0, done); - } - } - extern "C" fn gtls_connect( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut done: bool = 0 as i32 != 0; - result = gtls_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done); - if result as u64 != 0 { - return result; - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if done { - } else { - unsafe{ - __assert_fail( - b"done\0" as *const u8 as *const libc::c_char, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - 1384 as u32, - (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( - b"CURLcode gtls_connect(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - );} - } - return CURLE_OK; - - } - extern "C" fn gtls_data_pending(mut conn: *const connectdata, mut connindex: i32) -> bool { - let mut connssl: *const ssl_connect_data =unsafe{ - &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data}; - let mut res: bool = 0 as i32 != 0; - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - if unsafe{!((*backend).session).is_null() - && 0 as u64 != gnutls_record_check_pending((*backend).session)} - { - res = 1 as i32 != 0; - } - #[cfg(not(CURL_DISABLE_PROXY))] - if true { - connssl =unsafe{ &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) - as *const ssl_connect_data}; - backend = unsafe{(*connssl).backend}; - if unsafe{!((*backend).session).is_null() - && 0 as u64 != gnutls_record_check_pending((*backend).session)} - { - res = 1 as i32 != 0; - } - } - - return res; - } - extern "C" fn gtls_send( - mut data: *mut Curl_easy, - mut sockindex: i32, - mut mem: *const libc::c_void, - mut len: size_t, - mut curlcode: *mut CURLcode, - ) -> ssize_t { - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut connssl: *mut ssl_connect_data = - unsafe{&mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - let mut rc: ssize_t =unsafe{ gnutls_record_send((*backend).session, mem, len)}; - if rc < 0 as i64 { - unsafe{ *curlcode = (if rc == -(28 as i32) as i64 { - CURLE_AGAIN as i32 - } else { - CURLE_SEND_ERROR as i32 - }) as CURLcode; - rc = -(1 as i32) as ssize_t;} - } - return rc; - } - - extern "C" fn close_one(mut connssl: *mut ssl_connect_data) { - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - if unsafe{!((*backend).session).is_null()} { - let mut buf: [libc::c_char; 32] = [0; 32]; - /* Maybe the server has already sent a close notify alert. - Read it to avoid an RST on the TCP connection. */ - - unsafe{ gnutls_record_recv( - (*backend).session, - buf.as_mut_ptr() as *mut libc::c_void, - ::std::mem::size_of::<[libc::c_char; 32]>() as u64, - ); - gnutls_bye((*backend).session, GNUTLS_SHUT_WR); - gnutls_deinit((*backend).session); - (*backend).session = 0 as gnutls_session_t;} - } - if unsafe{!((*backend).cred).is_null()} { - unsafe{ - gnutls_certificate_free_credentials((*backend).cred); - (*backend).cred = 0 as gnutls_certificate_credentials_t;} - } - unsafe{ - #[cfg(HAVE_GNUTLS_SRP)] - if !((*backend).srp_client_cred).is_null() { - gnutls_srp_free_client_credentials((*backend).srp_client_cred); - (*backend).srp_client_cred = 0 as gnutls_srp_client_credentials_t; - }} +extern "C" fn gtls_shutdown( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> i32 { - } - extern "C" fn gtls_close(mut data: *mut Curl_easy, mut conn: *mut connectdata, mut sockindex: i32) { - unsafe { - close_one(&mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize)); - #[cfg(not(CURL_DISABLE_PROXY))] - close_one(&mut *((*conn).proxy_ssl).as_mut_ptr().offset(sockindex as isize)); - } - } - - /* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ - extern "C" fn gtls_shutdown( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) -> i32 { - let mut connssl: *mut ssl_connect_data = - unsafe{ &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - let mut retval: i32 = 0 as i32; - - /* This has only been tested on the proftpd server, and the mod_tls code - sends a close notify alert without waiting for a close notify alert in - response. Thus we wait for a close notify alert from the server, but - we do not send one. Let's hope other servers do the same... */ - unsafe{ - #[cfg(not(CURL_DISABLE_FTP))] - if (*data).set.ftp_ccc as u32 == CURLFTPSSL_CCC_ACTIVE as u32 { - gnutls_bye((*backend).session, GNUTLS_SHUT_WR); - } - if !((*backend).session).is_null() { - let mut result: ssize_t = 0; - let mut done: bool = 0 as i32 != 0; - let mut buf: [libc::c_char; 120] = [0; 120]; - while !done { - let mut what: i32 = Curl_socket_check( - (*conn).sock[sockindex as usize], - -(1 as i32), - -(1 as i32), - 10000 as timediff_t, - ); - if what > 0 as i32 { - /* Something to read, let's do it and hope that it is the close - notify alert from the server */ - result = gnutls_record_recv( - (*backend).session, - buf.as_mut_ptr() as *mut libc::c_void, - ::std::mem::size_of::<[libc::c_char; 120]>() as u64, - ); - match result { - 0 => { - /* This is the expected response. There was no data but only - the close notify alert */ - done = 1 as i32 != 0; - } - -28 | -52 => { - Curl_infof( - data, - b"GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\0" as *const u8 - as *const libc::c_char, - ); - } - _ => { - retval = -(1 as i32); - done = 1 as i32 != 0; - } - } - } else if 0 as i32 == what { - /* timeout */ - Curl_failf( - data, - b"SSL shutdown timeout\0" as *const u8 as *const libc::c_char, - ); - done = 1 as i32 != 0; - } else { - /* anything that gets here is fatally bad */ - Curl_failf( - data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, - *__errno_location(), - ); - retval = -(1 as i32); - done = 1 as i32 != 0; - } - } - gnutls_deinit((*backend).session); - } - gnutls_certificate_free_credentials((*backend).cred); - #[cfg(all(HAVE_GNUTLS_SRP, not(CURL_DISABLE_PROXY)))] - if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.authtype as u32 - } else { - (*data).set.ssl.authtype as u32 - }) == CURL_TLSAUTH_SRP as u32 - && !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }) - .is_null() - { - gnutls_srp_free_client_credentials((*backend).srp_client_cred); - } - #[cfg(all(HAVE_GNUTLS_SRP, CURL_DISABLE_PROXY))] - if (*data).set.ssl.authtype as u32 == CURL_TLSAUTH_SRP as u32 - && !((*data).set.ssl.username).is_null() - { - gnutls_srp_free_client_credentials((*backend).srp_client_cred); - } - (*backend).cred = 0 as gnutls_certificate_credentials_t; - (*backend).session = 0 as gnutls_session_t;} - return retval; - - } - - extern "C" fn gtls_recv( - mut data: *mut Curl_easy, - mut num: i32, - mut buf: *mut libc::c_char, - mut buffersize: size_t, - mut curlcode: *mut CURLcode, - ) -> ssize_t { + let mut connssl: *mut ssl_connect_data =unsafe{ + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; + let mut retval: i32 = 0 as i32; + unsafe{ + /* This has only been tested on the proftpd server, and the mod_tls code + sends a close notify alert without waiting for a close notify alert in + response. Thus we wait for a close notify alert from the server, but + we do not send one. Let's hope other servers do the same... */ + #[cfg(not(CURL_DISABLE_FTP))] + if (*data).set.ftp_ccc as u32 == CURLFTPSSL_CCC_ACTIVE as u32 { + gnutls_bye((*backend).session, GNUTLS_SHUT_WR); + } + if !((*backend).session).is_null() { + let mut result: ssize_t = 0; + let mut done: bool = 0 as i32 != 0; + let mut buf: [libc::c_char; 120] = [0; 120]; + while !done { + let mut what: i32 = Curl_socket_check( + (*conn).sock[sockindex as usize], + -(1 as i32), + -(1 as i32), + 10000 as timediff_t, + ); + if what > 0 as i32 { + /* Something to read, let's do it and hope that it is the close + notify alert from the server */ + result = gnutls_record_recv( + (*backend).session, + buf.as_mut_ptr() as *mut libc::c_void, + ::std::mem::size_of::<[libc::c_char; 120]>() as u64, + ); + match result { + 0 => { + /* This is the expected response. There was no data but only + the close notify alert */ + done = 1 as i32 != 0; + } + -28 | -52 => { + Curl_infof( + data, + b"GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\0" as *const u8 + as *const libc::c_char, + ); + } + _ => { + retval = -(1 as i32); + done = 1 as i32 != 0; + } + } + } else if 0 as i32 == what { + /* timeout */ + Curl_failf( + data, + b"SSL shutdown timeout\0" as *const u8 as *const libc::c_char, + ); + done = 1 as i32 != 0; + } else { + /* anything that gets here is fatally bad */ + Curl_failf( + data, + b"select/poll on SSL socket, errno: %d\0" as *const u8 + as *const libc::c_char, + *__errno_location(), + ); + retval = -(1 as i32); + done = 1 as i32 != 0; + } + } + gnutls_deinit((*backend).session); + } + gnutls_certificate_free_credentials((*backend).cred); + #[cfg(all(HAVE_GNUTLS_SRP, not(CURL_DISABLE_PROXY)))] + if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.authtype as u32 + } else { + (*data).set.ssl.authtype as u32 + }) == CURL_TLSAUTH_SRP as u32 + && !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }) + .is_null() + { + gnutls_srp_free_client_credentials((*backend).srp_client_cred); + } + #[cfg(all(HAVE_GNUTLS_SRP, CURL_DISABLE_PROXY))] + if (*data).set.ssl.authtype as u32 == CURL_TLSAUTH_SRP as u32 + && !((*data).set.ssl.username).is_null() + { + gnutls_srp_free_client_credentials((*backend).srp_client_cred); + } + (*backend).cred = 0 as gnutls_certificate_credentials_t; + (*backend).session = 0 as gnutls_session_t; + return retval; + } +} - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut connssl: *mut ssl_connect_data =unsafe{ - &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - let mut ret: ssize_t = 0; - ret = unsafe{gnutls_record_recv((*backend).session, buf as *mut libc::c_void, buffersize)}; - if ret == -(28 as i32) as i64 || ret == -(52 as i32) as i64 { - unsafe{*curlcode = CURLE_AGAIN; - return -(1 as i32) as ssize_t;} - } - if ret == -(37 as i32) as i64 { - /* BLOCKING call, this is bad but a work-around for now. Fixing this "the - proper way" takes a whole lot of work. */ - let mut result: CURLcode = handshake(data, conn, num, 0 as i32 != 0, 0 as i32 != 0); - if result as u64 != 0 { - /* handshake() writes error message on its own */ - unsafe{ *curlcode = result;} - } else { - unsafe{ *curlcode = CURLE_AGAIN;} /* then return as if this was a wouldblock */ - } - return -(1 as i32) as ssize_t; - } - if ret < 0 as i32 as i64 { - unsafe{Curl_failf( - data, - b"GnuTLS recv error (%d): %s\0" as *const u8 as *const libc::c_char, - ret as i32, - gnutls_strerror(ret as i32), - ); - *curlcode = CURLE_RECV_ERROR;} - return -(1 as i32) as ssize_t; - } - return ret; - - } - extern "C" fn gtls_session_free(mut ptr: *mut libc::c_void) { +extern "C" fn gtls_recv( + mut data: *mut Curl_easy, + mut num: i32, + mut buf: *mut libc::c_char, + mut buffersize: size_t, + mut curlcode: *mut CURLcode, +) -> ssize_t { + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut connssl: *mut ssl_connect_data =unsafe{ + &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; + let mut ret: ssize_t = 0; + unsafe{ + ret = gnutls_record_recv((*backend).session, buf as *mut libc::c_void, buffersize); + if ret == -(28 as i32) as i64 || ret == -(52 as i32) as i64 { + *curlcode = CURLE_AGAIN; + return -(1 as i32) as ssize_t; + } + if ret == -(37 as i32) as i64 { + /* BLOCKING call, this is bad but a work-around for now. Fixing this "the + proper way" takes a whole lot of work. */ + let mut result: CURLcode = handshake(data, conn, num, 0 as i32 != 0, 0 as i32 != 0); + if result as u64 != 0 { + /* handshake() writes error message on its own */ + *curlcode = result; + } else { + *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */ + } + return -(1 as i32) as ssize_t; + } + if ret < 0 as i32 as i64 { + Curl_failf( + data, + b"GnuTLS recv error (%d): %s\0" as *const u8 as *const libc::c_char, + ret as i32, + gnutls_strerror(ret as i32), + ); + *curlcode = CURLE_RECV_ERROR; + return -(1 as i32) as ssize_t; + } + return ret; + } +} +extern "C" fn gtls_session_free(mut ptr: *mut libc::c_void) { + unsafe { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(ptr); - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(ptr)}; - - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - ptr, - 1586 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - )}; - } - extern "C" fn gtls_version(mut buffer: *mut libc::c_char, mut size: size_t) -> size_t { - unsafe { - return curl_msnprintf( - buffer, - size, - b"GnuTLS/%s\0" as *const u8 as *const libc::c_char, - gnutls_check_version(0 as *const libc::c_char), - ) as size_t; - } - } - - /* data might be NULL! */ - extern "C" fn gtls_random( - mut data: *mut Curl_easy, - mut entropy: *mut u8, - mut length: size_t, - ) -> CURLcode { + #[cfg(CURLDEBUG)] + curl_dbg_free( + ptr, + 1586 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + } +} +extern "C" fn gtls_version(mut buffer: *mut libc::c_char, mut size: size_t) -> size_t { + unsafe { + return curl_msnprintf( + buffer, + size, + b"GnuTLS/%s\0" as *const u8 as *const libc::c_char, + gnutls_check_version(0 as *const libc::c_char), + ) as size_t; + } +} - let mut rc: i32 = 0; - rc = unsafe{gnutls_rnd(GNUTLS_RND_RANDOM, entropy as *mut libc::c_void, length)}; - return (if rc != 0 { - CURLE_FAILED_INIT as i32 - } else { - CURLE_OK as i32 - }) as CURLcode; - - } - extern "C" fn gtls_sha256sum( - mut tmp: *const u8, - mut tmplen: size_t, - mut sha256sum: *mut u8, - mut sha256len: size_t, - ) -> CURLcode { +/* data might be NULL! */ +extern "C" fn gtls_random( + mut data: *mut Curl_easy, + mut entropy: *mut u8, + mut length: size_t, +) -> CURLcode { - let mut SHA256pw: sha256_ctx = sha256_ctx { - state: [0; 8], - count: 0, - block: [0; 64], - index: 0, - }; - unsafe{ - nettle_sha256_init(&mut SHA256pw); - nettle_sha256_update(&mut SHA256pw, tmplen as size_t, tmp); - nettle_sha256_digest(&mut SHA256pw, sha256len as size_t, sha256sum);} - return CURLE_OK; - } - extern "C" fn gtls_cert_status_request() -> bool { - unsafe { - return 1 as i32 != 0; - } - } - extern "C" fn gtls_get_internals( - mut connssl: *mut ssl_connect_data, - mut info: CURLINFO, - ) -> *mut libc::c_void { + let mut rc: i32 = 0; + unsafe{ + rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy as *mut libc::c_void, length); + return (if rc != 0 { + CURLE_FAILED_INIT as i32 + } else { + CURLE_OK as i32 + }) as CURLcode; + } +} +extern "C" fn gtls_sha256sum( + mut tmp: *const u8, + mut tmplen: size_t, + mut sha256sum: *mut u8, + mut sha256len: size_t, +) -> CURLcode { - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - unsafe{ - return (*backend).session as *mut libc::c_void;} - } - #[no_mangle] - pub static mut Curl_ssl_gnutls: Curl_ssl = Curl_ssl { - info: { - curl_ssl_backend { - id: CURLSSLBACKEND_GNUTLS, - name: b"gnutls\0" as *const u8 as *const libc::c_char, - } - }, - supports: ((1 as i32) << 0 as i32 - | (1 as i32) << 1 as i32 - | (1 as i32) << 2 as i32 - | (1 as i32) << 4 as i32) as u32, - sizeof_ssl_backend_data: ::std::mem::size_of::() as u64, - init: Some(gtls_init as unsafe extern "C" fn() -> i32), - cleanup: Some(gtls_cleanup as unsafe extern "C" fn() -> ()), - version: Some(gtls_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t), - check_cxn: Some(Curl_none_check_cxn as unsafe extern "C" fn(*mut connectdata) -> i32), - shut_down: Some( - gtls_shutdown as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> i32, - ), - data_pending: Some(gtls_data_pending as unsafe extern "C" fn(*const connectdata, i32) -> bool), - random: Some(gtls_random as unsafe extern "C" fn(*mut Curl_easy, *mut u8, size_t) -> CURLcode), - cert_status_request: Some(gtls_cert_status_request as unsafe extern "C" fn() -> bool), - connect_blocking: Some( - gtls_connect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> CURLcode, - ), - connect_nonblocking: Some( - gtls_connect_nonblocking - as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32, *mut bool) -> CURLcode, - ), - getsock: Some( - Curl_ssl_getsock as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> i32, - ), - get_internals: Some( - gtls_get_internals - as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, - ), - close_one: Some( - gtls_close as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), - ), - close_all: Some(Curl_none_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), - session_free: Some(gtls_session_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), - set_engine: Some( - Curl_none_set_engine - as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, - ), - set_engine_default: Some( - Curl_none_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, - ), - engines_list: Some( - Curl_none_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, - ), - false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), - sha256sum: Some( - gtls_sha256sum as unsafe extern "C" fn(*const u8, size_t, *mut u8, size_t) -> CURLcode, - ), - associate_connection: None, - disassociate_connection: None, - }; - \ No newline at end of file + let mut SHA256pw: sha256_ctx =unsafe{ sha256_ctx { + state: [0; 8], + count: 0, + block: [0; 64], + index: 0, + }}; + unsafe{ + nettle_sha256_init(&mut SHA256pw); + nettle_sha256_update(&mut SHA256pw, tmplen as size_t, tmp); + nettle_sha256_digest(&mut SHA256pw, sha256len as size_t, sha256sum); + return CURLE_OK; + } +} +extern "C" fn gtls_cert_status_request() -> bool { + unsafe { + return 1 as i32 != 0; + } +} +extern "C" fn gtls_get_internals( + mut connssl: *mut ssl_connect_data, + mut info: CURLINFO, +) -> *mut libc::c_void { + unsafe { + let mut backend: *mut ssl_backend_data = (*connssl).backend; + return (*backend).session as *mut libc::c_void; + } +} +#[no_mangle] +pub static mut Curl_ssl_gnutls: Curl_ssl = Curl_ssl { + info: { + curl_ssl_backend { + id: CURLSSLBACKEND_GNUTLS, + name: b"gnutls\0" as *const u8 as *const libc::c_char, + } + }, + supports: ((1 as i32) << 0 as i32 + | (1 as i32) << 1 as i32 + | (1 as i32) << 2 as i32 + | (1 as i32) << 4 as i32) as u32, + sizeof_ssl_backend_data: ::std::mem::size_of::() as u64, + init: Some(gtls_init as unsafe extern "C" fn() -> i32), + cleanup: Some(gtls_cleanup as unsafe extern "C" fn() -> ()), + version: Some(gtls_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t), + check_cxn: Some(Curl_none_check_cxn as unsafe extern "C" fn(*mut connectdata) -> i32), + shut_down: Some( + gtls_shutdown as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> i32, + ), + data_pending: Some(gtls_data_pending as unsafe extern "C" fn(*const connectdata, i32) -> bool), + random: Some(gtls_random as unsafe extern "C" fn(*mut Curl_easy, *mut u8, size_t) -> CURLcode), + cert_status_request: Some(gtls_cert_status_request as unsafe extern "C" fn() -> bool), + connect_blocking: Some( + gtls_connect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> CURLcode, + ), + connect_nonblocking: Some( + gtls_connect_nonblocking + as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32, *mut bool) -> CURLcode, + ), + getsock: Some( + Curl_ssl_getsock as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> i32, + ), + get_internals: Some( + gtls_get_internals + as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, + ), + close_one: Some( + gtls_close as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), + ), + close_all: Some(Curl_none_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), + session_free: Some(gtls_session_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), + set_engine: Some( + Curl_none_set_engine + as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, + ), + set_engine_default: Some( + Curl_none_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, + ), + engines_list: Some( + Curl_none_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, + ), + false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), + sha256sum: Some( + gtls_sha256sum as unsafe extern "C" fn(*const u8, size_t, *mut u8, size_t) -> CURLcode, + ), + associate_connection: None, + disassociate_connection: None, +}; diff --git a/rust/rust_project/src/vtls/keylog.rs b/rust/rust_project/src/vtls/keylog.rs index 4c5f7d9..8c796a0 100644 --- a/rust/rust_project/src/vtls/keylog.rs +++ b/rust/rust_project/src/vtls/keylog.rs @@ -263,11 +263,9 @@ mod tests { #[test] fn test_keylog() { - unsafe { - Curl_tls_keylog_open(); - Curl_tls_keylog_write_line(b"0123456789ABCDEF\0" as *const u8 as *const libc::c_char); - assert_eq!(Curl_tls_keylog_enabled(), true); - Curl_tls_keylog_close(); - } + Curl_tls_keylog_open(); + Curl_tls_keylog_write_line(b"0123456789ABCDEF\0" as *const u8 as *const libc::c_char); + assert_eq!(Curl_tls_keylog_enabled(), true); + Curl_tls_keylog_close(); } } diff --git a/rust/rust_project/src/vtls/mbedtls.rs b/rust/rust_project/src/vtls/mbedtls.rs index cb5835f..8df5007 100644 --- a/rust/rust_project/src/vtls/mbedtls.rs +++ b/rust/rust_project/src/vtls/mbedtls.rs @@ -8,2289 +8,2267 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: pnext, + * Author: pnext, * Create: 2022-10-31 * Description: support mbedtls backend ******************************************************************************/ - use ::libc; - use rust_ffi::src::ffi_alias::type_alias::*; - use rust_ffi::src::ffi_fun::fun_call::*; - use rust_ffi::src::ffi_struct::struct_define::*; - use crate::src::vtls::vtls::*; - - /* - todo - 需要不开选项 MBEDTLS_ERROR_C 再翻译一次 - #ifndef MBEDTLS_ERROR_C - #define mbedtls_strerror(a,b,c) b[0] = 0 - #endif - */ - - //有一个漏翻译的 - #[cfg(THREADING_SUPPORT)] - static mut ts_entropy: mbedtls_entropy_context = mbedtls_entropy_context { - accumulator_started: 0, - accumulator: mbedtls_sha512_context { - total: [0; 2], - state: [0; 8], - buffer: [0; 128], - is384: 0, - }, - source_count: 0, - source: [mbedtls_entropy_source_state { - f_source: None, - p_source: 0 as *const libc::c_void as *mut libc::c_void, - size: 0, - threshold: 0, - strong: 0, - }; 20], - havege_data: mbedtls_havege_state { - PT1: 0, - PT2: 0, - offset: [0; 2], - pool: [0; 1024], - WALK: [0; 8192], - }, - mutex: mbedtls_threading_mutex_t { - mutex: pthread_mutex_t { - __data: __pthread_mutex_s { - __lock: 0, - __count: 0, - __owner: 0, - __nusers: 0, - __kind: 0, - __spins: 0, - __elision: 0, - __list: __pthread_list_t { - __prev: 0 as *const __pthread_internal_list - as *mut __pthread_internal_list, - __next: 0 as *const __pthread_internal_list - as *mut __pthread_internal_list, - }, - }, - }, - is_valid: 0, - }, - }; - #[cfg(THREADING_SUPPORT)] - static mut entropy_init_initialized: libc::c_int = 0 as libc::c_int; - #[cfg(THREADING_SUPPORT)] +use crate::src::vtls::vtls::*; +use ::libc; +use rust_ffi::src::ffi_alias::type_alias::*; +use rust_ffi::src::ffi_fun::fun_call::*; +use rust_ffi::src::ffi_struct::struct_define::*; + +/* +todo +需要不开选项 MBEDTLS_ERROR_C 再翻译一次 +#ifndef MBEDTLS_ERROR_C +#define mbedtls_strerror(a,b,c) b[0] = 0 +#endif +*/ + +//有一个漏翻译的 +#[cfg(THREADING_SUPPORT)] +static mut ts_entropy: mbedtls_entropy_context = mbedtls_entropy_context { + accumulator_started: 0, + accumulator: mbedtls_sha512_context { + total: [0; 2], + state: [0; 8], + buffer: [0; 128], + is384: 0, + }, + source_count: 0, + source: [mbedtls_entropy_source_state { + f_source: None, + p_source: 0 as *const libc::c_void as *mut libc::c_void, + size: 0, + threshold: 0, + strong: 0, + }; 20], + havege_data: mbedtls_havege_state { + PT1: 0, + PT2: 0, + offset: [0; 2], + pool: [0; 1024], + WALK: [0; 8192], + }, + mutex: mbedtls_threading_mutex_t { + mutex: pthread_mutex_t { + __data: __pthread_mutex_s { + __lock: 0, + __count: 0, + __owner: 0, + __nusers: 0, + __kind: 0, + __spins: 0, + __elision: 0, + __list: __pthread_list_t { + __prev: 0 as *const __pthread_internal_list as *mut __pthread_internal_list, + __next: 0 as *const __pthread_internal_list as *mut __pthread_internal_list, + }, + }, + }, + is_valid: 0, + }, +}; +#[cfg(THREADING_SUPPORT)] +static mut entropy_init_initialized: i32 = 0 as i32; +#[cfg(THREADING_SUPPORT)] extern "C" fn entropy_init_mutex(mut ctx: *mut mbedtls_entropy_context) { - unsafe{ - Curl_mbedtlsthreadlock_lock_function(0 as libc::c_int); - if entropy_init_initialized == 0 as libc::c_int { - mbedtls_entropy_init(ctx); - entropy_init_initialized = 1 as libc::c_int; - } - Curl_mbedtlsthreadlock_unlock_function(0 as libc::c_int);} - } - #[cfg(THREADING_SUPPORT)] + unsafe { + Curl_mbedtlsthreadlock_lock_function(0 as i32); + if entropy_init_initialized == 0 as i32 { + mbedtls_entropy_init(ctx); + entropy_init_initialized = 1 as i32; + } + Curl_mbedtlsthreadlock_unlock_function(0 as i32); + } +} +#[cfg(THREADING_SUPPORT)] extern "C" fn entropy_func_mutex( - mut data: *mut libc::c_void, - mut output: *mut libc::c_uchar, - mut len: size_t, - ) -> libc::c_int { - let mut ret: libc::c_int = 0; - unsafe{Curl_mbedtlsthreadlock_lock_function(1 as libc::c_int); - ret = mbedtls_entropy_func(data, output, len); - Curl_mbedtlsthreadlock_unlock_function(1 as libc::c_int);} - return ret; - } - // 132 done - // MBEDTLS_DEBUG 暂不添加 - - /* - todo - #ifdef USE_NGHTTP2 - # undef HAS_ALPN - # ifdef MBEDTLS_SSL_ALPN - # define HAS_ALPN - # endif - #endif - */ - // 内部没有宏 - static mut mbedtls_x509_crt_profile_fr: mbedtls_x509_crt_profile = { - mbedtls_x509_crt_profile { - allowed_mds: ((1 as libc::c_int) - << MBEDTLS_MD_SHA1 as libc::c_int - 1 as libc::c_int - | (1 as libc::c_int) - << MBEDTLS_MD_RIPEMD160 as libc::c_int - 1 as libc::c_int - | (1 as libc::c_int) << MBEDTLS_MD_SHA224 as libc::c_int - 1 as libc::c_int - | (1 as libc::c_int) << MBEDTLS_MD_SHA256 as libc::c_int - 1 as libc::c_int - | (1 as libc::c_int) << MBEDTLS_MD_SHA384 as libc::c_int - 1 as libc::c_int - | (1 as libc::c_int) << MBEDTLS_MD_SHA512 as libc::c_int - 1 as libc::c_int) - as uint32_t, - allowed_pks: 0xfffffff as libc::c_int as uint32_t, - allowed_curves: 0xfffffff as libc::c_int as uint32_t, - rsa_min_bitlen: 1024 as libc::c_int as uint32_t, - } - }; - - // done -extern "C" fn mbedtls_version_from_curl( - mut mbedver: *mut libc::c_int, - mut version: libc::c_long, - ) -> CURLcode { - // 189-done - // #if MBEDTLS_VERSION_NUMBER >= 0x03000000 - if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000){ - // todo - } - else{ - unsafe{ - match version { - 4 => { - *mbedver = 1 as libc::c_int; - return CURLE_OK; - } - 5 => { - *mbedver = 2 as libc::c_int; - return CURLE_OK; - } - 6 => { - *mbedver = 3 as libc::c_int; - return CURLE_OK; - } - 7 | _ => {} - } - }} - return CURLE_SSL_CONNECT_ERROR; - } - - // done + mut data: *mut libc::c_void, + mut output: *mut u8, + mut len: size_t, +) -> i32 { + let mut ret: i32 = 0; + unsafe { + Curl_mbedtlsthreadlock_lock_function(1 as i32); + ret = mbedtls_entropy_func(data, output, len); + Curl_mbedtlsthreadlock_unlock_function(1 as i32); + } + return ret; +} +// 132 done +// MBEDTLS_DEBUG 暂不添加 + +/* +todo +#ifdef USE_NGHTTP2 +# undef HAS_ALPN +# ifdef MBEDTLS_SSL_ALPN +# define HAS_ALPN +# endif +#endif +*/ +// 内部没有宏 +static mut mbedtls_x509_crt_profile_fr: mbedtls_x509_crt_profile = { + mbedtls_x509_crt_profile { + allowed_mds: ((1 as i32) << MBEDTLS_MD_SHA1 as i32 - 1 as i32 + | (1 as i32) << MBEDTLS_MD_RIPEMD160 as i32 - 1 as i32 + | (1 as i32) << MBEDTLS_MD_SHA224 as i32 - 1 as i32 + | (1 as i32) << MBEDTLS_MD_SHA256 as i32 - 1 as i32 + | (1 as i32) << MBEDTLS_MD_SHA384 as i32 - 1 as i32 + | (1 as i32) << MBEDTLS_MD_SHA512 as i32 - 1 as i32) as uint32_t, + allowed_pks: 0xfffffff as i32 as uint32_t, + allowed_curves: 0xfffffff as i32 as uint32_t, + rsa_min_bitlen: 1024 as i32 as uint32_t, + } +}; + +// done +extern "C" fn mbedtls_version_from_curl(mut mbedver: *mut i32, mut version: i64) -> CURLcode { + // 189-done + // #if MBEDTLS_VERSION_NUMBER >= 0x03000000 + if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000) { + // todo + } else { + unsafe { + match version { + 4 => { + *mbedver = 1 as i32; + return CURLE_OK; + } + 5 => { + *mbedver = 2 as i32; + return CURLE_OK; + } + 6 => { + *mbedver = 3 as i32; + return CURLE_OK; + } + 7 | _ => {} + } + } + } + return CURLE_SSL_CONNECT_ERROR; +} + +// done extern "C" fn set_ssl_version_min_max( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: libc::c_int, - ) -> CURLcode { - let mut connssl: *mut ssl_connect_data = unsafe{&mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; - let mut mbedtls_ver_min: libc::c_int = 1 as libc::c_int; - let mut mbedtls_ver_max: libc::c_int = 1 as libc::c_int; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_version =unsafe{ if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == (*conn).http_proxy.proxytype as libc::c_uint - && ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint - { - (*conn).proxy_ssl_config.version - } else { - (*conn).ssl_config.version - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_version = unsafe{(*conn).ssl_config.version}; - let mut ssl_version: libc::c_long = SSL_CONN_CONFIG_version; - let mut ssl_version_max: libc::c_long = SSL_CONN_CONFIG_version; - let mut result: CURLcode = CURLE_OK; - match ssl_version { - 0 | 1 => { - ssl_version = CURL_SSLVERSION_TLSv1_0 as libc::c_int as libc::c_long; - } - _ => {} - } - match ssl_version_max { - 0 | 65536 => { - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2 as libc::c_int as libc::c_long; - } - _ => {} - } - result = mbedtls_version_from_curl(&mut mbedtls_ver_min, ssl_version); - if result as u64 != 0 { - unsafe{ Curl_failf( - data, - b"unsupported min version passed via CURLOPT_SSLVERSION\0" as *const u8 - as *const libc::c_char, - );} - return result; - } - result = mbedtls_version_from_curl( - &mut mbedtls_ver_max, - ssl_version_max >> 16 as libc::c_int, - ); - if result as u64 != 0 { - unsafe{ Curl_failf( - data, - b"unsupported max version passed via CURLOPT_SSLVERSION\0" as *const u8 - as *const libc::c_char, - );} - return result; - } - unsafe{mbedtls_ssl_conf_min_version( - &mut (*backend).config, - 3 as libc::c_int, - mbedtls_ver_min, - ); - mbedtls_ssl_conf_max_version( - &mut (*backend).config, - 3 as libc::c_int, - mbedtls_ver_max, - );} - return result; - } - - // done + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut mbedtls_ver_min: i32 = 1 as i32; + let mut mbedtls_ver_max: i32 = 1 as i32; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_version = unsafe { + if CURLPROXY_HTTPS as i32 as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.version + } else { + (*conn).ssl_config.version + } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_version = unsafe { (*conn).ssl_config.version }; + let mut ssl_version: i64 = SSL_CONN_CONFIG_version; + let mut ssl_version_max: i64 = SSL_CONN_CONFIG_version; + let mut result: CURLcode = CURLE_OK; + match ssl_version { + 0 | 1 => { + ssl_version = CURL_SSLVERSION_TLSv1_0 as i32 as i64; + } + _ => {} + } + match ssl_version_max { + 0 | 65536 => { + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2 as i32 as i64; + } + _ => {} + } + result = mbedtls_version_from_curl(&mut mbedtls_ver_min, ssl_version); + if result as u64 != 0 { + unsafe { + Curl_failf( + data, + b"unsupported min version passed via CURLOPT_SSLVERSION\0" as *const u8 + as *const libc::c_char, + ); + } + return result; + } + result = mbedtls_version_from_curl(&mut mbedtls_ver_max, ssl_version_max >> 16 as i32); + if result as u64 != 0 { + unsafe { + Curl_failf( + data, + b"unsupported max version passed via CURLOPT_SSLVERSION\0" as *const u8 + as *const libc::c_char, + ); + } + return result; + } + unsafe { + mbedtls_ssl_conf_min_version(&mut (*backend).config, 3 as i32, mbedtls_ver_min); + mbedtls_ssl_conf_max_version(&mut (*backend).config, 3 as i32, mbedtls_ver_max); + } + return result; +} + +// done extern "C" fn mbed_connect_step1( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: libc::c_int, - ) -> CURLcode { - let mut connssl: *mut ssl_connect_data = unsafe{&mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - #[cfg(not(CURL_DISABLE_PROXY))] - let ssl_cafile: *const libc::c_char = if CURLPROXY_HTTPS as libc::c_int - as libc::c_uint == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && ssl_connection_complete as libc::c_int as libc::c_uint - != unsafe{(*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*conn).proxy_ssl_config.CAfile} - } else { - unsafe{(*conn).ssl_config.CAfile} - }; - #[cfg(CURL_DISABLE_PROXY)] - let ssl_cafile: *const libc::c_char = unsafe{(*conn).ssl_config.CAfile}; - #[cfg(not(CURL_DISABLE_PROXY))] - let verifypeer: bool = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{((*conn).proxy_ssl_config).verifypeer() as libc::c_int} - } else { - unsafe{ ((*conn).ssl_config).verifypeer() as libc::c_int} - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let verifypeer: bool = unsafe{((*conn).ssl_config).verifypeer() != 0}; - #[cfg(not(CURL_DISABLE_PROXY))] - let ssl_capath: *const libc::c_char = if CURLPROXY_HTTPS as libc::c_int - as libc::c_uint == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && ssl_connection_complete as libc::c_int as libc::c_uint - != unsafe{(*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*conn).proxy_ssl_config.CApath} - } else { - unsafe{(*conn).ssl_config.CApath} - }; - #[cfg(CURL_DISABLE_PROXY)] - let ssl_capath: *const libc::c_char = unsafe{(*conn).ssl_config.CApath}; - #[cfg(not(CURL_DISABLE_PROXY))] - let ssl_cert: *mut libc::c_char = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*data).set.proxy_ssl.primary.clientcert} - } else { - unsafe{ (*data).set.ssl.primary.clientcert} - }; - #[cfg(CURL_DISABLE_PROXY)] - let ssl_cert: *mut libc::c_char = unsafe{(*data).set.ssl.primary.clientcert}; - #[cfg(not(CURL_DISABLE_PROXY))] - let mut ssl_cert_blob: *const curl_blob = if CURLPROXY_HTTPS as libc::c_int - as libc::c_uint == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*data).set.proxy_ssl.primary.cert_blob} - } else { - unsafe{(*data).set.ssl.primary.cert_blob} - }; - #[cfg(CURL_DISABLE_PROXY)] - let mut ssl_cert_blob: *const curl_blob = unsafe{(*data).set.ssl.primary.cert_blob}; - #[cfg(not(CURL_DISABLE_PROXY))] - let ssl_crlfile: *const libc::c_char = if CURLPROXY_HTTPS as libc::c_int - as libc::c_uint == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*data).set.proxy_ssl.CRLfile} - } else { - unsafe{(*data).set.ssl.CRLfile} - }; - #[cfg(CURL_DISABLE_PROXY)] - let ssl_crlfile: *const libc::c_char = (*data).set.ssl.CRLfile; - #[cfg(not(CURL_DISABLE_PROXY))] - let hostname: *const libc::c_char = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && ssl_connection_complete as libc::c_int as libc::c_uint - != unsafe{(*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*conn).http_proxy.host.name} - } else { - unsafe{(*conn).host.name} - }; - #[cfg(CURL_DISABLE_PROXY)] - let hostname: *const libc::c_char = unsafe{(*conn).host.name}; - // 280-282 - /* - #ifndef CURL_DISABLE_VERBOSE_STRINGS - const long int port = SSL_HOST_PORT(); - #endif - */ - #[cfg(all(not(CURL_DISABLE_VERBOSE_STRINGS), not(CURL_DISABLE_PROXY)))] - let port: libc::c_long = (if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*conn).port} - } else { - unsafe{(*conn).remote_port} - }) as libc::c_long; - #[cfg(all(not(CURL_DISABLE_VERBOSE_STRINGS), CURL_DISABLE_PROXY))] - let port: libc::c_long =unsafe{ (*conn).remote_port as libc::c_long}; - - let mut ret: libc::c_int = -(1 as libc::c_int); - let mut errorbuf: [libc::c_char; 128] = [0; 128]; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_version =unsafe{ if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == (*conn).http_proxy.proxytype as libc::c_uint - && ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint - { - (*conn).proxy_ssl_config.version - } else { - (*conn).ssl_config.version - }}; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_version =unsafe{ (*conn).ssl_config.version}; + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + #[cfg(not(CURL_DISABLE_PROXY))] + let ssl_cafile: *const libc::c_char = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as i32 as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.CAfile } + } else { + unsafe { (*conn).ssl_config.CAfile } + }; + #[cfg(CURL_DISABLE_PROXY)] + let ssl_cafile: *const libc::c_char = unsafe { (*conn).ssl_config.CAfile }; + #[cfg(not(CURL_DISABLE_PROXY))] + let verifypeer: bool = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifypeer() as i32 } + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let verifypeer: bool = unsafe { ((*conn).ssl_config).verifypeer() != 0 }; + #[cfg(not(CURL_DISABLE_PROXY))] + let ssl_capath: *const libc::c_char = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as i32 as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.CApath } + } else { + unsafe { (*conn).ssl_config.CApath } + }; + #[cfg(CURL_DISABLE_PROXY)] + let ssl_capath: *const libc::c_char = unsafe { (*conn).ssl_config.CApath }; + #[cfg(not(CURL_DISABLE_PROXY))] + let ssl_cert: *mut libc::c_char = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*data).set.proxy_ssl.primary.clientcert } + } else { + unsafe { (*data).set.ssl.primary.clientcert } + }; + #[cfg(CURL_DISABLE_PROXY)] + let ssl_cert: *mut libc::c_char = unsafe { (*data).set.ssl.primary.clientcert }; + #[cfg(not(CURL_DISABLE_PROXY))] + let mut ssl_cert_blob: *const curl_blob = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*data).set.proxy_ssl.primary.cert_blob } + } else { + unsafe { (*data).set.ssl.primary.cert_blob } + }; + #[cfg(CURL_DISABLE_PROXY)] + let mut ssl_cert_blob: *const curl_blob = unsafe { (*data).set.ssl.primary.cert_blob }; + #[cfg(not(CURL_DISABLE_PROXY))] + let ssl_crlfile: *const libc::c_char = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*data).set.proxy_ssl.CRLfile } + } else { + unsafe { (*data).set.ssl.CRLfile } + }; + #[cfg(CURL_DISABLE_PROXY)] + let ssl_crlfile: *const libc::c_char = unsafe { (*data).set.ssl.CRLfile }; + #[cfg(not(CURL_DISABLE_PROXY))] + let hostname: *const libc::c_char = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as i32 as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).http_proxy.host.name } + } else { + unsafe { (*conn).host.name } + }; + #[cfg(CURL_DISABLE_PROXY)] + let hostname: *const libc::c_char = unsafe { (*conn).host.name }; + // 280-282 + /* + #ifndef CURL_DISABLE_VERBOSE_STRINGS + const long int port = SSL_HOST_PORT(); + #endif + */ + #[cfg(all(not(CURL_DISABLE_VERBOSE_STRINGS), not(CURL_DISABLE_PROXY)))] + let port: i64 = (if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).port } + } else { + unsafe { (*conn).remote_port } + }) as i64; + #[cfg(all(not(CURL_DISABLE_VERBOSE_STRINGS), CURL_DISABLE_PROXY))] + let port: i64 = unsafe { (*conn).remote_port as i64 }; - if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv2 as libc::c_int as libc::c_long - || SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv3 as libc::c_int as libc::c_long - { - unsafe{Curl_failf( - data, - b"Not supported SSL version\0" as *const u8 as *const libc::c_char, - );} - return CURLE_NOT_BUILT_IN; - } - - unsafe{ - // 292-314 - match () { - #[cfg(THREADING_SUPPORT)] - _ => { - entropy_init_mutex(&mut ts_entropy); - mbedtls_ctr_drbg_init(&mut (*backend).ctr_drbg); - ret = mbedtls_ctr_drbg_seed( - &mut (*backend).ctr_drbg, - Some( - entropy_func_mutex - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_uchar, - size_t, - ) -> libc::c_int, - ), - &mut ts_entropy as *mut mbedtls_entropy_context as *mut libc::c_void, - 0 as *const libc::c_uchar, - 0 as libc::c_int as size_t, - ); - if ret != 0 { - mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\0" as *const u8 - as *const libc::c_char, - -ret, - errorbuf.as_mut_ptr(), - ); - } - } - #[cfg(not(THREADING_SUPPORT))] - _ => { } - } - } - unsafe{ - mbedtls_x509_crt_init(&mut (*backend).cacert);} - if !ssl_cafile.is_null() { - ret = unsafe{mbedtls_x509_crt_parse_file(&mut (*backend).cacert, ssl_cafile)}; - if ret < 0 as libc::c_int { - unsafe{mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"Error reading ca cert file %s - mbedTLS: (-0x%04X) %s\0" as *const u8 - as *const libc::c_char, - ssl_cafile, - -ret, - errorbuf.as_mut_ptr(), - );} - if verifypeer { - return CURLE_SSL_CACERT_BADFILE; - } - } - } + let mut ret: i32 = -(1 as i32); + let mut errorbuf: [libc::c_char; 128] = [0; 128]; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_version = unsafe { + if CURLPROXY_HTTPS as i32 as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.version + } else { + (*conn).ssl_config.version + } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_version = unsafe { (*conn).ssl_config.version }; - if !ssl_capath.is_null() { - ret = unsafe{ mbedtls_x509_crt_parse_path(&mut (*backend).cacert, ssl_capath)}; - if ret < 0 as libc::c_int { - unsafe{mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"Error reading ca cert path %s - mbedTLS: (-0x%04X) %s\0" as *const u8 - as *const libc::c_char, - ssl_capath, - -ret, - errorbuf.as_mut_ptr(), - );} - if verifypeer { - return CURLE_SSL_CACERT_BADFILE; - } - } - } - - unsafe{mbedtls_x509_crt_init(&mut (*backend).clicert);} - if !ssl_cert.is_null() { - ret = unsafe{mbedtls_x509_crt_parse_file(&mut (*backend).clicert, ssl_cert)}; - if ret != 0 { - unsafe{mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"Error reading client cert file %s - mbedTLS: (-0x%04X) %s\0" - as *const u8 as *const libc::c_char, - ssl_cert, - -ret, - errorbuf.as_mut_ptr(), - );} - return CURLE_SSL_CERTPROBLEM; - } - } + if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv2 as i32 as i64 + || SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv3 as i32 as i64 + { + unsafe { + Curl_failf( + data, + b"Not supported SSL version\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_NOT_BUILT_IN; + } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_key = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - ==unsafe{ (*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*data).set.proxy_ssl.key} - } else { - unsafe{ (*data).set.ssl.key} - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_key =unsafe{(*data).set.ssl.key}; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_key_blob = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{ (*data).set.proxy_ssl.key_blob} - } else { - unsafe{ (*data).set.ssl.key_blob} - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_key_blob = unsafe{(*data).set.ssl.key_blob}; - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_key_passwd = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - ==unsafe{ (*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*data).set.proxy_ssl.key_passwd} - } else { - unsafe{(*data).set.ssl.key_passwd} - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_key_passwd = unsafe{(*data).set.ssl.key_passwd}; - - if !ssl_cert_blob.is_null() { - let mut blob_data: *const libc::c_uchar = unsafe{(*ssl_cert_blob).data - as *const libc::c_uchar}; - ret = unsafe{mbedtls_x509_crt_parse( - &mut (*backend).clicert, - blob_data, - (*ssl_cert_blob).len, - )}; - if ret != 0 { - unsafe{mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"Error reading private key %s - mbedTLS: (-0x%04X) %s\0" as *const u8 - as *const libc::c_char, - SSL_SET_OPTION_key, - -ret, - errorbuf.as_mut_ptr(), - );} - return CURLE_SSL_CERTPROBLEM; - } - } - unsafe{mbedtls_pk_init(&mut (*backend).pk);} - // 377 - if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) { - - if !(SSL_SET_OPTION_key).is_null() || !(SSL_SET_OPTION_key_blob).is_null(){ // 377 - if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) { - // 378 - if(SSL_SET_OPTION(key)) { - if !(SSL_SET_OPTION_key).is_null() - { // 378 - if(SSL_SET_OPTION(key)) { - ret = unsafe{mbedtls_pk_parse_keyfile( - &mut (*backend).pk, - SSL_SET_OPTION_key, - SSL_SET_OPTION_key_passwd, - )}; - if ret != 0 { - unsafe{mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - );} - unsafe{Curl_failf( - data, - b"Error reading private key %s - mbedTLS: (-0x%04X) %s\0" - as *const u8 as *const libc::c_char, - SSL_SET_OPTION_key, - -ret, - errorbuf.as_mut_ptr(), - );} - return CURLE_SSL_CERTPROBLEM; - } - } else { - let mut ssl_key_blob: *const curl_blob = SSL_SET_OPTION_key_blob; - let mut key_data: *const libc::c_uchar = unsafe{(*ssl_key_blob).data - as *const libc::c_uchar}; - let mut passwd: *const libc::c_char = SSL_SET_OPTION_key_passwd; - // 401-done - // #if MBEDTLS_VERSION_NUMBER >= 0x03000000 - if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000){ - // todo-402 - /* - todo - ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, - (const unsigned char *)passwd, - passwd ? strlen(passwd) : 0, - mbedtls_ctr_drbg_random, - &backend->ctr_drbg); - */ - } - else{ - ret =unsafe{ mbedtls_pk_parse_key( - &mut (*backend).pk, - key_data, - (*ssl_key_blob).len, - passwd as *const libc::c_uchar, - if !passwd.is_null() { - strlen(passwd) - } else { - 0 as libc::c_int as libc::c_ulong - }, - )}; - } - - if ret != 0 { - unsafe{mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"Error parsing private key - mbedTLS: (-0x%04X) %s\0" as *const u8 - as *const libc::c_char, - -ret, - errorbuf.as_mut_ptr(), - );} - return CURLE_SSL_CERTPROBLEM; - } - } - if ret == 0 as libc::c_int - && unsafe{!(mbedtls_pk_can_do(&mut (*backend).pk, MBEDTLS_PK_RSA) != 0 - || mbedtls_pk_can_do(&mut (*backend).pk, MBEDTLS_PK_ECKEY) != 0)} - { - ret = -(0x3f00 as libc::c_int); - } - } - - unsafe{mbedtls_x509_crl_init(&mut (*backend).crl);} - if !ssl_crlfile.is_null() { - ret = unsafe{mbedtls_x509_crl_parse_file(&mut (*backend).crl, ssl_crlfile)}; - if ret != 0 { - unsafe{ mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"Error reading CRL file %s - mbedTLS: (-0x%04X) %s\0" as *const u8 - as *const libc::c_char, - ssl_crlfile, - -ret, - errorbuf.as_mut_ptr(), - );} - return CURLE_SSL_CRL_BADFILE; - } - } - unsafe{Curl_infof( - data, - b"mbedTLS: Connecting to %s:%ld\0" as *const u8 as *const libc::c_char, - hostname, - port, - ); - mbedtls_ssl_config_init(&mut (*backend).config); - mbedtls_ssl_init(&mut (*backend).ssl);} - - if unsafe{mbedtls_ssl_setup(&mut (*backend).ssl, &mut (*backend).config)} != 0 { - unsafe{Curl_failf( - data, - b"mbedTLS: ssl_init failed\0" as *const u8 as *const libc::c_char, - );} - return CURLE_SSL_CONNECT_ERROR; - } - ret = unsafe{mbedtls_ssl_config_defaults( - &mut (*backend).config, - 0 as libc::c_int, - 0 as libc::c_int, - 0 as libc::c_int, - )}; - if ret != 0 { - unsafe{Curl_failf( - data, - b"mbedTLS: ssl_config failed\0" as *const u8 as *const libc::c_char, - );} - return CURLE_SSL_CONNECT_ERROR; - } - - unsafe{mbedtls_ssl_conf_cert_profile(&mut (*backend).config, &mbedtls_x509_crt_profile_fr);} - unsafe{ - match SSL_CONN_CONFIG_version { - // 467-done - // #if MBEDTLS_VERSION_NUMBER < 0x03000000 - 0 | 1 => { - #[cfg(MBEDTLS_VERSION_NUMBER_LT_0X03000000)] - mbedtls_ssl_conf_min_version( - &mut (*backend).config, - 3 as libc::c_int, - 1 as libc::c_int, - ); - #[cfg(MBEDTLS_VERSION_NUMBER_LT_0X03000000)] - Curl_infof( - data, - b"mbedTLS: Set min SSL version to TLS 1.0\0" as *const u8 - as *const libc::c_char, - ); - } - // 471 - 4 | 5 | 6 | 7 => { - let mut result: CURLcode = set_ssl_version_min_max(data, conn, sockindex); - if result as libc::c_uint != CURLE_OK as libc::c_int as libc::c_uint { - return result; - } - } - _ => { - Curl_failf( - data, - b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 - as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } - } - } - - unsafe{mbedtls_ssl_conf_authmode(&mut (*backend).config, 1 as libc::c_int);} - unsafe{mbedtls_ssl_conf_rng( - &mut (*backend).config, - Some( - mbedtls_ctr_drbg_random - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_uchar, - size_t, - ) -> libc::c_int, - ), - &mut (*backend).ctr_drbg as *mut mbedtls_ctr_drbg_context as *mut libc::c_void, - );} - unsafe{mbedtls_ssl_set_bio( - &mut (*backend).ssl, - &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) - as *mut curl_socket_t as *mut libc::c_void, - Some( - mbedtls_net_send - as unsafe extern "C" fn( - *mut libc::c_void, - *const libc::c_uchar, - size_t, - ) -> libc::c_int, - ), - Some( - mbedtls_net_recv - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_uchar, - size_t, - ) -> libc::c_int, - ), - None, - );} - unsafe{mbedtls_ssl_conf_ciphersuites( - &mut (*backend).config, - mbedtls_ssl_list_ciphersuites(), - );} - unsafe{ - // 499 - #[cfg(MBEDTLS_SSL_RENEGOTIATION)] - mbedtls_ssl_conf_renegotiation(&mut (*backend).config, 1 as libc::c_int); - // 504 - #[cfg(MBEDTLS_SSL_SESSION_TICKETS)] - mbedtls_ssl_conf_session_tickets(&mut (*backend).config, 0 as libc::c_int); - } - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{((*data).set.proxy_ssl.primary).sessionid() as libc::c_int} - } else { - unsafe{ ((*data).set.ssl.primary).sessionid() as libc::c_int} - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = unsafe{((*data).set.ssl.primary).sessionid()}; - - if SSL_SET_OPTION_primary_sessionid != 0{ - let mut old_session: *mut libc::c_void = 0 as *mut libc::c_void; - Curl_ssl_sessionid_lock(data); - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_IS_PROXY_null = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - 1 as libc::c_int - } else { - 0 as libc::c_int - } != 0 ; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_IS_PROXY_null = unsafe{if 0 as libc::c_int != 0 { 1 as libc::c_int } else { 0 as libc::c_int }} != 0 ; - if !Curl_ssl_getsessionid( - data, - conn, - SSL_IS_PROXY_null, - &mut old_session, - 0 as *mut size_t, - sockindex, - ) { - ret = unsafe{mbedtls_ssl_set_session( - &mut (*backend).ssl, - old_session as *const mbedtls_ssl_session, - )}; - if ret != 0 { - Curl_ssl_sessionid_unlock(data); - unsafe{Curl_failf( - data, - b"mbedtls_ssl_set_session returned -0x%x\0" as *const u8 - as *const libc::c_char, - -ret, - );} - return CURLE_SSL_CONNECT_ERROR; - } - unsafe{Curl_infof( - data, - b"mbedTLS re-using session\0" as *const u8 as *const libc::c_char, - );} - } - Curl_ssl_sessionid_unlock(data); - } - unsafe{ - mbedtls_ssl_conf_ca_chain( - &mut (*backend).config, - &mut (*backend).cacert, - &mut (*backend).crl, - );} - - if !(SSL_SET_OPTION_key).is_null() || !(SSL_SET_OPTION_key_blob).is_null(){ - unsafe{mbedtls_ssl_conf_own_cert( - &mut (*backend).config, - &mut (*backend).clicert, - &mut (*backend).pk, - );} - } - unsafe{ - if mbedtls_ssl_set_hostname(&mut (*backend).ssl, hostname) != 0 { - Curl_failf( - data, - b"couldn't set hostname in mbedTLS\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } - // 544-done - if cfg!(HAS_ALPN){ - if ((*conn).bits).tls_enable_alpn() != 0 { - let mut p: *mut *const libc::c_char = &mut *((*backend).protocols) - .as_mut_ptr() - .offset(0 as libc::c_int as isize) as *mut *const libc::c_char; - #[cfg(USE_NGHTTP2)] - if (*data).state.httpwant as libc::c_int >= CURL_HTTP_VERSION_2_0 as libc::c_int - { - let fresh0 = p; - p = p.offset(1); - *fresh0 = b"h2\0" as *const u8 as *const libc::c_char; - } - let fresh1 = p; - p = p.offset(1); - *fresh1 = b"http/1.1\0" as *const u8 as *const libc::c_char; - *p = 0 as *const libc::c_char; - if mbedtls_ssl_conf_alpn_protocols( - &mut (*backend).config, - &mut *((*backend).protocols).as_mut_ptr().offset(0 as libc::c_int as isize), - ) != 0 - { - Curl_failf( - data, - b"Failed setting ALPN protocols\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } - p = &mut *((*backend).protocols).as_mut_ptr().offset(0 as libc::c_int as isize) - as *mut *const libc::c_char; - while !(*p).is_null() { - Curl_infof( - data, - b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, - *p, - ); - p = p.offset(1); - } - } - } - if ((*data).set.ssl.fsslctx).is_some() { - ret = (Some(((*data).set.ssl.fsslctx).expect("non-null function pointer"))) - .expect( - "non-null function pointer", - )( - data, - &mut (*backend).config as *mut mbedtls_ssl_config as *mut libc::c_void, - (*data).set.ssl.fsslctxp, - ) as libc::c_int; - if ret != 0 { - Curl_failf( - data, - b"error signaled by ssl ctx callback\0" as *const u8 - as *const libc::c_char, - ); - return ret as CURLcode; - } - } - (*connssl).connecting_state = ssl_connect_2; - return CURLE_OK; - } + unsafe { + // 292-314 + match () { + #[cfg(THREADING_SUPPORT)] + _ => { + entropy_init_mutex(&mut ts_entropy); + mbedtls_ctr_drbg_init(&mut (*backend).ctr_drbg); + ret = mbedtls_ctr_drbg_seed( + &mut (*backend).ctr_drbg, + Some( + entropy_func_mutex + as unsafe extern "C" fn(*mut libc::c_void, *mut u8, size_t) -> i32, + ), + &mut ts_entropy as *mut mbedtls_entropy_context as *mut libc::c_void, + 0 as *const u8, + 0 as i32 as size_t, + ); + if ret != 0 { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + -ret, + errorbuf.as_mut_ptr(), + ); + } + } + #[cfg(not(THREADING_SUPPORT))] + _ => {} + } + } + unsafe { + mbedtls_x509_crt_init(&mut (*backend).cacert); + } + if !ssl_cafile.is_null() { + ret = unsafe { mbedtls_x509_crt_parse_file(&mut (*backend).cacert, ssl_cafile) }; + if ret < 0 as i32 { + unsafe { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"Error reading ca cert file %s - mbedTLS: (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + ssl_cafile, + -ret, + errorbuf.as_mut_ptr(), + ); + } + if verifypeer { + return CURLE_SSL_CACERT_BADFILE; + } + } + } + + if !ssl_capath.is_null() { + ret = unsafe { mbedtls_x509_crt_parse_path(&mut (*backend).cacert, ssl_capath) }; + if ret < 0 as i32 { + unsafe { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"Error reading ca cert path %s - mbedTLS: (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + ssl_capath, + -ret, + errorbuf.as_mut_ptr(), + ); + } + if verifypeer { + return CURLE_SSL_CACERT_BADFILE; + } + } + } + + unsafe { + mbedtls_x509_crt_init(&mut (*backend).clicert); + } + if !ssl_cert.is_null() { + ret = unsafe { mbedtls_x509_crt_parse_file(&mut (*backend).clicert, ssl_cert) }; + if ret != 0 { + unsafe { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"Error reading client cert file %s - mbedTLS: (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + ssl_cert, + -ret, + errorbuf.as_mut_ptr(), + ); + } + return CURLE_SSL_CERTPROBLEM; + } + } + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_key = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*data).set.proxy_ssl.key } + } else { + unsafe { (*data).set.ssl.key } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_key = unsafe { (*data).set.ssl.key }; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_key_blob = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*data).set.proxy_ssl.key_blob } + } else { + unsafe { (*data).set.ssl.key_blob } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_key_blob = unsafe { (*data).set.ssl.key_blob }; + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_key_passwd = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*data).set.proxy_ssl.key_passwd } + } else { + unsafe { (*data).set.ssl.key_passwd } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_key_passwd = unsafe { (*data).set.ssl.key_passwd }; + + if !ssl_cert_blob.is_null() { + let mut blob_data: *const u8 = unsafe { (*ssl_cert_blob).data as *const u8 }; + ret = unsafe { + mbedtls_x509_crt_parse(&mut (*backend).clicert, blob_data, (*ssl_cert_blob).len) + }; + if ret != 0 { + unsafe { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"Error reading private key %s - mbedTLS: (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + SSL_SET_OPTION_key, + -ret, + errorbuf.as_mut_ptr(), + ); + } + return CURLE_SSL_CERTPROBLEM; + } + } + unsafe { + mbedtls_pk_init(&mut (*backend).pk); + } + // 377 - if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) { + + if !(SSL_SET_OPTION_key).is_null() || !(SSL_SET_OPTION_key_blob).is_null() { + // 377 - if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) { + // 378 - if(SSL_SET_OPTION(key)) { + if !(SSL_SET_OPTION_key).is_null() { + // 378 - if(SSL_SET_OPTION(key)) { + ret = unsafe { + mbedtls_pk_parse_keyfile( + &mut (*backend).pk, + SSL_SET_OPTION_key, + SSL_SET_OPTION_key_passwd, + ) + }; + if ret != 0 { + unsafe { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + } + unsafe { + Curl_failf( + data, + b"Error reading private key %s - mbedTLS: (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + SSL_SET_OPTION_key, + -ret, + errorbuf.as_mut_ptr(), + ); + } + return CURLE_SSL_CERTPROBLEM; + } + } else { + let mut ssl_key_blob: *const curl_blob = SSL_SET_OPTION_key_blob; + let mut key_data: *const u8 = unsafe { (*ssl_key_blob).data as *const u8 }; + let mut passwd: *const libc::c_char = SSL_SET_OPTION_key_passwd; + // 401-done + // #if MBEDTLS_VERSION_NUMBER >= 0x03000000 + if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000) { + // todo-402 + /* + todo + ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, + (const unsigned char *)passwd, + passwd ? strlen(passwd) : 0, + mbedtls_ctr_drbg_random, + &backend->ctr_drbg); + */ + } else { + ret = unsafe { + mbedtls_pk_parse_key( + &mut (*backend).pk, + key_data, + (*ssl_key_blob).len, + passwd as *const u8, + if !passwd.is_null() { + strlen(passwd) + } else { + 0 as i32 as u64 + }, + ) + }; + } + + if ret != 0 { + unsafe { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"Error parsing private key - mbedTLS: (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + -ret, + errorbuf.as_mut_ptr(), + ); + } + return CURLE_SSL_CERTPROBLEM; + } + } + if ret == 0 as i32 + && unsafe { + !(mbedtls_pk_can_do(&mut (*backend).pk, MBEDTLS_PK_RSA) != 0 + || mbedtls_pk_can_do(&mut (*backend).pk, MBEDTLS_PK_ECKEY) != 0) + } + { + ret = -(0x3f00 as i32); + } + } + + unsafe { + mbedtls_x509_crl_init(&mut (*backend).crl); + } + if !ssl_crlfile.is_null() { + ret = unsafe { mbedtls_x509_crl_parse_file(&mut (*backend).crl, ssl_crlfile) }; + if ret != 0 { + unsafe { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"Error reading CRL file %s - mbedTLS: (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + ssl_crlfile, + -ret, + errorbuf.as_mut_ptr(), + ); + } + return CURLE_SSL_CRL_BADFILE; + } + } + unsafe { + Curl_infof( + data, + b"mbedTLS: Connecting to %s:%ld\0" as *const u8 as *const libc::c_char, + hostname, + port, + ); + mbedtls_ssl_config_init(&mut (*backend).config); + mbedtls_ssl_init(&mut (*backend).ssl); + } + + if unsafe { mbedtls_ssl_setup(&mut (*backend).ssl, &mut (*backend).config) } != 0 { + unsafe { + Curl_failf( + data, + b"mbedTLS: ssl_init failed\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + ret = unsafe { + mbedtls_ssl_config_defaults(&mut (*backend).config, 0 as i32, 0 as i32, 0 as i32) + }; + if ret != 0 { + unsafe { + Curl_failf( + data, + b"mbedTLS: ssl_config failed\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + + unsafe { + mbedtls_ssl_conf_cert_profile(&mut (*backend).config, &mbedtls_x509_crt_profile_fr); + } + unsafe { + match SSL_CONN_CONFIG_version { + // 467-done + // #if MBEDTLS_VERSION_NUMBER < 0x03000000 + 0 | 1 => { + #[cfg(MBEDTLS_VERSION_NUMBER_LT_0X03000000)] + mbedtls_ssl_conf_min_version(&mut (*backend).config, 3 as i32, 1 as i32); + #[cfg(MBEDTLS_VERSION_NUMBER_LT_0X03000000)] + Curl_infof( + data, + b"mbedTLS: Set min SSL version to TLS 1.0\0" as *const u8 + as *const libc::c_char, + ); + } + // 471 + 4 | 5 | 6 | 7 => { + let mut result: CURLcode = set_ssl_version_min_max(data, conn, sockindex); + if result as u32 != CURLE_OK as i32 as u32 { + return result; + } + } + _ => { + Curl_failf( + data, + b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } + } + } + + unsafe { + mbedtls_ssl_conf_authmode(&mut (*backend).config, 1 as i32); + } + unsafe { + mbedtls_ssl_conf_rng( + &mut (*backend).config, + Some( + mbedtls_ctr_drbg_random + as unsafe extern "C" fn(*mut libc::c_void, *mut u8, size_t) -> i32, + ), + &mut (*backend).ctr_drbg as *mut mbedtls_ctr_drbg_context as *mut libc::c_void, + ); + } + unsafe { + mbedtls_ssl_set_bio( + &mut (*backend).ssl, + &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) as *mut curl_socket_t + as *mut libc::c_void, + Some( + mbedtls_net_send + as unsafe extern "C" fn(*mut libc::c_void, *const u8, size_t) -> i32, + ), + Some( + mbedtls_net_recv as unsafe extern "C" fn(*mut libc::c_void, *mut u8, size_t) -> i32, + ), + None, + ); + } + unsafe { + mbedtls_ssl_conf_ciphersuites(&mut (*backend).config, mbedtls_ssl_list_ciphersuites()); + } + unsafe { + // 499 + #[cfg(MBEDTLS_SSL_RENEGOTIATION)] + mbedtls_ssl_conf_renegotiation(&mut (*backend).config, 1 as i32); + // 504 + #[cfg(MBEDTLS_SSL_SESSION_TICKETS)] + mbedtls_ssl_conf_session_tickets(&mut (*backend).config, 0 as i32); + } + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } + } else { + unsafe { ((*data).set.ssl.primary).sessionid() as i32 } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() }; + + if SSL_SET_OPTION_primary_sessionid != 0 { + let mut old_session: *mut libc::c_void = 0 as *mut libc::c_void; + Curl_ssl_sessionid_lock(data); + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_IS_PROXY_null = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + 1 as i32 + } else { + 0 as i32 + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_IS_PROXY_null = unsafe { + if 0 as i32 != 0 { + 1 as i32 + } else { + 0 as i32 + } + } != 0; + if !Curl_ssl_getsessionid( + data, + conn, + SSL_IS_PROXY_null, + &mut old_session, + 0 as *mut size_t, + sockindex, + ) { + ret = unsafe { + mbedtls_ssl_set_session( + &mut (*backend).ssl, + old_session as *const mbedtls_ssl_session, + ) + }; + if ret != 0 { + Curl_ssl_sessionid_unlock(data); + unsafe { + Curl_failf( + data, + b"mbedtls_ssl_set_session returned -0x%x\0" as *const u8 + as *const libc::c_char, + -ret, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + unsafe { + Curl_infof( + data, + b"mbedTLS re-using session\0" as *const u8 as *const libc::c_char, + ); + } + } + Curl_ssl_sessionid_unlock(data); + } + unsafe { + mbedtls_ssl_conf_ca_chain( + &mut (*backend).config, + &mut (*backend).cacert, + &mut (*backend).crl, + ); + } + + if !(SSL_SET_OPTION_key).is_null() || !(SSL_SET_OPTION_key_blob).is_null() { + unsafe { + mbedtls_ssl_conf_own_cert( + &mut (*backend).config, + &mut (*backend).clicert, + &mut (*backend).pk, + ); + } + } + unsafe { + if mbedtls_ssl_set_hostname(&mut (*backend).ssl, hostname) != 0 { + Curl_failf( + data, + b"couldn't set hostname in mbedTLS\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } + // 544-done + if cfg!(HAS_ALPN) { + if ((*conn).bits).tls_enable_alpn() != 0 { + let mut p: *mut *const libc::c_char = &mut *((*backend).protocols) + .as_mut_ptr() + .offset(0 as i32 as isize) + as *mut *const libc::c_char; + #[cfg(USE_NGHTTP2)] + if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 { + let fresh0 = p; + p = p.offset(1); + *fresh0 = b"h2\0" as *const u8 as *const libc::c_char; + } + let fresh1 = p; + p = p.offset(1); + *fresh1 = b"http/1.1\0" as *const u8 as *const libc::c_char; + *p = 0 as *const libc::c_char; + if mbedtls_ssl_conf_alpn_protocols( + &mut (*backend).config, + &mut *((*backend).protocols) + .as_mut_ptr() + .offset(0 as i32 as isize), + ) != 0 + { + Curl_failf( + data, + b"Failed setting ALPN protocols\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } + p = &mut *((*backend).protocols) + .as_mut_ptr() + .offset(0 as i32 as isize) as *mut *const libc::c_char; + while !(*p).is_null() { + Curl_infof( + data, + b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, + *p, + ); + p = p.offset(1); + } + } + } + if ((*data).set.ssl.fsslctx).is_some() { + ret = (Some(((*data).set.ssl.fsslctx).expect("non-null function pointer"))) + .expect("non-null function pointer")( + data, + &mut (*backend).config as *mut mbedtls_ssl_config as *mut libc::c_void, + (*data).set.ssl.fsslctxp, + ) as i32; + if ret != 0 { + Curl_failf( + data, + b"error signaled by ssl ctx callback\0" as *const u8 as *const libc::c_char, + ); + return ret as CURLcode; + } + } + (*connssl).connecting_state = ssl_connect_2; + return CURLE_OK; + } } - - // done + +// done extern "C" fn mbed_connect_step2( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: libc::c_int, - ) -> CURLcode { - let mut ret: libc::c_int = 0; - let mut connssl: *mut ssl_connect_data =unsafe{ &mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - let mut peercert: *const mbedtls_x509_crt = 0 as *const mbedtls_x509_crt; - #[cfg(not(CURL_DISABLE_PROXY))] - let pinnedpubkey: *const libc::c_char = if CURLPROXY_HTTPS as libc::c_int - as libc::c_uint == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{(*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as libc::c_int as usize]} - } else { - unsafe{ (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as libc::c_int as usize]} - }; - #[cfg(CURL_DISABLE_PROXY)] - let pinnedpubkey: *const libc::c_char = (*data) - .set - .str_0[STRING_SSL_PINNEDPUBLICKEY as libc::c_int as usize]; - let ref mut fresh2 = unsafe{(*conn).recv[sockindex as usize]}; - *fresh2 = Some(mbed_recv as Curl_recv); - let ref mut fresh3 = unsafe{(*conn).send[sockindex as usize]}; - *fresh3 = Some(mbed_send as Curl_send); - ret = unsafe{mbedtls_ssl_handshake(&mut (*backend).ssl)}; - if ret == -(0x6900 as libc::c_int) { - unsafe{(*connssl).connecting_state = ssl_connect_2_reading;} - return CURLE_OK; - } else { - if ret == -(0x6880 as libc::c_int) { - unsafe{(*connssl).connecting_state = ssl_connect_2_writing;} - return CURLE_OK; - } else { - if ret != 0 { - let mut errorbuf: [libc::c_char; 128] = [0; 128]; - unsafe{mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"ssl_handshake returned - mbedTLS: (-0x%04X) %s\0" as *const u8 - as *const libc::c_char, - -ret, - errorbuf.as_mut_ptr(), - );} - return CURLE_SSL_CONNECT_ERROR; - } - } - } - unsafe{Curl_infof( - data, - b"mbedTLS: Handshake complete, cipher is %s\0" as *const u8 - as *const libc::c_char, - mbedtls_ssl_get_ciphersuite(&mut (*backend).ssl), - );} - ret = unsafe{mbedtls_ssl_get_verify_result(&mut (*backend).ssl) as libc::c_int}; - #[cfg(not(CURL_DISABLE_PROXY))] - if if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - ==unsafe{ (*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{ ((*conn).proxy_ssl_config).verifyhost() as libc::c_int} - } else { - unsafe{((*conn).ssl_config).verifyhost() as libc::c_int} - } == 0 - { - ret &= !(0x4 as libc::c_int); - } - #[cfg(CURL_DISABLE_PROXY)] - if ((*conn).ssl_config).verifyhost() == 0 { - ret &= !(0x4 as libc::c_int); - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifyhost_1 = (if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{((*conn).proxy_ssl_config).verifypeer() as libc::c_int} - } else { - unsafe{((*conn).ssl_config).verifypeer() as libc::c_int} - }) != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifyhost_1 =unsafe{ ((*conn).ssl_config).verifypeer() as libc::c_int != 0}; - if ret != 0 && SSL_CONN_CONFIG_verifyhost_1{ - if ret & 0x1 as libc::c_int != 0 { - unsafe{Curl_failf( - data, - b"Cert verify failed: BADCERT_EXPIRED\0" as *const u8 - as *const libc::c_char, - );} - } else if ret & 0x2 as libc::c_int != 0 { - unsafe{Curl_failf( - data, - b"Cert verify failed: BADCERT_REVOKED\0" as *const u8 - as *const libc::c_char, - );} - } else if ret & 0x4 as libc::c_int != 0 { - unsafe{Curl_failf( - data, - b"Cert verify failed: BADCERT_CN_MISMATCH\0" as *const u8 - as *const libc::c_char, - );} - } else if ret & 0x8 as libc::c_int != 0 { - unsafe{Curl_failf( - data, - b"Cert verify failed: BADCERT_NOT_TRUSTED\0" as *const u8 - as *const libc::c_char, - );} - } else if ret & 0x200 as libc::c_int != 0 { - unsafe{Curl_failf( - data, - b"Cert verify failed: BADCERT_FUTURE\0" as *const u8 - as *const libc::c_char, - );} - } - return CURLE_PEER_FAILED_VERIFICATION; - } - peercert = unsafe{mbedtls_ssl_get_peer_cert(&mut (*backend).ssl)}; - if !peercert.is_null() && unsafe{((*data).set).verbose() as libc::c_int} != 0 { - let bufsize: size_t = 16384 as libc::c_int as size_t; - #[cfg(not(CURLDEBUG))] - let mut buffer: *mut libc::c_char = unsafe{Curl_cmalloc - .expect("non-null function pointer")(bufsize) as *mut libc::c_char}; - #[cfg(CURLDEBUG)] - let mut buffer: *mut libc::c_char = unsafe{curl_dbg_malloc( - bufsize, - 655 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char}; - if buffer.is_null() { - return CURLE_OUT_OF_MEMORY; - } - if unsafe{mbedtls_x509_crt_info( - buffer, - bufsize, - b"* \0" as *const u8 as *const libc::c_char, - peercert, - ) > 0 as libc::c_int} - { - unsafe{ Curl_infof( - data, - b"Dumping cert info: %s\0" as *const u8 as *const libc::c_char, - buffer, - );} - } else { - unsafe{Curl_infof( - data, - b"Unable to dump certificate information\0" as *const u8 - as *const libc::c_char, - );} - } - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(buffer as *mut libc::c_void);} - - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - buffer as *mut libc::c_void, - 665 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - );} - } - if !pinnedpubkey.is_null() { - let mut size: libc::c_int = 0; - let mut result: CURLcode = CURLE_OK; - let mut p: *mut mbedtls_x509_crt = 0 as *mut mbedtls_x509_crt; - let mut pubkey: *mut libc::c_uchar = 0 as *mut libc::c_uchar; - // ****************************************************************** - // 674 - done - // #if MBEDTLS_VERSION_NUMBER >= 0x03000000 - if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000){ - // todo - // 暂不支持 MBEDTLS_VERSION_NUMBER >= 0x03000000 - } - else{ - if unsafe{peercert.is_null() || ((*peercert).raw.p).is_null() - || (*peercert).raw.len == 0} - { - unsafe{Curl_failf( - data, - b"Failed due to missing peer certificate\0" as *const u8 - as *const libc::c_char, - );} - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - } - // ****************************************************************** - unsafe{ - match () { - #[cfg(not(CURLDEBUG))] - _ => { - p = Curl_ccalloc - .expect( - "non-null function pointer", - )( - 1 as libc::c_int as size_t, - ::std::mem::size_of::() as libc::c_ulong, - ) as *mut mbedtls_x509_crt; - } - #[cfg(CURLDEBUG)] - _ => { - p = curl_dbg_calloc( - 1 as libc::c_int as size_t, - ::std::mem::size_of::() as libc::c_ulong, - 684 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - ) as *mut mbedtls_x509_crt; - } - } - } - if p.is_null() { - return CURLE_OUT_OF_MEMORY; - } - unsafe{ - match () { - #[cfg(not(CURLDEBUG))] - _ => { - pubkey = Curl_cmalloc - .expect( - "non-null function pointer", - )( - (if 38 as libc::c_int + 2 as libc::c_int * 1024 as libc::c_int - > 30 as libc::c_int - + 2 as libc::c_int - * ((521 as libc::c_int + 7 as libc::c_int) / 8 as libc::c_int) - { - 38 as libc::c_int + 2 as libc::c_int * 1024 as libc::c_int - } else { - 30 as libc::c_int - + 2 as libc::c_int - * ((521 as libc::c_int + 7 as libc::c_int) / 8 as libc::c_int) - }) as size_t, - ) as *mut libc::c_uchar; - } - #[cfg(CURLDEBUG)] - _ => { - pubkey = curl_dbg_malloc( - (if 38 as libc::c_int + 2 as libc::c_int * 1024 as libc::c_int - > 30 as libc::c_int - + 2 as libc::c_int - * ((521 as libc::c_int + 7 as libc::c_int) / 8 as libc::c_int) - { - 38 as libc::c_int + 2 as libc::c_int * 1024 as libc::c_int - } else { - 30 as libc::c_int - + 2 as libc::c_int - * ((521 as libc::c_int + 7 as libc::c_int) / 8 as libc::c_int) - }) as size_t, - 689 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_uchar; - } - } - } - if pubkey.is_null() { - result = CURLE_OUT_OF_MEMORY; - } else { - unsafe{mbedtls_x509_crt_init(p);} - // ************************************************************************* - // 701 - TODO - // #if MBEDTLS_VERSION_NUMBER >= 0x03000000 - if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000){ - // TODO - // 尚不支持 MBEDTLS_VERSION_NUMBER >= 0x03000000 - } - else{ - if unsafe{mbedtls_x509_crt_parse_der(p, (*peercert).raw.p, (*peercert).raw.len) != 0} - { - unsafe{Curl_failf( - data, - b"Failed copying peer certificate\0" as *const u8 - as *const libc::c_char, - );} - result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } else { - size = unsafe{mbedtls_pk_write_pubkey_der( - &mut (*p).pk, - pubkey, - (if 38 as libc::c_int + 2 as libc::c_int * 1024 as libc::c_int - > 30 as libc::c_int - + 2 as libc::c_int - * ((521 as libc::c_int + 7 as libc::c_int) - / 8 as libc::c_int) - { - 38 as libc::c_int + 2 as libc::c_int * 1024 as libc::c_int - } else { - 30 as libc::c_int - + 2 as libc::c_int - * ((521 as libc::c_int + 7 as libc::c_int) - / 8 as libc::c_int) - }) as size_t, - )}; - } - if size <= 0 as libc::c_int { - unsafe{Curl_failf( - data, - b"Failed copying public key from peer certificate\0" as *const u8 - as *const libc::c_char, - );} - result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } else { - unsafe{ - result = Curl_pin_peer_pubkey( - data, - pinnedpubkey, - &mut *pubkey - .offset( - ((if 38 as libc::c_int - + 2 as libc::c_int * 1024 as libc::c_int - > 30 as libc::c_int - + 2 as libc::c_int - * ((521 as libc::c_int + 7 as libc::c_int) - / 8 as libc::c_int) - { - 38 as libc::c_int + 2 as libc::c_int * 1024 as libc::c_int - } else { - 30 as libc::c_int - + 2 as libc::c_int - * ((521 as libc::c_int + 7 as libc::c_int) - / 8 as libc::c_int) - }) - size) as isize, - ), - size as size_t, - );} - } - // ************************************************************************* - } - } - unsafe{mbedtls_x509_crt_free(p);} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(p as *mut libc::c_void);} - - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - p as *mut libc::c_void, - 732 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - );} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")(pubkey as *mut libc::c_void);} - - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - pubkey as *mut libc::c_void, - 733 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - ); - if result as u64 != 0 { - return result; - }} - } - // 738-763 todo - unsafe{ - if cfg!(HAS_ALPN){ - if ((*conn).bits).tls_enable_alpn() != 0 { - let mut next_protocol: *const libc::c_char = mbedtls_ssl_get_alpn_protocol( - &mut (*backend).ssl, - ); - if !next_protocol.is_null() { - Curl_infof( - data, - b"ALPN, server accepted to use %s\0" as *const u8 as *const libc::c_char, - next_protocol, - ); - #[cfg(USE_NGHTTP2)] - let USE_NGHTTP2_flag = true; - #[cfg(not(USE_NGHTTP2))] - let USE_NGHTTP2_flag = false; - if strncmp( - next_protocol, - b"h2\0" as *const u8 as *const libc::c_char, - 2 as libc::c_int as libc::c_ulong, - ) == 0 && *next_protocol.offset(2 as libc::c_int as isize) == 0 && USE_NGHTTP2_flag - { - (*conn).negnpn = CURL_HTTP_VERSION_2_0 as libc::c_int; - } else if strncmp( - next_protocol, - b"http/1.1\0" as *const u8 as *const libc::c_char, - 8 as libc::c_int as libc::c_ulong, - ) == 0 && *next_protocol.offset(8 as libc::c_int as isize) == 0 - { - (*conn).negnpn = CURL_HTTP_VERSION_1_1 as libc::c_int; - } - } else { - Curl_infof( - data, - b"ALPN, server did not agree to a protocol\0" as *const u8 - as *const libc::c_char, - ); - } - Curl_multiuse_state( - data, - if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as libc::c_int { - 2 as libc::c_int - } else { - -(1 as libc::c_int) - }, - ); - } - } - } - unsafe{(*connssl).connecting_state = ssl_connect_3;} - unsafe{ Curl_infof(data, b"SSL connected\0" as *const u8 as *const libc::c_char);} - return CURLE_OK; - } - - // 内部没有宏 + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut ret: i32 = 0; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut peercert: *const mbedtls_x509_crt = 0 as *const mbedtls_x509_crt; + #[cfg(not(CURL_DISABLE_PROXY))] + let pinnedpubkey: *const libc::c_char = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as i32 as usize] } + } else { + unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as i32 as usize] } + }; + #[cfg(CURL_DISABLE_PROXY)] + let pinnedpubkey: *const libc::c_char = + unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as i32 as usize] }; + let ref mut fresh2 = unsafe { (*conn).recv[sockindex as usize] }; + *fresh2 = Some(mbed_recv as Curl_recv); + let ref mut fresh3 = unsafe { (*conn).send[sockindex as usize] }; + *fresh3 = Some(mbed_send as Curl_send); + ret = unsafe { mbedtls_ssl_handshake(&mut (*backend).ssl) }; + if ret == -(0x6900 as i32) { + unsafe { + (*connssl).connecting_state = ssl_connect_2_reading; + } + return CURLE_OK; + } else { + if ret == -(0x6880 as i32) { + unsafe { + (*connssl).connecting_state = ssl_connect_2_writing; + } + return CURLE_OK; + } else { + if ret != 0 { + let mut errorbuf: [libc::c_char; 128] = [0; 128]; + unsafe { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"ssl_handshake returned - mbedTLS: (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + -ret, + errorbuf.as_mut_ptr(), + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + } + } + unsafe { + Curl_infof( + data, + b"mbedTLS: Handshake complete, cipher is %s\0" as *const u8 as *const libc::c_char, + mbedtls_ssl_get_ciphersuite(&mut (*backend).ssl), + ); + } + ret = unsafe { mbedtls_ssl_get_verify_result(&mut (*backend).ssl) as i32 }; + #[cfg(not(CURL_DISABLE_PROXY))] + if if CURLPROXY_HTTPS as i32 as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } + { + unsafe { ((*conn).proxy_ssl_config).verifyhost() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifyhost() as i32 } + } == 0 + { + ret &= !(0x4 as i32); + } + #[cfg(CURL_DISABLE_PROXY)] + unsafe { + if ((*conn).ssl_config).verifyhost() == 0 { + ret &= !(0x4 as i32); + } + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifyhost_1 = (if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifypeer() as i32 } + }) != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifyhost_1 = unsafe { ((*conn).ssl_config).verifypeer() as i32 != 0 }; + if ret != 0 && SSL_CONN_CONFIG_verifyhost_1 { + if ret & 0x1 as i32 != 0 { + unsafe { + Curl_failf( + data, + b"Cert verify failed: BADCERT_EXPIRED\0" as *const u8 as *const libc::c_char, + ); + } + } else if ret & 0x2 as i32 != 0 { + unsafe { + Curl_failf( + data, + b"Cert verify failed: BADCERT_REVOKED\0" as *const u8 as *const libc::c_char, + ); + } + } else if ret & 0x4 as i32 != 0 { + unsafe { + Curl_failf( + data, + b"Cert verify failed: BADCERT_CN_MISMATCH\0" as *const u8 + as *const libc::c_char, + ); + } + } else if ret & 0x8 as i32 != 0 { + unsafe { + Curl_failf( + data, + b"Cert verify failed: BADCERT_NOT_TRUSTED\0" as *const u8 + as *const libc::c_char, + ); + } + } else if ret & 0x200 as i32 != 0 { + unsafe { + Curl_failf( + data, + b"Cert verify failed: BADCERT_FUTURE\0" as *const u8 as *const libc::c_char, + ); + } + } + return CURLE_PEER_FAILED_VERIFICATION; + } + peercert = unsafe { mbedtls_ssl_get_peer_cert(&mut (*backend).ssl) }; + if !peercert.is_null() && unsafe { ((*data).set).verbose() as i32 } != 0 { + let bufsize: size_t = 16384 as i32 as size_t; + #[cfg(not(CURLDEBUG))] + let mut buffer: *mut libc::c_char = unsafe { + Curl_cmalloc.expect("non-null function pointer")(bufsize) as *mut libc::c_char + }; + #[cfg(CURLDEBUG)] + let mut buffer: *mut libc::c_char = unsafe { + curl_dbg_malloc( + bufsize, + 655 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ) as *mut libc::c_char + }; + if buffer.is_null() { + return CURLE_OUT_OF_MEMORY; + } + if unsafe { + mbedtls_x509_crt_info( + buffer, + bufsize, + b"* \0" as *const u8 as *const libc::c_char, + peercert, + ) > 0 as i32 + } { + unsafe { + Curl_infof( + data, + b"Dumping cert info: %s\0" as *const u8 as *const libc::c_char, + buffer, + ); + } + } else { + unsafe { + Curl_infof( + data, + b"Unable to dump certificate information\0" as *const u8 as *const libc::c_char, + ); + } + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(buffer as *mut libc::c_void); + } + + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + buffer as *mut libc::c_void, + 665 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ); + } + } + if !pinnedpubkey.is_null() { + let mut size: i32 = 0; + let mut result: CURLcode = CURLE_OK; + let mut p: *mut mbedtls_x509_crt = 0 as *mut mbedtls_x509_crt; + let mut pubkey: *mut u8 = 0 as *mut u8; + // ****************************************************************** + // 674 - done + // #if MBEDTLS_VERSION_NUMBER >= 0x03000000 + if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000) { + // todo + // 暂不支持 MBEDTLS_VERSION_NUMBER >= 0x03000000 + } else { + if unsafe { + peercert.is_null() || ((*peercert).raw.p).is_null() || (*peercert).raw.len == 0 + } { + unsafe { + Curl_failf( + data, + b"Failed due to missing peer certificate\0" as *const u8 + as *const libc::c_char, + ); + } + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + } + // ****************************************************************** + unsafe { + match () { + #[cfg(not(CURLDEBUG))] + _ => { + p = Curl_ccalloc.expect("non-null function pointer")( + 1 as i32 as size_t, + ::std::mem::size_of::() as u64, + ) as *mut mbedtls_x509_crt; + } + #[cfg(CURLDEBUG)] + _ => { + p = curl_dbg_calloc( + 1 as i32 as size_t, + ::std::mem::size_of::() as u64, + 684 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ) as *mut mbedtls_x509_crt; + } + } + } + if p.is_null() { + return CURLE_OUT_OF_MEMORY; + } + unsafe { + match () { + #[cfg(not(CURLDEBUG))] + _ => { + pubkey = Curl_cmalloc.expect("non-null function pointer")( + (if 38 as i32 + 2 as i32 * 1024 as i32 + > 30 as i32 + 2 as i32 * ((521 as i32 + 7 as i32) / 8 as i32) + { + 38 as i32 + 2 as i32 * 1024 as i32 + } else { + 30 as i32 + 2 as i32 * ((521 as i32 + 7 as i32) / 8 as i32) + }) as size_t, + ) as *mut u8; + } + #[cfg(CURLDEBUG)] + _ => { + pubkey = curl_dbg_malloc( + (if 38 as i32 + 2 as i32 * 1024 as i32 + > 30 as i32 + 2 as i32 * ((521 as i32 + 7 as i32) / 8 as i32) + { + 38 as i32 + 2 as i32 * 1024 as i32 + } else { + 30 as i32 + 2 as i32 * ((521 as i32 + 7 as i32) / 8 as i32) + }) as size_t, + 689 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ) as *mut u8; + } + } + } + if pubkey.is_null() { + result = CURLE_OUT_OF_MEMORY; + } else { + unsafe { + mbedtls_x509_crt_init(p); + } + // ************************************************************************* + // 701 - TODO + // #if MBEDTLS_VERSION_NUMBER >= 0x03000000 + if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000) { + // TODO + // 尚不支持 MBEDTLS_VERSION_NUMBER >= 0x03000000 + } else { + if unsafe { + mbedtls_x509_crt_parse_der(p, (*peercert).raw.p, (*peercert).raw.len) != 0 + } { + unsafe { + Curl_failf( + data, + b"Failed copying peer certificate\0" as *const u8 + as *const libc::c_char, + ); + } + result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } else { + size = unsafe { + mbedtls_pk_write_pubkey_der( + &mut (*p).pk, + pubkey, + (if 38 as i32 + 2 as i32 * 1024 as i32 + > 30 as i32 + 2 as i32 * ((521 as i32 + 7 as i32) / 8 as i32) + { + 38 as i32 + 2 as i32 * 1024 as i32 + } else { + 30 as i32 + 2 as i32 * ((521 as i32 + 7 as i32) / 8 as i32) + }) as size_t, + ) + }; + } + if size <= 0 as i32 { + unsafe { + Curl_failf( + data, + b"Failed copying public key from peer certificate\0" as *const u8 + as *const libc::c_char, + ); + } + result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } else { + unsafe { + result = Curl_pin_peer_pubkey( + data, + pinnedpubkey, + &mut *pubkey.offset( + ((if 38 as i32 + 2 as i32 * 1024 as i32 + > 30 as i32 + 2 as i32 * ((521 as i32 + 7 as i32) / 8 as i32) + { + 38 as i32 + 2 as i32 * 1024 as i32 + } else { + 30 as i32 + 2 as i32 * ((521 as i32 + 7 as i32) / 8 as i32) + }) - size) as isize, + ), + size as size_t, + ); + } + } + // ************************************************************************* + } + } + unsafe { + mbedtls_x509_crt_free(p); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(p as *mut libc::c_void); + } + + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + p as *mut libc::c_void, + 732 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(pubkey as *mut libc::c_void); + } + + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + pubkey as *mut libc::c_void, + 733 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ); + if result as u64 != 0 { + return result; + } + } + } + // 738-763 todo + unsafe { + if cfg!(HAS_ALPN) { + if ((*conn).bits).tls_enable_alpn() != 0 { + let mut next_protocol: *const libc::c_char = + mbedtls_ssl_get_alpn_protocol(&mut (*backend).ssl); + if !next_protocol.is_null() { + Curl_infof( + data, + b"ALPN, server accepted to use %s\0" as *const u8 as *const libc::c_char, + next_protocol, + ); + #[cfg(USE_NGHTTP2)] + let USE_NGHTTP2_flag = true; + #[cfg(not(USE_NGHTTP2))] + let USE_NGHTTP2_flag = false; + if strncmp( + next_protocol, + b"h2\0" as *const u8 as *const libc::c_char, + 2 as i32 as u64, + ) == 0 + && *next_protocol.offset(2 as i32 as isize) == 0 + && USE_NGHTTP2_flag + { + (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; + } else if strncmp( + next_protocol, + b"http/1.1\0" as *const u8 as *const libc::c_char, + 8 as i32 as u64, + ) == 0 + && *next_protocol.offset(8 as i32 as isize) == 0 + { + (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; + } + } else { + Curl_infof( + data, + b"ALPN, server did not agree to a protocol\0" as *const u8 + as *const libc::c_char, + ); + } + Curl_multiuse_state( + data, + if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as i32 { + 2 as i32 + } else { + -(1 as i32) + }, + ); + } + } + } + unsafe { + (*connssl).connecting_state = ssl_connect_3; + } + unsafe { + Curl_infof(data, b"SSL connected\0" as *const u8 as *const libc::c_char); + } + return CURLE_OK; +} + +// 内部没有宏 extern "C" fn mbed_connect_step3( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: libc::c_int, - ) -> CURLcode { - let mut retcode: CURLcode = CURLE_OK; - let mut connssl: *mut ssl_connect_data = unsafe{ &mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; - unsafe{ - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ssl_connect_3 as libc::c_int as libc::c_uint - == (*connssl).connecting_state as libc::c_uint - {} else { - __assert_fail( - b"ssl_connect_3 == connssl->connecting_state\0" as *const u8 - as *const libc::c_char, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - 780 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 75], - &[libc::c_char; 75], - >( - b"CURLcode mbed_connect_step3(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - unsafe{((*data).set.proxy_ssl.primary).sessionid() as libc::c_int} - } else { - unsafe{((*data).set.ssl.primary).sessionid() as libc::c_int} - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = unsafe{((*data).set.ssl.primary).sessionid()}; - - if SSL_SET_OPTION_primary_sessionid != 0{ - let mut ret: libc::c_int = 0; - let mut our_ssl_sessionid: *mut mbedtls_ssl_session = 0 - as *mut mbedtls_ssl_session; - let mut old_ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_IS_PROXY_null_1 = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint - == unsafe{(*conn).http_proxy.proxytype as libc::c_uint} - && unsafe{ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] - .state as libc::c_uint} - { - 1 as libc::c_int - } else { - 0 as libc::c_int - } != 0 ; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_IS_PROXY_null_1 = if 0 as libc::c_int != 0 { 1 as libc::c_int } else { 0 as libc::c_int } != 0 ; - let mut isproxy: bool = SSL_IS_PROXY_null_1; - unsafe{ - match () { - #[cfg(not(CURLDEBUG))] - _ => { - our_ssl_sessionid = Curl_cmalloc - .expect( - "non-null function pointer", - )(::std::mem::size_of::() as libc::c_ulong) - as *mut mbedtls_ssl_session; - } - #[cfg(CURLDEBUG)] - _ => { - our_ssl_sessionid = curl_dbg_malloc( - ::std::mem::size_of::() as libc::c_ulong, - 788 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - ) as *mut mbedtls_ssl_session; - } - } - } - if our_ssl_sessionid.is_null() { - return CURLE_OUT_OF_MEMORY; - } - unsafe{mbedtls_ssl_session_init(our_ssl_sessionid);} - ret = unsafe{mbedtls_ssl_get_session(&mut (*backend).ssl, our_ssl_sessionid)}; - if ret != 0 { - if ret != -(0x7f00 as libc::c_int) { - unsafe{mbedtls_ssl_session_free(our_ssl_sessionid);} - } - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree - .expect( - "non-null function pointer", - )(our_ssl_sessionid as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( - our_ssl_sessionid as *mut libc::c_void, - 798 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - );} - unsafe{Curl_failf( - data, - b"mbedtls_ssl_get_session returned -0x%x\0" as *const u8 - as *const libc::c_char, - -ret, - );} - return CURLE_SSL_CONNECT_ERROR; - } - Curl_ssl_sessionid_lock(data); - if !Curl_ssl_getsessionid( - data, - conn, - isproxy, - &mut old_ssl_sessionid, - 0 as *mut size_t, - sockindex, - ) { - Curl_ssl_delsessionid(data, old_ssl_sessionid); - } - retcode = Curl_ssl_addsessionid( - data, - conn, - isproxy, - our_ssl_sessionid as *mut libc::c_void, - 0 as libc::c_int as size_t, - sockindex, - ); - Curl_ssl_sessionid_unlock(data); - if retcode as u64 != 0 { - unsafe{mbedtls_ssl_session_free(our_ssl_sessionid);} - unsafe{ + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut retcode: CURLcode = CURLE_OK; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ssl_connect_3 as i32 as u32 == (*connssl).connecting_state as u32 { + } else { + __assert_fail( + b"ssl_connect_3 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + 780 as i32 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode mbed_connect_step3(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } + } else { + unsafe { ((*data).set.ssl.primary).sessionid() as i32 } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() }; + + if SSL_SET_OPTION_primary_sessionid != 0 { + let mut ret: i32 = 0; + let mut our_ssl_sessionid: *mut mbedtls_ssl_session = 0 as *mut mbedtls_ssl_session; + let mut old_ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_IS_PROXY_null_1 = if CURLPROXY_HTTPS as i32 as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && unsafe { + ssl_connection_complete as i32 as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + 1 as i32 + } else { + 0 as i32 + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_IS_PROXY_null_1 = if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0; + let mut isproxy: bool = SSL_IS_PROXY_null_1; + unsafe { + match () { + #[cfg(not(CURLDEBUG))] + _ => { + our_ssl_sessionid = + Curl_cmalloc.expect("non-null function pointer")(::std::mem::size_of::< + mbedtls_ssl_session, + >() + as u64) as *mut mbedtls_ssl_session; + } + #[cfg(CURLDEBUG)] + _ => { + our_ssl_sessionid = curl_dbg_malloc( + ::std::mem::size_of::() as u64, + 788 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ) as *mut mbedtls_ssl_session; + } + } + } + if our_ssl_sessionid.is_null() { + return CURLE_OUT_OF_MEMORY; + } + unsafe { + mbedtls_ssl_session_init(our_ssl_sessionid); + } + ret = unsafe { mbedtls_ssl_get_session(&mut (*backend).ssl, our_ssl_sessionid) }; + if ret != 0 { + if ret != -(0x7f00 as i32) { + unsafe { + mbedtls_ssl_session_free(our_ssl_sessionid); + } + } #[cfg(not(CURLDEBUG))] - Curl_cfree - .expect( - "non-null function pointer", - )(our_ssl_sessionid as *mut libc::c_void);} - unsafe{ - #[cfg(CURLDEBUG)] - curl_dbg_free( - our_ssl_sessionid as *mut libc::c_void, - 814 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - );} - unsafe{Curl_failf( - data, - b"failed to store ssl session\0" as *const u8 as *const libc::c_char, - );} - return retcode; - } - } - unsafe{(*connssl).connecting_state = ssl_connect_done;} - return CURLE_OK; - } - - // 内部没有宏 - extern "C" fn mbed_send( - mut data: *mut Curl_easy, - mut sockindex: libc::c_int, - mut mem: *const libc::c_void, - mut len: size_t, - mut curlcode: *mut CURLcode, - ) -> ssize_t { - let mut conn: *mut connectdata = unsafe{ (*data).conn}; - let mut connssl: *mut ssl_connect_data =unsafe{ &mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{ (*connssl).backend}; - let mut ret: libc::c_int = -(1 as libc::c_int); - ret = unsafe{ mbedtls_ssl_write(&mut (*backend).ssl, mem as *mut libc::c_uchar, len)}; - if ret < 0 as libc::c_int { - unsafe{ *curlcode = (if ret == -(0x6880 as libc::c_int) { - CURLE_AGAIN as libc::c_int - } else { - CURLE_SEND_ERROR as libc::c_int - }) as CURLcode;} - ret = -(1 as libc::c_int); - } - return ret as ssize_t; - } - - // 内部没有宏 - extern "C" fn mbedtls_close_all(mut data: *mut Curl_easy) {} - - // done + unsafe { + Curl_cfree.expect("non-null function pointer")( + our_ssl_sessionid as *mut libc::c_void, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + our_ssl_sessionid as *mut libc::c_void, + 798 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ); + } + unsafe { + Curl_failf( + data, + b"mbedtls_ssl_get_session returned -0x%x\0" as *const u8 as *const libc::c_char, + -ret, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + Curl_ssl_sessionid_lock(data); + if !Curl_ssl_getsessionid( + data, + conn, + isproxy, + &mut old_ssl_sessionid, + 0 as *mut size_t, + sockindex, + ) { + Curl_ssl_delsessionid(data, old_ssl_sessionid); + } + retcode = Curl_ssl_addsessionid( + data, + conn, + isproxy, + our_ssl_sessionid as *mut libc::c_void, + 0 as i32 as size_t, + sockindex, + ); + Curl_ssl_sessionid_unlock(data); + if retcode as u64 != 0 { + unsafe { + mbedtls_ssl_session_free(our_ssl_sessionid); + } + unsafe { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + our_ssl_sessionid as *mut libc::c_void, + ); + } + unsafe { + #[cfg(CURLDEBUG)] + curl_dbg_free( + our_ssl_sessionid as *mut libc::c_void, + 814 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ); + } + unsafe { + Curl_failf( + data, + b"failed to store ssl session\0" as *const u8 as *const libc::c_char, + ); + } + return retcode; + } + } + unsafe { + (*connssl).connecting_state = ssl_connect_done; + } + return CURLE_OK; +} + +// 内部没有宏 +extern "C" fn mbed_send( + mut data: *mut Curl_easy, + mut sockindex: i32, + mut mem: *const libc::c_void, + mut len: size_t, + mut curlcode: *mut CURLcode, +) -> ssize_t { + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut ret: i32 = -(1 as i32); + ret = unsafe { mbedtls_ssl_write(&mut (*backend).ssl, mem as *mut u8, len) }; + if ret < 0 as i32 { + unsafe { + *curlcode = (if ret == -(0x6880 as i32) { + CURLE_AGAIN as i32 + } else { + CURLE_SEND_ERROR as i32 + }) as CURLcode; + } + ret = -(1 as i32); + } + return ret as ssize_t; +} + +// 内部没有宏 +extern "C" fn mbedtls_close_all(mut data: *mut Curl_easy) {} + +// done extern "C" fn mbedtls_close( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: libc::c_int, - ) { - let mut connssl: *mut ssl_connect_data = unsafe{ &mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{ (*connssl).backend}; - let mut buf: [libc::c_char; 32] = [0; 32]; - unsafe{ mbedtls_ssl_read( - &mut (*backend).ssl, - buf.as_mut_ptr() as *mut libc::c_uchar, - ::std::mem::size_of::<[libc::c_char; 32]>() as libc::c_ulong, - ); - mbedtls_pk_free(&mut (*backend).pk); - mbedtls_x509_crt_free(&mut (*backend).clicert); - mbedtls_x509_crt_free(&mut (*backend).cacert); - mbedtls_x509_crl_free(&mut (*backend).crl); - mbedtls_ssl_config_free(&mut (*backend).config); - mbedtls_ssl_free(&mut (*backend).ssl); - mbedtls_ctr_drbg_free(&mut (*backend).ctr_drbg);} - // done - 869 - #[cfg(THREADING_SUPPORT)] - unsafe{ mbedtls_entropy_free(&mut (*backend).entropy);} - } - - // 内部没有宏 + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) { + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut buf: [libc::c_char; 32] = [0; 32]; + unsafe { + mbedtls_ssl_read( + &mut (*backend).ssl, + buf.as_mut_ptr() as *mut u8, + ::std::mem::size_of::<[libc::c_char; 32]>() as u64, + ); + mbedtls_pk_free(&mut (*backend).pk); + mbedtls_x509_crt_free(&mut (*backend).clicert); + mbedtls_x509_crt_free(&mut (*backend).cacert); + mbedtls_x509_crl_free(&mut (*backend).crl); + mbedtls_ssl_config_free(&mut (*backend).config); + mbedtls_ssl_free(&mut (*backend).ssl); + mbedtls_ctr_drbg_free(&mut (*backend).ctr_drbg); + } + // done - 869 + #[cfg(THREADING_SUPPORT)] + unsafe { + mbedtls_entropy_free(&mut (*backend).entropy); + } +} + +// 内部没有宏 extern "C" fn mbed_recv( - mut data: *mut Curl_easy, - mut num: libc::c_int, - mut buf: *mut libc::c_char, - mut buffersize: size_t, - mut curlcode: *mut CURLcode, - ) -> ssize_t { - unsafe{ - let mut conn: *mut connectdata = (*data).conn; - let mut connssl: *mut ssl_connect_data = &mut *((*conn).ssl) - .as_mut_ptr() - .offset(num as isize) as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = (*connssl).backend; - let mut ret: libc::c_int = -(1 as libc::c_int); - let mut len: ssize_t = -(1 as libc::c_int) as ssize_t; - ret = mbedtls_ssl_read(&mut (*backend).ssl, buf as *mut libc::c_uchar, buffersize); - if ret <= 0 as libc::c_int { - if ret == -(0x7880 as libc::c_int) { - return 0 as libc::c_int as ssize_t; - } - *curlcode = (if ret == -(0x6900 as libc::c_int) { - CURLE_AGAIN as libc::c_int - } else { - CURLE_RECV_ERROR as libc::c_int - }) as CURLcode; - return -(1 as libc::c_int) as ssize_t; - } - len = ret as ssize_t; - return len; - } - } - - // 内部没有宏 + mut data: *mut Curl_easy, + mut num: i32, + mut buf: *mut libc::c_char, + mut buffersize: size_t, + mut curlcode: *mut CURLcode, +) -> ssize_t { + unsafe { + let mut conn: *mut connectdata = (*data).conn; + let mut connssl: *mut ssl_connect_data = + &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) as *mut ssl_connect_data; + let mut backend: *mut ssl_backend_data = (*connssl).backend; + let mut ret: i32 = -(1 as i32); + let mut len: ssize_t = -(1 as i32) as ssize_t; + ret = mbedtls_ssl_read(&mut (*backend).ssl, buf as *mut u8, buffersize); + if ret <= 0 as i32 { + if ret == -(0x7880 as i32) { + return 0 as i32 as ssize_t; + } + *curlcode = (if ret == -(0x6900 as i32) { + CURLE_AGAIN as i32 + } else { + CURLE_RECV_ERROR as i32 + }) as CURLcode; + return -(1 as i32) as ssize_t; + } + len = ret as ssize_t; + return len; + } +} + +// 内部没有宏 extern "C" fn mbedtls_session_free(mut ptr: *mut libc::c_void) { - unsafe{ mbedtls_ssl_session_free(ptr as *mut mbedtls_ssl_session);} - #[cfg(not(CURLDEBUG))] - unsafe{ Curl_cfree.expect("non-null function pointer")(ptr);} - - #[cfg(CURLDEBUG)] - unsafe{ curl_dbg_free( - ptr, - 904 as libc::c_int, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - );} - } - - // done -extern "C" fn mbedtls_version( - mut buffer: *mut libc::c_char, - mut size: size_t, - ) -> size_t { - // 909 - done - if cfg!(MBEDTLS_VERSION_C){ - let mut version: libc::c_uint =unsafe{ mbedtls_version_get_number()}; - return unsafe{ curl_msnprintf( - buffer, - size, - b"mbedTLS/%u.%u.%u\0" as *const u8 as *const libc::c_char, - version >> 24 as libc::c_int, - version >> 16 as libc::c_int & 0xff as libc::c_int as libc::c_uint, - version >> 8 as libc::c_int & 0xff as libc::c_int as libc::c_uint, - ) as size_t}; - } - else{ - return unsafe{ curl_msnprintf( - buffer, - size, - b"mbedTLS/%s\0" as *const u8 as *const libc::c_char, - b"2.16.3\0" as *const u8 as *const libc::c_char, - ) as size_t}; - } - - } - - // done - unsafe extern "C" fn mbedtls_random( - mut data: *mut Curl_easy, - mut entropy: *mut libc::c_uchar, - mut length: size_t, - ) -> CURLcode { - if cfg!(MBEDTLS_CTR_DRBG_C){ - let mut ret: libc::c_int = -(1 as libc::c_int); - let mut errorbuf: [libc::c_char; 128] = [0; 128]; - let mut ctr_entropy: mbedtls_entropy_context = mbedtls_entropy_context { - accumulator_started: 0, - accumulator: mbedtls_sha512_context { - total: [0; 2], - state: [0; 8], - buffer: [0; 128], - is384: 0, - }, - source_count: 0, - source: [mbedtls_entropy_source_state { - f_source: None, - p_source: 0 as *const libc::c_void as *mut libc::c_void, - size: 0, - threshold: 0, - strong: 0, - }; 20], - havege_data: mbedtls_havege_state { - PT1: 0, - PT2: 0, - offset: [0; 2], - pool: [0; 1024], - WALK: [0; 8192], - }, - mutex: mbedtls_threading_mutex_t { - mutex: pthread_mutex_t { - __data: __pthread_mutex_s { - __lock: 0, - __count: 0, - __owner: 0, - __nusers: 0, - __kind: 0, - __spins: 0, - __elision: 0, - __list: __pthread_list_t { - __prev: 0 as *const __pthread_internal_list - as *mut __pthread_internal_list, - __next: 0 as *const __pthread_internal_list - as *mut __pthread_internal_list, - }, - }, - }, - is_valid: 0, - }, - }; - let mut ctr_drbg: mbedtls_ctr_drbg_context = mbedtls_ctr_drbg_context { - counter: [0; 16], - reseed_counter: 0, - prediction_resistance: 0, - entropy_len: 0, - reseed_interval: 0, - aes_ctx: mbedtls_aes_context { - nr: 0, - rk: 0 as *mut uint32_t, - buf: [0; 68], - }, - f_entropy: None, - p_entropy: 0 as *mut libc::c_void, - mutex: mbedtls_threading_mutex_t { - mutex: pthread_mutex_t { - __data: __pthread_mutex_s { - __lock: 0, - __count: 0, - __owner: 0, - __nusers: 0, - __kind: 0, - __spins: 0, - __elision: 0, - __list: __pthread_list_t { - __prev: 0 as *const __pthread_internal_list - as *mut __pthread_internal_list, - __next: 0 as *const __pthread_internal_list - as *mut __pthread_internal_list, - }, - }, - }, - is_valid: 0, - }, - }; - mbedtls_entropy_init(&mut ctr_entropy); - mbedtls_ctr_drbg_init(&mut ctr_drbg); - ret = mbedtls_ctr_drbg_seed( - &mut ctr_drbg, - Some( - mbedtls_entropy_func - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_uchar, - size_t, - ) -> libc::c_int, - ), - &mut ctr_entropy as *mut mbedtls_entropy_context as *mut libc::c_void, - 0 as *const libc::c_uchar, - 0 as libc::c_int as size_t, - ); - if ret != 0 { - mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\0" as *const u8 - as *const libc::c_char, - -ret, - errorbuf.as_mut_ptr(), - ); - } else { - ret = mbedtls_ctr_drbg_random( - &mut ctr_drbg as *mut mbedtls_ctr_drbg_context as *mut libc::c_void, - entropy, - length, - ); - if ret != 0 { - mbedtls_strerror( - ret, - errorbuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong, - ); - Curl_failf( - data, - b"mbedTLS: ctr_drbg_init returned (-0x%04X) %s\0" as *const u8 - as *const libc::c_char, - -ret, - errorbuf.as_mut_ptr(), - ); - } - } - mbedtls_ctr_drbg_free(&mut ctr_drbg); - mbedtls_entropy_free(&mut ctr_entropy); - return (if ret == 0 as libc::c_int { - CURLE_OK as libc::c_int - } else { - CURLE_FAILED_INIT as libc::c_int - }) as CURLcode; - }else if cfg!(MBEDTLS_HAVEGE_C){ - // todo - return CURLE_OK as libc::c_int as CURLcode; - }else{ - return CURLE_NOT_BUILT_IN as libc::c_int as CURLcode; - } - } - - // 内部没有宏 + unsafe { + mbedtls_ssl_session_free(ptr as *mut mbedtls_ssl_session); + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(ptr); + } + + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + ptr, + 904 as i32, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + ); + } +} + +// done +extern "C" fn mbedtls_version(mut buffer: *mut libc::c_char, mut size: size_t) -> size_t { + // 909 - done + if cfg!(MBEDTLS_VERSION_C) { + let mut version: u32 = unsafe { mbedtls_version_get_number() }; + return unsafe { + curl_msnprintf( + buffer, + size, + b"mbedTLS/%u.%u.%u\0" as *const u8 as *const libc::c_char, + version >> 24 as i32, + version >> 16 as i32 & 0xff as i32 as u32, + version >> 8 as i32 & 0xff as i32 as u32, + ) as size_t + }; + } else { + return unsafe { + curl_msnprintf( + buffer, + size, + b"mbedTLS/%s\0" as *const u8 as *const libc::c_char, + b"2.16.3\0" as *const u8 as *const libc::c_char, + ) as size_t + }; + } +} + +// done +unsafe extern "C" fn mbedtls_random( + mut data: *mut Curl_easy, + mut entropy: *mut u8, + mut length: size_t, +) -> CURLcode { + if cfg!(MBEDTLS_CTR_DRBG_C) { + let mut ret: i32 = -(1 as i32); + let mut errorbuf: [libc::c_char; 128] = [0; 128]; + let mut ctr_entropy: mbedtls_entropy_context = mbedtls_entropy_context { + accumulator_started: 0, + accumulator: mbedtls_sha512_context { + total: [0; 2], + state: [0; 8], + buffer: [0; 128], + is384: 0, + }, + source_count: 0, + source: [mbedtls_entropy_source_state { + f_source: None, + p_source: 0 as *const libc::c_void as *mut libc::c_void, + size: 0, + threshold: 0, + strong: 0, + }; 20], + havege_data: mbedtls_havege_state { + PT1: 0, + PT2: 0, + offset: [0; 2], + pool: [0; 1024], + WALK: [0; 8192], + }, + mutex: mbedtls_threading_mutex_t { + mutex: pthread_mutex_t { + __data: __pthread_mutex_s { + __lock: 0, + __count: 0, + __owner: 0, + __nusers: 0, + __kind: 0, + __spins: 0, + __elision: 0, + __list: __pthread_list_t { + __prev: 0 as *const __pthread_internal_list + as *mut __pthread_internal_list, + __next: 0 as *const __pthread_internal_list + as *mut __pthread_internal_list, + }, + }, + }, + is_valid: 0, + }, + }; + let mut ctr_drbg: mbedtls_ctr_drbg_context = mbedtls_ctr_drbg_context { + counter: [0; 16], + reseed_counter: 0, + prediction_resistance: 0, + entropy_len: 0, + reseed_interval: 0, + aes_ctx: mbedtls_aes_context { + nr: 0, + rk: 0 as *mut uint32_t, + buf: [0; 68], + }, + f_entropy: None, + p_entropy: 0 as *mut libc::c_void, + mutex: mbedtls_threading_mutex_t { + mutex: pthread_mutex_t { + __data: __pthread_mutex_s { + __lock: 0, + __count: 0, + __owner: 0, + __nusers: 0, + __kind: 0, + __spins: 0, + __elision: 0, + __list: __pthread_list_t { + __prev: 0 as *const __pthread_internal_list + as *mut __pthread_internal_list, + __next: 0 as *const __pthread_internal_list + as *mut __pthread_internal_list, + }, + }, + }, + is_valid: 0, + }, + }; + mbedtls_entropy_init(&mut ctr_entropy); + mbedtls_ctr_drbg_init(&mut ctr_drbg); + ret = mbedtls_ctr_drbg_seed( + &mut ctr_drbg, + Some( + mbedtls_entropy_func + as unsafe extern "C" fn(*mut libc::c_void, *mut u8, size_t) -> i32, + ), + &mut ctr_entropy as *mut mbedtls_entropy_context as *mut libc::c_void, + 0 as *const u8, + 0 as i32 as size_t, + ); + if ret != 0 { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + -ret, + errorbuf.as_mut_ptr(), + ); + } else { + ret = mbedtls_ctr_drbg_random( + &mut ctr_drbg as *mut mbedtls_ctr_drbg_context as *mut libc::c_void, + entropy, + length, + ); + if ret != 0 { + mbedtls_strerror( + ret, + errorbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + Curl_failf( + data, + b"mbedTLS: ctr_drbg_init returned (-0x%04X) %s\0" as *const u8 + as *const libc::c_char, + -ret, + errorbuf.as_mut_ptr(), + ); + } + } + mbedtls_ctr_drbg_free(&mut ctr_drbg); + mbedtls_entropy_free(&mut ctr_entropy); + return (if ret == 0 as i32 { + CURLE_OK as i32 + } else { + CURLE_FAILED_INIT as i32 + }) as CURLcode; + } else if cfg!(MBEDTLS_HAVEGE_C) { + // todo + return CURLE_OK as i32 as CURLcode; + } else { + return CURLE_NOT_BUILT_IN as i32 as CURLcode; + } +} + +// 内部没有宏 extern "C" fn mbed_connect_common( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: libc::c_int, - mut nonblocking: bool, - mut done: *mut bool, - ) -> CURLcode { - let mut retcode: CURLcode = CURLE_OK; - let mut connssl: *mut ssl_connect_data = unsafe{ &mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data}; - let mut sockfd: curl_socket_t = unsafe{ (*conn).sock[sockindex as usize]}; - let mut timeout_ms: timediff_t = 0; - let mut what: libc::c_int = 0; - if unsafe{ ssl_connection_complete as libc::c_int as libc::c_uint - == (*connssl).state as libc::c_uint} - { - unsafe{ *done = 1 as libc::c_int != 0;} - return CURLE_OK; - } - if ssl_connect_1 as libc::c_int as libc::c_uint - == unsafe{ (*connssl).connecting_state as libc::c_uint} - { - timeout_ms = unsafe{ Curl_timeleft(data, 0 as *mut curltime, 1 as libc::c_int != 0)}; - if timeout_ms < 0 as libc::c_int as libc::c_long { - unsafe{ Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - );} - return CURLE_OPERATION_TIMEDOUT; - } - retcode = mbed_connect_step1(data, conn, sockindex); - if retcode as u64 != 0 { - return retcode; - } - } - while ssl_connect_2 as libc::c_int as libc::c_uint - == unsafe{ (*connssl).connecting_state as libc::c_uint} - || ssl_connect_2_reading as libc::c_int as libc::c_uint - == unsafe{ (*connssl).connecting_state as libc::c_uint} - || ssl_connect_2_writing as libc::c_int as libc::c_uint - == unsafe{ (*connssl).connecting_state as libc::c_uint} - { - timeout_ms = unsafe{ Curl_timeleft(data, 0 as *mut curltime, 1 as libc::c_int != 0)}; - if timeout_ms < 0 as libc::c_int as libc::c_long { - unsafe{ Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - );} - return CURLE_OPERATION_TIMEDOUT; - } - if unsafe{ (*connssl).connecting_state as libc::c_uint} - == ssl_connect_2_reading as libc::c_int as libc::c_uint - || unsafe{ (*connssl).connecting_state as libc::c_uint} - == ssl_connect_2_writing as libc::c_int as libc::c_uint - { - let mut writefd: curl_socket_t = if ssl_connect_2_writing as libc::c_int - as libc::c_uint == unsafe{ (*connssl).connecting_state as libc::c_uint} - { - sockfd - } else { - -(1 as libc::c_int) - }; - let mut readfd: curl_socket_t = if ssl_connect_2_reading as libc::c_int - as libc::c_uint == unsafe{ (*connssl).connecting_state as libc::c_uint} - { - sockfd - } else { - -(1 as libc::c_int) - }; - what = unsafe{ Curl_socket_check( - readfd, - -(1 as libc::c_int), - writefd, - if nonblocking as libc::c_int != 0 { - 0 as libc::c_int as libc::c_long - } else { - timeout_ms - }, - )}; - if what < 0 as libc::c_int { - unsafe{ Curl_failf( - data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, - *__errno_location(), - );} - return CURLE_SSL_CONNECT_ERROR; - } else { - if 0 as libc::c_int == what { - if nonblocking { - unsafe{ *done = 0 as libc::c_int != 0;} - return CURLE_OK; - } else { - unsafe{ Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 - as *const libc::c_char, - );} - return CURLE_OPERATION_TIMEDOUT; - } - } - } - } - retcode = unsafe{ mbed_connect_step2(data, conn, sockindex)}; - if unsafe{ retcode as libc::c_uint != 0 - || nonblocking as libc::c_int != 0 - && (ssl_connect_2 as libc::c_int as libc::c_uint - == (*connssl).connecting_state as libc::c_uint - || ssl_connect_2_reading as libc::c_int as libc::c_uint - == (*connssl).connecting_state as libc::c_uint - || ssl_connect_2_writing as libc::c_int as libc::c_uint - == (*connssl).connecting_state as libc::c_uint)} - { - return retcode; - } - } - if ssl_connect_3 as libc::c_int as libc::c_uint - == unsafe{ (*connssl).connecting_state as libc::c_uint} - { - retcode = unsafe{ mbed_connect_step3(data, conn, sockindex)}; - if retcode as u64 != 0 { - return retcode; - } - } - if ssl_connect_done as libc::c_int as libc::c_uint - == unsafe{ (*connssl).connecting_state as libc::c_uint} - { - unsafe{ (*connssl).state = ssl_connection_complete;} - let ref mut fresh4 = unsafe{ (*conn).recv[sockindex as usize]}; - *fresh4 = Some(mbed_recv as Curl_recv); - let ref mut fresh5 = unsafe{ (*conn).send[sockindex as usize]}; - *fresh5 = Some(mbed_send as Curl_send); - unsafe{ *done = 1 as libc::c_int != 0;} - } else { - unsafe{ *done = 0 as libc::c_int != 0;} - } - unsafe{ (*connssl).connecting_state = ssl_connect_1;} - return CURLE_OK; - } - - // 内部没有宏 - extern "C" fn mbedtls_connect_nonblocking( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: libc::c_int, - mut done: *mut bool, - ) -> CURLcode { - unsafe{ return mbed_connect_common(data, conn, sockindex, 1 as libc::c_int != 0, done);} - } - - // 内部没有宏 + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut nonblocking: bool, + mut done: *mut bool, +) -> CURLcode { + let mut retcode: CURLcode = CURLE_OK; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; + let mut timeout_ms: timediff_t = 0; + let mut what: i32 = 0; + if unsafe { ssl_connection_complete as i32 as u32 == (*connssl).state as u32 } { + unsafe { + *done = 1 as i32 != 0; + } + return CURLE_OK; + } + if ssl_connect_1 as i32 as u32 == unsafe { (*connssl).connecting_state as u32 } { + timeout_ms = unsafe { Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0) }; + if timeout_ms < 0 as i32 as i64 { + unsafe { + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_OPERATION_TIMEDOUT; + } + retcode = mbed_connect_step1(data, conn, sockindex); + if retcode as u64 != 0 { + return retcode; + } + } + while ssl_connect_2 as i32 as u32 == unsafe { (*connssl).connecting_state as u32 } + || ssl_connect_2_reading as i32 as u32 == unsafe { (*connssl).connecting_state as u32 } + || ssl_connect_2_writing as i32 as u32 == unsafe { (*connssl).connecting_state as u32 } + { + timeout_ms = unsafe { Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0) }; + if timeout_ms < 0 as i32 as i64 { + unsafe { + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_OPERATION_TIMEDOUT; + } + if unsafe { (*connssl).connecting_state as u32 } == ssl_connect_2_reading as i32 as u32 + || unsafe { (*connssl).connecting_state as u32 } == ssl_connect_2_writing as i32 as u32 + { + let mut writefd: curl_socket_t = if ssl_connect_2_writing as i32 as u32 + == unsafe { (*connssl).connecting_state as u32 } + { + sockfd + } else { + -(1 as i32) + }; + let mut readfd: curl_socket_t = if ssl_connect_2_reading as i32 as u32 + == unsafe { (*connssl).connecting_state as u32 } + { + sockfd + } else { + -(1 as i32) + }; + what = unsafe { + Curl_socket_check( + readfd, + -(1 as i32), + writefd, + if nonblocking as i32 != 0 { + 0 as i32 as i64 + } else { + timeout_ms + }, + ) + }; + if what < 0 as i32 { + unsafe { + Curl_failf( + data, + b"select/poll on SSL socket, errno: %d\0" as *const u8 + as *const libc::c_char, + *__errno_location(), + ); + } + return CURLE_SSL_CONNECT_ERROR; + } else { + if 0 as i32 == what { + if nonblocking { + unsafe { + *done = 0 as i32 != 0; + } + return CURLE_OK; + } else { + unsafe { + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_OPERATION_TIMEDOUT; + } + } + } + } + retcode = unsafe { mbed_connect_step2(data, conn, sockindex) }; + if unsafe { + retcode as u32 != 0 + || nonblocking as i32 != 0 + && (ssl_connect_2 as i32 as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_reading as i32 as u32 + == (*connssl).connecting_state as u32 + || ssl_connect_2_writing as i32 as u32 + == (*connssl).connecting_state as u32) + } { + return retcode; + } + } + if ssl_connect_3 as i32 as u32 == unsafe { (*connssl).connecting_state as u32 } { + retcode = unsafe { mbed_connect_step3(data, conn, sockindex) }; + if retcode as u64 != 0 { + return retcode; + } + } + if ssl_connect_done as i32 as u32 == unsafe { (*connssl).connecting_state as u32 } { + unsafe { + (*connssl).state = ssl_connection_complete; + } + let ref mut fresh4 = unsafe { (*conn).recv[sockindex as usize] }; + *fresh4 = Some(mbed_recv as Curl_recv); + let ref mut fresh5 = unsafe { (*conn).send[sockindex as usize] }; + *fresh5 = Some(mbed_send as Curl_send); + unsafe { + *done = 1 as i32 != 0; + } + } else { + unsafe { + *done = 0 as i32 != 0; + } + } + unsafe { + (*connssl).connecting_state = ssl_connect_1; + } + return CURLE_OK; +} + +// 内部没有宏 +extern "C" fn mbedtls_connect_nonblocking( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut done: *mut bool, +) -> CURLcode { + unsafe { + return mbed_connect_common(data, conn, sockindex, 1 as i32 != 0, done); + } +} + +// 内部没有宏 extern "C" fn mbedtls_connect( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: libc::c_int, - ) -> CURLcode { - let mut retcode: CURLcode = CURLE_OK; - let mut done: bool = 0 as libc::c_int != 0; - retcode = unsafe{ mbed_connect_common( - data, - conn, - sockindex, - 0 as libc::c_int != 0, - &mut done, - )}; - if retcode as u64 != 0 { - return retcode; - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if done {} else { - unsafe{ - __assert_fail( - b"done\0" as *const u8 as *const libc::c_char, - b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, - 1094 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 72], - &[libc::c_char; 72], - >( - b"CURLcode mbedtls_connect(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - );} - } - return CURLE_OK; - } - - // 内部没有宏 - extern "C" fn mbedtls_init() -> libc::c_int { - unsafe{ return Curl_mbedtlsthreadlock_thread_setup();} - } - - // 内部没有宏 + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut retcode: CURLcode = CURLE_OK; + let mut done: bool = 0 as i32 != 0; + retcode = unsafe { mbed_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done) }; + if retcode as u64 != 0 { + return retcode; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if done { + } else { + unsafe { + __assert_fail( + b"done\0" as *const u8 as *const libc::c_char, + b"vtls/mbedtls.c\0" as *const u8 as *const libc::c_char, + 1094 as i32 as u32, + (*::std::mem::transmute::<&[u8; 72], &[libc::c_char; 72]>( + b"CURLcode mbedtls_connect(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + return CURLE_OK; +} + +// 内部没有宏 +extern "C" fn mbedtls_init() -> i32 { + unsafe { + return Curl_mbedtlsthreadlock_thread_setup(); + } +} + +// 内部没有宏 extern "C" fn mbedtls_cleanup() { - unsafe{ Curl_mbedtlsthreadlock_thread_cleanup();} - } - - // 内部没有宏 -extern "C" fn mbedtls_data_pending( - mut conn: *const connectdata, - mut sockindex: libc::c_int, - ) -> bool { - let mut connssl: *const ssl_connect_data = unsafe{ &*((*conn).ssl) - .as_ptr() - .offset(sockindex as isize) as *const ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{ (*connssl).backend}; - unsafe{ return mbedtls_ssl_get_bytes_avail(&mut (*backend).ssl) - != 0 as libc::c_int as libc::c_ulong;} - } - - // done + unsafe { + Curl_mbedtlsthreadlock_thread_cleanup(); + } +} + +// 内部没有宏 +extern "C" fn mbedtls_data_pending(mut conn: *const connectdata, mut sockindex: i32) -> bool { + let mut connssl: *const ssl_connect_data = + unsafe { &*((*conn).ssl).as_ptr().offset(sockindex as isize) as *const ssl_connect_data }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + return mbedtls_ssl_get_bytes_avail(&mut (*backend).ssl) != 0 as i32 as u64; + } +} + +// done extern "C" fn mbedtls_sha256sum( - mut input: *const libc::c_uchar, - mut inputlen: size_t, - mut sha256sum: *mut libc::c_uchar, - mut sha256len: size_t, - ) -> CURLcode { - // 1128 - done - if cfg!(MBEDTLS_VERSION_NUMBER_LT_0X02070000){ - // C语句 - 未翻译 - // mbedtls_sha256(input, inputlen, sha256sum, 0); - } - else{ - /* returns 0 on success, otherwise failure */ - if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000){ - // C语句 - 未翻译 - // if(mbedtls_sha256(input, inputlen, sha256sum, 0) != 0) - } - else{ - // 这边翻译出来对应的是 - // C语句 - // if(mbedtls_sha256_ret(input, inputlen, sha256sum, 0) != 0) - // 所以对应的版本是 0X03000000 > MBEDTLS_VERSION_NUMBER >= 0X02070000 - if unsafe{mbedtls_sha256_ret(input, inputlen, sha256sum, 0 as libc::c_int)!= 0 as libc::c_int} { - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - } - return CURLE_OK; - } - - // 内部没有宏 + mut input: *const u8, + mut inputlen: size_t, + mut sha256sum: *mut u8, + mut sha256len: size_t, +) -> CURLcode { + // 1128 - done + if cfg!(MBEDTLS_VERSION_NUMBER_LT_0X02070000) { + // C语句 - 未翻译 + // mbedtls_sha256(input, inputlen, sha256sum, 0); + } else { + /* returns 0 on success, otherwise failure */ + if cfg!(MBEDTLS_VERSION_NUMBER_GT_0X03000000) { + // C语句 - 未翻译 + // if(mbedtls_sha256(input, inputlen, sha256sum, 0) != 0) + } else { + // 这边翻译出来对应的是 + // C语句 + // if(mbedtls_sha256_ret(input, inputlen, sha256sum, 0) != 0) + // 所以对应的版本是 0X03000000 > MBEDTLS_VERSION_NUMBER >= 0X02070000 + if unsafe { mbedtls_sha256_ret(input, inputlen, sha256sum, 0 as i32) != 0 as i32 } { + return CURLE_BAD_FUNCTION_ARGUMENT; + } + } + } + return CURLE_OK; +} + +// 内部没有宏 extern "C" fn mbedtls_get_internals( - mut connssl: *mut ssl_connect_data, - mut info: CURLINFO, - ) -> *mut libc::c_void { - let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; - unsafe{return &mut (*backend).ssl as *mut mbedtls_ssl_context as *mut libc::c_void;} - } - - - #[no_mangle] - pub static mut Curl_ssl_mbedtls: Curl_ssl = unsafe { - { - let mut init = Curl_ssl { - info: { - let mut init = curl_ssl_backend { - id: CURLSSLBACKEND_MBEDTLS, - name: b"mbedtls\0" as *const u8 as *const libc::c_char, - }; - init - }, - supports: ((1 as libc::c_int) << 0 as libc::c_int - | (1 as libc::c_int) << 2 as libc::c_int - | (1 as libc::c_int) << 3 as libc::c_int) as libc::c_uint, - sizeof_ssl_backend_data: ::std::mem::size_of::() - as libc::c_ulong, - init: Some(mbedtls_init as unsafe extern "C" fn() -> libc::c_int), - cleanup: Some(mbedtls_cleanup as unsafe extern "C" fn() -> ()), - version: Some( - mbedtls_version - as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t, - ), - check_cxn: Some( - Curl_none_check_cxn - as unsafe extern "C" fn(*mut connectdata) -> libc::c_int, - ), - shut_down: Some( - Curl_none_shutdown - as unsafe extern "C" fn( - *mut Curl_easy, - *mut connectdata, - libc::c_int, - ) -> libc::c_int, - ), - data_pending: Some( - mbedtls_data_pending - as unsafe extern "C" fn(*const connectdata, libc::c_int) -> bool, - ), - random: Some( - mbedtls_random - as unsafe extern "C" fn( - *mut Curl_easy, - *mut libc::c_uchar, - size_t, - ) -> CURLcode, - ), - cert_status_request: Some( - Curl_none_cert_status_request as unsafe extern "C" fn() -> bool, - ), - connect_blocking: Some( - mbedtls_connect - as unsafe extern "C" fn( - *mut Curl_easy, - *mut connectdata, - libc::c_int, - ) -> CURLcode, - ), - connect_nonblocking: Some( - mbedtls_connect_nonblocking - as unsafe extern "C" fn( - *mut Curl_easy, - *mut connectdata, - libc::c_int, - *mut bool, - ) -> CURLcode, - ), - getsock: Some( - Curl_ssl_getsock - as unsafe extern "C" fn( - *mut connectdata, - *mut curl_socket_t, - ) -> libc::c_int, - ), - get_internals: Some( - mbedtls_get_internals - as unsafe extern "C" fn( - *mut ssl_connect_data, - CURLINFO, - ) -> *mut libc::c_void, - ), - close_one: Some( - mbedtls_close - as unsafe extern "C" fn( - *mut Curl_easy, - *mut connectdata, - libc::c_int, - ) -> (), - ), - close_all: Some( - mbedtls_close_all as unsafe extern "C" fn(*mut Curl_easy) -> (), - ), - session_free: Some( - mbedtls_session_free as unsafe extern "C" fn(*mut libc::c_void) -> (), - ), - set_engine: Some( - Curl_none_set_engine - as unsafe extern "C" fn( - *mut Curl_easy, - *const libc::c_char, - ) -> CURLcode, - ), - set_engine_default: Some( - Curl_none_set_engine_default - as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, - ), - engines_list: Some( - Curl_none_engines_list - as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, - ), - false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), - sha256sum: Some( - mbedtls_sha256sum - as unsafe extern "C" fn( - *const libc::c_uchar, - size_t, - *mut libc::c_uchar, - size_t, - ) -> CURLcode, - ), - associate_connection: None, - disassociate_connection: None, - }; - init - } - }; + mut connssl: *mut ssl_connect_data, + mut info: CURLINFO, +) -> *mut libc::c_void { + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + return &mut (*backend).ssl as *mut mbedtls_ssl_context as *mut libc::c_void; + } +} - \ No newline at end of file +#[no_mangle] +pub static mut Curl_ssl_mbedtls: Curl_ssl = unsafe { + { + let mut init = Curl_ssl { + info: { + let mut init = curl_ssl_backend { + id: CURLSSLBACKEND_MBEDTLS, + name: b"mbedtls\0" as *const u8 as *const libc::c_char, + }; + init + }, + supports: ((1 as i32) << 0 as i32 | (1 as i32) << 2 as i32 | (1 as i32) << 3 as i32) + as u32, + sizeof_ssl_backend_data: ::std::mem::size_of::() as u64, + init: Some(mbedtls_init as unsafe extern "C" fn() -> i32), + cleanup: Some(mbedtls_cleanup as unsafe extern "C" fn() -> ()), + version: Some( + mbedtls_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t, + ), + check_cxn: Some(Curl_none_check_cxn as unsafe extern "C" fn(*mut connectdata) -> i32), + shut_down: Some( + Curl_none_shutdown + as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> i32, + ), + data_pending: Some( + mbedtls_data_pending as unsafe extern "C" fn(*const connectdata, i32) -> bool, + ), + random: Some( + mbedtls_random as unsafe extern "C" fn(*mut Curl_easy, *mut u8, size_t) -> CURLcode, + ), + cert_status_request: Some( + Curl_none_cert_status_request as unsafe extern "C" fn() -> bool, + ), + connect_blocking: Some( + mbedtls_connect + as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> CURLcode, + ), + connect_nonblocking: Some( + mbedtls_connect_nonblocking + as unsafe extern "C" fn( + *mut Curl_easy, + *mut connectdata, + i32, + *mut bool, + ) -> CURLcode, + ), + getsock: Some( + Curl_ssl_getsock + as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> i32, + ), + get_internals: Some( + mbedtls_get_internals + as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, + ), + close_one: Some( + mbedtls_close as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), + ), + close_all: Some(mbedtls_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), + session_free: Some( + mbedtls_session_free as unsafe extern "C" fn(*mut libc::c_void) -> (), + ), + set_engine: Some( + Curl_none_set_engine + as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, + ), + set_engine_default: Some( + Curl_none_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, + ), + engines_list: Some( + Curl_none_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, + ), + false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), + sha256sum: Some( + mbedtls_sha256sum + as unsafe extern "C" fn(*const u8, size_t, *mut u8, size_t) -> CURLcode, + ), + associate_connection: None, + disassociate_connection: None, + }; + init + } +}; diff --git a/rust/rust_project/src/vtls/mbedtls_threadlock.rs b/rust/rust_project/src/vtls/mbedtls_threadlock.rs index 098d8ad..67b2430 100644 --- a/rust/rust_project/src/vtls/mbedtls_threadlock.rs +++ b/rust/rust_project/src/vtls/mbedtls_threadlock.rs @@ -81,7 +81,7 @@ pub extern "C" fn Curl_mbedtlsthreadlock_thread_cleanup() -> i32 { if mutex_buf.is_null() { return 0; /* error, no threads locks defined */ } - + i = 0; while i < 2 { if pthread_mutex_destroy(&mut *mutex_buf.offset(i as isize)) != 0 { @@ -89,7 +89,7 @@ pub extern "C" fn Curl_mbedtlsthreadlock_thread_cleanup() -> i32 { } i += 1; } - + #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")(mutex_buf as *mut libc::c_void); #[cfg(CURLDEBUG)] diff --git a/rust/rust_project/src/vtls/nss.rs b/rust/rust_project/src/vtls/nss.rs index b379241..1a1e000 100644 --- a/rust/rust_project/src/vtls/nss.rs +++ b/rust/rust_project/src/vtls/nss.rs @@ -769,12 +769,12 @@ extern "C" fn dup_nickname( if n.is_null() { unsafe { Curl_infof( - data, - b"warning: certificate file name \"%s\" handled as nickname; please use \"./%s\" to force file name\0" - as *const u8 as *const libc::c_char, - str, - str, - ); + data, + b"warning: certificate file name \"%s\" handled as nickname; please use \"./%s\" to force file name\0" + as *const u8 as *const libc::c_char, + str, + str, + ); } #[cfg(not(CURLDEBUG))] return unsafe { Curl_cstrdup.expect("non-null function pointer")(str) }; @@ -2908,10 +2908,10 @@ pub extern "C" fn Curl_nss_force_init(mut data: *mut Curl_easy) -> CURLcode { if !data.is_null() { unsafe { Curl_failf( - data, - b"unable to initialize NSS, curl_global_init() should have been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL\0" - as *const u8 as *const libc::c_char, - ); + data, + b"unable to initialize NSS, curl_global_init() should have been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL\0" + as *const u8 as *const libc::c_char, + ); } } return CURLE_FAILED_INIT; @@ -3461,7 +3461,7 @@ extern "C" fn nss_init_sslver( } }; #[cfg(CURL_DISABLE_PROXY)] - let max: i64 = (*conn).ssl_config.version_max; + let max: i64 = unsafe { (*conn).ssl_config.version_max }; let mut vrange: SSLVersionRange = SSLVersionRange { min: 0, max: 0 }; match min { 1 | 0 => { @@ -4604,11 +4604,11 @@ extern "C" fn nss_setup_connect( if result as u32 == CURLE_FAILED_INIT as i32 as u32 { unsafe { Curl_infof( - data, - b"WARNING: failed to load NSS PEM library %s. Using OpenSSL PEM certificates will not work.\0" - as *const u8 as *const libc::c_char, - pem_library, - ); + data, + b"WARNING: failed to load NSS PEM library %s. Using OpenSSL PEM certificates will not work.\0" + as *const u8 as *const libc::c_char, + pem_library, + ); } } else if result as u64 != 0 { break 'error; @@ -5060,18 +5060,18 @@ extern "C" fn nss_setup_connect( } else { unsafe { __assert_fail( - b"ssl_connection_complete == conn->proxy_ssl[sockindex].state\0" - as *const u8 as *const libc::c_char, - b"vtls/nss.c\0" as *const u8 as *const libc::c_char, - 2029 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 74], - &[libc::c_char; 74], - >( - b"CURLcode nss_setup_connect(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); + b"ssl_connection_complete == conn->proxy_ssl[sockindex].state\0" + as *const u8 as *const libc::c_char, + b"vtls/nss.c\0" as *const u8 as *const libc::c_char, + 2029 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::< + &[u8; 74], + &[libc::c_char; 74], + >( + b"CURLcode nss_setup_connect(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); } } #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] @@ -5079,18 +5079,18 @@ extern "C" fn nss_setup_connect( } else { unsafe { __assert_fail( - b"conn->proxy_ssl[sockindex].backend->handle != ((void*)0)\0" - as *const u8 as *const libc::c_char, - b"vtls/nss.c\0" as *const u8 as *const libc::c_char, - 2030 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 74], - &[libc::c_char; 74], - >( - b"CURLcode nss_setup_connect(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); + b"conn->proxy_ssl[sockindex].backend->handle != ((void*)0)\0" + as *const u8 as *const libc::c_char, + b"vtls/nss.c\0" as *const u8 as *const libc::c_char, + 2030 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::< + &[u8; 74], + &[libc::c_char; 74], + >( + b"CURLcode nss_setup_connect(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); } } nspr_io = unsafe { (*(*conn).proxy_ssl[sockindex as usize].backend).nss_handle }; @@ -5186,7 +5186,7 @@ extern "C" fn nss_setup_connect( unsafe { (*data).set.ssl.key_passwd } }; #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_key_passwd = (*data).set.ssl.key_passwd; + let SSL_SET_OPTION_key_passwd = unsafe { (*data).set.ssl.key_passwd }; if !SSL_SET_OPTION_key_passwd.is_null() { unsafe { SSL_SetPKCS11PinArg( diff --git a/rust/rust_project/src/vtls/openssl.rs b/rust/rust_project/src/vtls/openssl.rs old mode 100755 new mode 100644 index fcd74e8..1917385 --- a/rust/rust_project/src/vtls/openssl.rs +++ b/rust/rust_project/src/vtls/openssl.rs @@ -12,728 +12,946 @@ * Create: 2022-10-31 * Description: support openssl backend ******************************************************************************/ -use crate::src::vtls::keylog::*; -use crate::src::vtls::vtls::*; -use libc; -use rust_ffi::src::ffi_alias::type_alias::*; -use rust_ffi::src::ffi_fun::fun_call::*; -use rust_ffi::src::ffi_struct::struct_define::*; - -#[inline] -extern "C" fn sk_X509_pop(mut sk: *mut stack_st_X509) -> *mut X509 { - unsafe { - return OPENSSL_sk_pop(sk as *mut OPENSSL_STACK) as *mut X509; - } -} -#[inline] -extern "C" fn sk_X509_pop_free(mut sk: *mut stack_st_X509, mut freefunc: sk_X509_freefunc) { - unsafe { - OPENSSL_sk_pop_free( - sk as *mut OPENSSL_STACK, - ::std::mem::transmute::(freefunc), - ); - } -} -#[inline] -extern "C" fn sk_X509_INFO_num(mut sk: *const stack_st_X509_INFO) -> i32 { - unsafe { - return OPENSSL_sk_num(sk as *const OPENSSL_STACK); - } -} -#[inline] -extern "C" fn sk_X509_INFO_value( - mut sk: *const stack_st_X509_INFO, - mut idx: i32, -) -> *mut X509_INFO { - unsafe { - return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509_INFO; - } -} -#[inline] -extern "C" fn sk_X509_INFO_pop_free( - mut sk: *mut stack_st_X509_INFO, - mut freefunc: sk_X509_INFO_freefunc, -) { - unsafe { - OPENSSL_sk_pop_free( - sk as *mut OPENSSL_STACK, - ::std::mem::transmute::(freefunc), - ); - } -} -#[inline] -extern "C" fn sk_X509_EXTENSION_num(mut sk: *const stack_st_X509_EXTENSION) -> i32 { - unsafe { - return OPENSSL_sk_num(sk as *const OPENSSL_STACK); - } -} -#[inline] -extern "C" fn sk_X509_EXTENSION_value( - mut sk: *const stack_st_X509_EXTENSION, - mut idx: i32, -) -> *mut X509_EXTENSION { - unsafe { - return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509_EXTENSION; - } -} -#[inline] -extern "C" fn sk_X509_num(mut sk: *const stack_st_X509) -> i32 { - unsafe { - return OPENSSL_sk_num(sk as *const OPENSSL_STACK); - } -} -#[inline] -extern "C" fn sk_X509_value(mut sk: *const stack_st_X509, mut idx: i32) -> *mut X509 { - unsafe { - return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509; - } -} -#[inline] -extern "C" fn sk_GENERAL_NAME_num(mut sk: *const stack_st_GENERAL_NAME) -> i32 { - unsafe { - return OPENSSL_sk_num(sk as *const OPENSSL_STACK); - } -} -#[inline] -extern "C" fn sk_GENERAL_NAME_value( - mut sk: *const stack_st_GENERAL_NAME, - mut idx: i32, -) -> *mut GENERAL_NAME { - unsafe { - return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut GENERAL_NAME; - } -} -#[cfg(HAVE_KEYLOG_CALLBACK)] -extern "C" fn ossl_keylog_callback(mut ssl: *const SSL, mut line: *const libc::c_char) { - unsafe { - Curl_tls_keylog_write_line(line); - } -} -// TODO - 255 - 关闭 HAVE_KEYLOG_CALLBACK选项,在翻译一次 -// #[cfg(not(HAVE_KEYLOG_CALLBACK))] - -extern "C" fn SSL_ERROR_to_str(mut err: i32) -> *const libc::c_char { - match err { - 0 => return b"SSL_ERROR_NONE\0" as *const u8 as *const libc::c_char, - 1 => return b"SSL_ERROR_SSL\0" as *const u8 as *const libc::c_char, - 2 => return b"SSL_ERROR_WANT_READ\0" as *const u8 as *const libc::c_char, - 3 => return b"SSL_ERROR_WANT_WRITE\0" as *const u8 as *const libc::c_char, - 4 => return b"SSL_ERROR_WANT_X509_LOOKUP\0" as *const u8 as *const libc::c_char, - 5 => return b"SSL_ERROR_SYSCALL\0" as *const u8 as *const libc::c_char, - 6 => return b"SSL_ERROR_ZERO_RETURN\0" as *const u8 as *const libc::c_char, - 7 => return b"SSL_ERROR_WANT_CONNECT\0" as *const u8 as *const libc::c_char, - 8 => return b"SSL_ERROR_WANT_ACCEPT\0" as *const u8 as *const libc::c_char, - #[cfg(SSL_ERROR_WANT_ASYNC)] - 9 => return b"SSL_ERROR_WANT_ASYNC\0" as *const u8 as *const libc::c_char, - #[cfg(SSL_ERROR_WANT_ASYNC_JOB)] - 10 => return b"SSL_ERROR_WANT_ASYNC_JOB\0" as *const u8 as *const libc::c_char, - #[cfg(SSL_ERROR_WANT_EARLY)] - 11 => return b"SSL_ERROR_WANT_EARLY\0" as *const u8 as *const libc::c_char, - _ => return b"SSL_ERROR unknown\0" as *const u8 as *const libc::c_char, - }; -} -/* Return error string for last OpenSSL error - */ -extern "C" fn ossl_strerror( - mut error: u64, - mut buf: *mut libc::c_char, - mut size: size_t, -) -> *mut libc::c_char { - unsafe { - if size != 0 { - *buf = '\0' as libc::c_char; - } - // TODO - 351 - // #[cfg(OPENSSL_IS_BORINGSSL)] - #[cfg(not(OPENSSL_IS_BORINGSSL))] - ERR_error_string_n(error, buf, size); - if size > 1 as u64 && *buf == 0 { - strncpy( - buf, - if error != 0 { - b"Unknown error\0" as *const u8 as *const libc::c_char - } else { - b"No error\0" as *const u8 as *const libc::c_char - }, - size, - ); - *buf.offset(size.wrapping_sub(1 as u64) as isize) = '\0' as libc::c_char; - } - } - return buf; -} -/* Return an extra data index for the transfer data. - * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). - */ -extern "C" fn ossl_get_ssl_data_index() -> i32 { - static mut ssl_ex_data_data_index: i32 = -(1 as i32); - unsafe { - if ssl_ex_data_data_index < 0 as i32 { - ssl_ex_data_data_index = CRYPTO_get_ex_new_index( - 0 as i32, - 0 as i64, - 0 as *mut libc::c_void, - None, - None, - None, - ); - } - return ssl_ex_data_data_index; - } -} -/* Return an extra data index for the connection data. - * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). - */ -extern "C" fn ossl_get_ssl_conn_index() -> i32 { - static mut ssl_ex_data_conn_index: i32 = -(1 as i32); - unsafe { - if ssl_ex_data_conn_index < 0 as i32 { - ssl_ex_data_conn_index = CRYPTO_get_ex_new_index( - 0 as i32, - 0 as i64, - 0 as *mut libc::c_void, - None, - None, - None, - ); - } - return ssl_ex_data_conn_index; - } -} -/* Return an extra data index for the sockindex. - * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). - */ -extern "C" fn ossl_get_ssl_sockindex_index() -> i32 { - static mut sockindex_index: i32 = -(1 as i32); - unsafe { - if sockindex_index < 0 as i32 { - sockindex_index = CRYPTO_get_ex_new_index( - 0 as i32, - 0 as i64, - 0 as *mut libc::c_void, - None, - None, - None, - ); - } - return sockindex_index; - } -} -/* Return an extra data index for proxy boolean. - * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). - */ -extern "C" fn ossl_get_proxy_index() -> i32 { - static mut proxy_index: i32 = -(1 as i32); - unsafe { - if proxy_index < 0 as i32 { - proxy_index = CRYPTO_get_ex_new_index( - 0 as i32, - 0 as i64, - 0 as *mut libc::c_void, - None, - None, - None, - ); - } - return proxy_index; - } -} - -extern "C" fn passwd_callback( - mut buf: *mut libc::c_char, - mut num: i32, - mut encrypting: i32, - mut global_passwd: *mut libc::c_void, -) -> i32 { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if 0 as i32 == encrypting { - } else { - unsafe { - __assert_fail( - b"0 == encrypting\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 416 as u32, - (*::std::mem::transmute::<&[u8; 46], &[libc::c_char; 46]>( - b"int passwd_callback(char *, int, int, void *)\0", - )) - .as_ptr(), - ); - } - } - if encrypting == 0 { - let mut klen: i32 = unsafe { curlx_uztosi(strlen(global_passwd as *mut libc::c_char)) }; - if num > klen { - unsafe { - memcpy( - buf as *mut libc::c_void, - global_passwd, - (klen + 1 as i32) as u64, - ); - } - return klen; - } - } - return 0 as i32; -} -extern "C" fn rand_enough() -> bool { - return if 0 as i32 != unsafe { RAND_status() } { - 1 as i32 - } else { - 0 as i32 - } != 0; -} -extern "C" fn ossl_seed(mut data: *mut Curl_easy) -> CURLcode { - let mut fname: [libc::c_char; 256] = [0; 256]; - /* This might get called before it has been added to a multi handle */ - if unsafe { !((*data).multi).is_null() && (*(*data).multi).ssl_seeded as i32 != 0 } { - return CURLE_OK; - } - if rand_enough() { - if unsafe { !((*data).multi).is_null() } { - unsafe { - (*(*data).multi).ssl_seeded = 1 as i32 != 0; - } - } - return CURLE_OK; - } - // TODO - 451 - 选项 RANDOM_FILE - unsafe { - RAND_load_file( - if !((*data).set.str_0[STRING_SSL_RANDOM_FILE as usize]).is_null() { - (*data).set.str_0[STRING_SSL_RANDOM_FILE as usize] as *const libc::c_char - } else { - b"/dev/urandom\0" as *const u8 as *const libc::c_char - }, - 1024 as i64, - ); - } - if rand_enough() { - return CURLE_OK; - } - - /* fallback to a custom seeding of the PRNG using a hash based on a current - time */ - // TODO - 467 有一段if的条件编译 - // #[cfg(HAVE_RAND_EGD)] - loop { - let mut randb: [u8; 64] = [0; 64]; - let mut len: size_t = ::std::mem::size_of::<[u8; 64]>() as u64; - let mut i: size_t = 0; - let mut i_max: size_t = 0; - i = 0 as size_t; - i_max = len.wrapping_div(::std::mem::size_of::() as u64); - while i < i_max { - let mut tv: curltime = unsafe { Curl_now() }; - unsafe { - Curl_wait_ms(1 as timediff_t); - } - tv.tv_sec = (tv.tv_sec as u64).wrapping_mul(i.wrapping_add(1 as u64)) as time_t; - tv.tv_usec = (tv.tv_usec as u32).wrapping_mul((i as u32).wrapping_add(2 as u32)) as i32; - unsafe { - tv.tv_sec = (tv.tv_sec as u64 - ^ (((Curl_now()).tv_sec + (Curl_now()).tv_usec as i64) as u64) - .wrapping_mul(i.wrapping_add(3 as u64)) - << 8 as i32) as time_t; - tv.tv_usec = (tv.tv_usec as u32 - ^ ((((Curl_now()).tv_sec + (Curl_now()).tv_usec as i64) as u64) - .wrapping_mul(i.wrapping_add(4 as u64)) as u32) - << 16 as i32) as i32; - memcpy( - &mut *randb - .as_mut_ptr() - .offset(i.wrapping_mul(::std::mem::size_of::() as u64) as isize) - as *mut u8 as *mut libc::c_void, - &mut tv as *mut curltime as *const libc::c_void, - ::std::mem::size_of::() as u64, - ); - } - i = i.wrapping_add(1); - } - unsafe { - RAND_add( - randb.as_mut_ptr() as *const libc::c_void, - len as i32, - len as libc::c_double / 2 as libc::c_double, - ); - } - if rand_enough() { - break; - } - } - /* generates a default path for the random seed file */ - fname[0 as usize] = 0 as libc::c_char; /* blank it first */ - unsafe { - RAND_file_name( - fname.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - if fname[0 as usize] != 0 { - /* we got a file name to try */ - unsafe { - RAND_load_file(fname.as_mut_ptr(), 1024 as i64); - } - if rand_enough() { - return CURLE_OK; - } - } - unsafe { - Curl_infof( - data, - b"libcurl is now using a weak random seed!\0" as *const u8 as *const libc::c_char, - ); - } - return (if rand_enough() as i32 != 0 { - CURLE_OK as i32 - } else { - CURLE_SSL_CONNECT_ERROR as i32 - }) as CURLcode; -} - -extern "C" fn do_file_type(mut type_0: *const libc::c_char) -> i32 { - unsafe { - if type_0.is_null() || *type_0.offset(0 as isize) == 0 { - return 1 as i32; - } - if Curl_strcasecompare(type_0, b"PEM\0" as *const u8 as *const libc::c_char) != 0 { - return 1 as i32; - } - if Curl_strcasecompare(type_0, b"DER\0" as *const u8 as *const libc::c_char) != 0 { - return 2 as i32; - } - if Curl_strcasecompare(type_0, b"ENG\0" as *const u8 as *const libc::c_char) != 0 { - return 42 as i32; - } - if Curl_strcasecompare(type_0, b"P12\0" as *const u8 as *const libc::c_char) != 0 { - return 43 as i32; - } - return -(1 as i32); - } -} - -/* - * Supply default password to the engine user interface conversation. - * The password is passed by OpenSSL engine from ENGINE_load_private_key() - * last argument to the ui and can be obtained by UI_get0_user_data(ui) here. - */ -#[cfg(USE_OPENSSL_ENGINE)] -extern "C" fn ssl_ui_reader(mut ui: *mut UI, mut uis: *mut UI_STRING) -> i32 { - let mut password: *const libc::c_char = 0 as *const libc::c_char; - match unsafe { UI_get_string_type(uis) as u32 } { - 1 | 2 => { - password = unsafe { UI_get0_user_data(ui) as *const libc::c_char }; - if !password.is_null() && unsafe { UI_get_input_flags(uis) & 0x2 as i32 != 0 } { - unsafe { - UI_set_result(ui, uis, password); - } - return 1 as i32; - } - } - _ => {} - } - return unsafe { - (UI_method_get_reader(UI_OpenSSL())).expect("non-null function pointer")(ui, uis) - }; -} - -/* - * Suppress interactive request for a default password if available. - */ -#[cfg(USE_OPENSSL_ENGINE)] -extern "C" fn ssl_ui_writer(mut ui: *mut UI, mut uis: *mut UI_STRING) -> i32 { - unsafe { - match UI_get_string_type(uis) as u32 { - 1 | 2 => { - if !(UI_get0_user_data(ui)).is_null() && UI_get_input_flags(uis) & 0x2 as i32 != 0 { - return 1 as i32; - } - } - _ => {} - } - return (UI_method_get_writer(UI_OpenSSL())).expect("non-null function pointer")(ui, uis); - } -} - -/* - * Check if a given string is a PKCS#11 URI - */ -#[cfg(USE_OPENSSL_ENGINE)] -extern "C" fn is_pkcs11_uri(mut string: *const libc::c_char) -> bool { - unsafe { - return !string.is_null() - && Curl_strncasecompare( - string, - b"pkcs11:\0" as *const u8 as *const libc::c_char, - 7 as size_t, - ) != 0; - } -} -extern "C" fn SSL_CTX_use_certificate_blob( - mut ctx: *mut SSL_CTX, - mut blob: *const curl_blob, - mut type_0: i32, - mut key_passwd: *const libc::c_char, -) -> i32 { - let mut current_block: u64; - let mut ret: i32 = 0 as i32; - let mut x: *mut X509 = 0 as *mut X509; - /* the typecast of blob->len is fine since it is guaranteed to never be - larger than CURL_MAX_INPUT_LENGTH */ - let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; - if in_0.is_null() { - return CURLE_OUT_OF_MEMORY as i32; - } - 'end: loop { - if type_0 == 2 as i32 { - /* j = ERR_R_ASN1_LIB; */ - x = unsafe { d2i_X509_bio(in_0, 0 as *mut *mut X509) }; - } else if type_0 == 1 as i32 { - /* ERR_R_PEM_LIB; */ - x = unsafe { - PEM_read_bio_X509( - in_0, - 0 as *mut *mut X509, - Some( - passwd_callback - as unsafe extern "C" fn( - *mut libc::c_char, - i32, - i32, - *mut libc::c_void, - ) -> i32, - ), - key_passwd as *mut libc::c_void, - ) - }; - } else { - ret = 0 as i32; - break 'end; - } - if x.is_null() { - ret = 0 as i32; - break 'end; - } - ret = unsafe { SSL_CTX_use_certificate(ctx, x) }; - break 'end; - } - unsafe { - X509_free(x); - BIO_free(in_0); - } - return ret; -} - -extern "C" fn SSL_CTX_use_PrivateKey_blob( - mut ctx: *mut SSL_CTX, - mut blob: *const curl_blob, - mut type_0: i32, - mut key_passwd: *const libc::c_char, -) -> i32 { - /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ - let mut current_block: u64; - let mut ret: i32 = 0 as i32; - let mut pkey: *mut EVP_PKEY = 0 as *mut EVP_PKEY; - let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; - if in_0.is_null() { - return CURLE_OUT_OF_MEMORY as i32; - } - 'end: loop { - if type_0 == 1 as i32 { - pkey = unsafe { - PEM_read_bio_PrivateKey( - in_0, - 0 as *mut *mut EVP_PKEY, - Some( - passwd_callback - as unsafe extern "C" fn( - *mut libc::c_char, - i32, - i32, - *mut libc::c_void, - ) -> i32, - ), - key_passwd as *mut libc::c_void, - ) - }; - } else if type_0 == 2 as i32 { - pkey = unsafe { d2i_PrivateKey_bio(in_0, 0 as *mut *mut EVP_PKEY) }; - } else { - ret = 0 as i32; - break 'end; - } - if pkey.is_null() { - ret = 0 as i32; - break 'end; - } - unsafe { - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); - } - break 'end; - } - unsafe { - BIO_free(in_0); - } - return ret; -} -extern "C" fn SSL_CTX_use_certificate_chain_blob( - mut ctx: *mut SSL_CTX, - mut blob: *const curl_blob, - mut key_passwd: *const libc::c_char, -) -> i32 { - /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ - // TODO - 672 与OPENSSL_VERSION_NUMBER有关的条件编译 - let mut current_block: u64; - let mut ret: i32 = 0 as i32; - let mut x: *mut X509 = 0 as *mut X509; - let mut passwd_callback_userdata: *mut libc::c_void = key_passwd as *mut libc::c_void; - let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; - if in_0.is_null() { - return CURLE_OUT_OF_MEMORY as i32; - } - unsafe { - ERR_clear_error(); - x = PEM_read_bio_X509_AUX( - in_0, - 0 as *mut *mut X509, - Some( - passwd_callback - as unsafe extern "C" fn(*mut libc::c_char, i32, i32, *mut libc::c_void) -> i32, - ), - key_passwd as *mut libc::c_void, - ); - } - 'end: loop { - if x.is_null() { - ret = 0 as i32; - break 'end; - } - ret = unsafe { SSL_CTX_use_certificate(ctx, x) }; - if unsafe { ERR_peek_error() } != 0 as u64 { - ret = 0 as i32; - } - if ret != 0 { - let mut ca: *mut X509 = 0 as *mut X509; - let mut err: u64 = 0; - if unsafe { - SSL_CTX_ctrl( - ctx, - 88 as i32, - 0 as i64, - 0 as *mut libc::c_void as *mut libc::c_char as *mut libc::c_void, - ) - } == 0 - { - ret = 0 as i32; - break 'end; - } - loop { - ca = unsafe { - PEM_read_bio_X509( - in_0, - 0 as *mut *mut X509, - Some( - passwd_callback - as unsafe extern "C" fn( - *mut libc::c_char, - i32, - i32, - *mut libc::c_void, - ) -> i32, - ), - passwd_callback_userdata, - ) - }; - if ca.is_null() { - break; - } - if unsafe { - SSL_CTX_ctrl( - ctx, - 89 as i32, - 0 as i64, - ca as *mut libc::c_char as *mut libc::c_void, - ) - } == 0 - { - unsafe { - X509_free(ca); - } - ret = 0 as i32; - break 'end; - } - } - err = unsafe { ERR_peek_last_error() }; - if (err >> 24 as i64 & 0xff as u64) as i32 == 9 as i32 - && (err & 0xfff as u64) as i32 == 108 as i32 - { - unsafe { ERR_clear_error() }; - } else { - ret = 0 as i32; - } - } - break 'end; - } - unsafe { - X509_free(x); - BIO_free(in_0); - } - return ret; -} - -extern "C" fn cert_stuff( - mut data: *mut Curl_easy, - mut ctx: *mut SSL_CTX, - mut cert_file: *mut libc::c_char, - mut cert_blob: *const curl_blob, - mut cert_type: *const libc::c_char, - mut key_file: *mut libc::c_char, - mut key_blob: *const curl_blob, - mut key_type: *const libc::c_char, - mut key_passwd: *mut libc::c_char, -) -> i32 { - let mut current_block: u64; - let mut error_buffer: [libc::c_char; 256] = [0; 256]; - let mut check_privkey: bool = 1 as i32 != 0; - let mut file_type: i32 = do_file_type(cert_type); - if !cert_file.is_null() || !cert_blob.is_null() || file_type == 42 as i32 { - let mut ssl: *mut SSL = 0 as *mut SSL; - let mut x509: *mut X509 = 0 as *mut X509; - let mut cert_done: i32 = 0 as i32; - let mut cert_use_result: i32 = 0; - if !key_passwd.is_null() { - /* set the password in the callback userdata */ - unsafe { - SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd as *mut libc::c_void); - /* Set passwd callback: */ - SSL_CTX_set_default_passwd_cb( - ctx, - Some( - passwd_callback - as unsafe extern "C" fn( - *mut libc::c_char, - i32, - i32, - *mut libc::c_void, - ) -> i32, - ), - ); - } - } - - match file_type { - 1 => { - /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ - cert_use_result = if !cert_blob.is_null() { - SSL_CTX_use_certificate_chain_blob(ctx, cert_blob, key_passwd) - } else { - unsafe { SSL_CTX_use_certificate_chain_file(ctx, cert_file) } - }; - if cert_use_result != 1 as i32 { - unsafe { - Curl_failf( + use crate::src::vtls::keylog::*; + use crate::src::vtls::vtls::*; + use libc; + use rust_ffi::src::ffi_alias::type_alias::*; + use rust_ffi::src::ffi_fun::fun_call::*; + use rust_ffi::src::ffi_struct::struct_define::*; + + #[inline] + extern "C" fn sk_X509_pop(mut sk: *mut stack_st_X509) -> *mut X509 { + unsafe { + return OPENSSL_sk_pop(sk as *mut OPENSSL_STACK) as *mut X509; + } + } + #[inline] + extern "C" fn sk_X509_pop_free(mut sk: *mut stack_st_X509, mut freefunc: sk_X509_freefunc) { + unsafe { + OPENSSL_sk_pop_free( + sk as *mut OPENSSL_STACK, + ::std::mem::transmute::(freefunc), + ); + } + } + #[inline] + extern "C" fn sk_X509_INFO_num(mut sk: *const stack_st_X509_INFO) -> i32 { + unsafe { + return OPENSSL_sk_num(sk as *const OPENSSL_STACK); + } + } + #[inline] + extern "C" fn sk_X509_INFO_value( + mut sk: *const stack_st_X509_INFO, + mut idx: i32, + ) -> *mut X509_INFO { + unsafe { + return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509_INFO; + } + } + #[inline] + extern "C" fn sk_X509_INFO_pop_free( + mut sk: *mut stack_st_X509_INFO, + mut freefunc: sk_X509_INFO_freefunc, + ) { + unsafe { + OPENSSL_sk_pop_free( + sk as *mut OPENSSL_STACK, + ::std::mem::transmute::(freefunc), + ); + } + } + #[inline] + extern "C" fn sk_X509_EXTENSION_num(mut sk: *const stack_st_X509_EXTENSION) -> i32 { + unsafe { + return OPENSSL_sk_num(sk as *const OPENSSL_STACK); + } + } + #[inline] + extern "C" fn sk_X509_EXTENSION_value( + mut sk: *const stack_st_X509_EXTENSION, + mut idx: i32, + ) -> *mut X509_EXTENSION { + unsafe { + return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509_EXTENSION; + } + } + #[inline] + extern "C" fn sk_X509_num(mut sk: *const stack_st_X509) -> i32 { + unsafe { + return OPENSSL_sk_num(sk as *const OPENSSL_STACK); + } + } + #[inline] + extern "C" fn sk_X509_value(mut sk: *const stack_st_X509, mut idx: i32) -> *mut X509 { + unsafe { + return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509; + } + } + #[inline] + extern "C" fn sk_GENERAL_NAME_num(mut sk: *const stack_st_GENERAL_NAME) -> i32 { + unsafe { + return OPENSSL_sk_num(sk as *const OPENSSL_STACK); + } + } + #[inline] + extern "C" fn sk_GENERAL_NAME_value( + mut sk: *const stack_st_GENERAL_NAME, + mut idx: i32, + ) -> *mut GENERAL_NAME { + unsafe { + return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut GENERAL_NAME; + } + } + #[cfg(HAVE_KEYLOG_CALLBACK)] + extern "C" fn ossl_keylog_callback(mut ssl: *const SSL, mut line: *const libc::c_char) { + unsafe { + Curl_tls_keylog_write_line(line); + } + } + // TODO - 255 - 关闭 HAVE_KEYLOG_CALLBACK选项,在翻译一次 + // #[cfg(not(HAVE_KEYLOG_CALLBACK))] + + extern "C" fn SSL_ERROR_to_str(mut err: i32) -> *const libc::c_char { + match err { + 0 => return b"SSL_ERROR_NONE\0" as *const u8 as *const libc::c_char, + 1 => return b"SSL_ERROR_SSL\0" as *const u8 as *const libc::c_char, + 2 => return b"SSL_ERROR_WANT_READ\0" as *const u8 as *const libc::c_char, + 3 => return b"SSL_ERROR_WANT_WRITE\0" as *const u8 as *const libc::c_char, + 4 => return b"SSL_ERROR_WANT_X509_LOOKUP\0" as *const u8 as *const libc::c_char, + 5 => return b"SSL_ERROR_SYSCALL\0" as *const u8 as *const libc::c_char, + 6 => return b"SSL_ERROR_ZERO_RETURN\0" as *const u8 as *const libc::c_char, + 7 => return b"SSL_ERROR_WANT_CONNECT\0" as *const u8 as *const libc::c_char, + 8 => return b"SSL_ERROR_WANT_ACCEPT\0" as *const u8 as *const libc::c_char, + #[cfg(SSL_ERROR_WANT_ASYNC)] + 9 => return b"SSL_ERROR_WANT_ASYNC\0" as *const u8 as *const libc::c_char, + #[cfg(SSL_ERROR_WANT_ASYNC_JOB)] + 10 => return b"SSL_ERROR_WANT_ASYNC_JOB\0" as *const u8 as *const libc::c_char, + #[cfg(SSL_ERROR_WANT_EARLY)] + 11 => return b"SSL_ERROR_WANT_EARLY\0" as *const u8 as *const libc::c_char, + _ => return b"SSL_ERROR unknown\0" as *const u8 as *const libc::c_char, + }; + } + /* Return error string for last OpenSSL error + */ + extern "C" fn ossl_strerror( + mut error: u64, + mut buf: *mut libc::c_char, + mut size: size_t, + ) -> *mut libc::c_char { + unsafe { + if size != 0 { + *buf = '\0' as libc::c_char; + } + // TODO - 351 + // #[cfg(OPENSSL_IS_BORINGSSL)] + #[cfg(not(OPENSSL_IS_BORINGSSL))] + ERR_error_string_n(error, buf, size); + if size > 1 as u64 && *buf == 0 { + strncpy( + buf, + if error != 0 { + b"Unknown error\0" as *const u8 as *const libc::c_char + } else { + b"No error\0" as *const u8 as *const libc::c_char + }, + size, + ); + *buf.offset(size.wrapping_sub(1 as u64) as isize) = '\0' as libc::c_char; + } + } + return buf; + } + /* Return an extra data index for the transfer data. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ + extern "C" fn ossl_get_ssl_data_index() -> i32 { + static mut ssl_ex_data_data_index: i32 = -(1 as i32); + unsafe { + if ssl_ex_data_data_index < 0 as i32 { + ssl_ex_data_data_index = CRYPTO_get_ex_new_index( + 0 as i32, + 0 as i64, + 0 as *mut libc::c_void, + None, + None, + None, + ); + } + return ssl_ex_data_data_index; + } + } + /* Return an extra data index for the connection data. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ + extern "C" fn ossl_get_ssl_conn_index() -> i32 { + static mut ssl_ex_data_conn_index: i32 = -(1 as i32); + unsafe { + if ssl_ex_data_conn_index < 0 as i32 { + ssl_ex_data_conn_index = CRYPTO_get_ex_new_index( + 0 as i32, + 0 as i64, + 0 as *mut libc::c_void, + None, + None, + None, + ); + } + return ssl_ex_data_conn_index; + } + } + /* Return an extra data index for the sockindex. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ + extern "C" fn ossl_get_ssl_sockindex_index() -> i32 { + static mut sockindex_index: i32 = -(1 as i32); + unsafe { + if sockindex_index < 0 as i32 { + sockindex_index = CRYPTO_get_ex_new_index( + 0 as i32, + 0 as i64, + 0 as *mut libc::c_void, + None, + None, + None, + ); + } + return sockindex_index; + } + } + /* Return an extra data index for proxy boolean. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ + extern "C" fn ossl_get_proxy_index() -> i32 { + static mut proxy_index: i32 = -(1 as i32); + unsafe { + if proxy_index < 0 as i32 { + proxy_index = CRYPTO_get_ex_new_index( + 0 as i32, + 0 as i64, + 0 as *mut libc::c_void, + None, + None, + None, + ); + } + return proxy_index; + } + } + + extern "C" fn passwd_callback( + mut buf: *mut libc::c_char, + mut num: i32, + mut encrypting: i32, + mut global_passwd: *mut libc::c_void, + ) -> i32 { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if 0 as i32 == encrypting { + } else { + unsafe { + __assert_fail( + b"0 == encrypting\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 416 as u32, + (*::std::mem::transmute::<&[u8; 46], &[libc::c_char; 46]>( + b"int passwd_callback(char *, int, int, void *)\0", + )) + .as_ptr(), + ); + } + } + if encrypting == 0 { + let mut klen: i32 = unsafe { curlx_uztosi(strlen(global_passwd as *mut libc::c_char)) }; + if num > klen { + unsafe { + memcpy( + buf as *mut libc::c_void, + global_passwd, + (klen + 1 as i32) as u64, + ); + } + return klen; + } + } + return 0 as i32; + } + extern "C" fn rand_enough() -> bool { + return if 0 as i32 != unsafe { RAND_status() } { + 1 as i32 + } else { + 0 as i32 + } != 0; + } + extern "C" fn ossl_seed(mut data: *mut Curl_easy) -> CURLcode { + let mut fname: [libc::c_char; 256] = [0; 256]; + /* This might get called before it has been added to a multi handle */ + if unsafe { !((*data).multi).is_null() && (*(*data).multi).ssl_seeded as i32 != 0 } { + return CURLE_OK; + } + if rand_enough() { + if unsafe { !((*data).multi).is_null() } { + unsafe { + (*(*data).multi).ssl_seeded = 1 as i32 != 0; + } + } + return CURLE_OK; + } + // TODO - 451 - 选项 RANDOM_FILE + unsafe { + RAND_load_file( + if !((*data).set.str_0[STRING_SSL_RANDOM_FILE as usize]).is_null() { + (*data).set.str_0[STRING_SSL_RANDOM_FILE as usize] as *const libc::c_char + } else { + b"/dev/urandom\0" as *const u8 as *const libc::c_char + }, + 1024 as i64, + ); + } + if rand_enough() { + return CURLE_OK; + } + + /* fallback to a custom seeding of the PRNG using a hash based on a current + time */ + // TODO - 467 有一段if的条件编译 + // #[cfg(HAVE_RAND_EGD)] + loop { + let mut randb: [u8; 64] = [0; 64]; + let mut len: size_t = ::std::mem::size_of::<[u8; 64]>() as u64; + let mut i: size_t = 0; + let mut i_max: size_t = 0; + i = 0 as size_t; + i_max = len.wrapping_div(::std::mem::size_of::() as u64); + while i < i_max { + let mut tv: curltime = unsafe { Curl_now() }; + unsafe { + Curl_wait_ms(1 as timediff_t); + } + tv.tv_sec = (tv.tv_sec as u64).wrapping_mul(i.wrapping_add(1 as u64)) as time_t; + tv.tv_usec = (tv.tv_usec as u32).wrapping_mul((i as u32).wrapping_add(2 as u32)) as i32; + unsafe { + tv.tv_sec = (tv.tv_sec as u64 + ^ (((Curl_now()).tv_sec + (Curl_now()).tv_usec as i64) as u64) + .wrapping_mul(i.wrapping_add(3 as u64)) + << 8 as i32) as time_t; + tv.tv_usec = (tv.tv_usec as u32 + ^ ((((Curl_now()).tv_sec + (Curl_now()).tv_usec as i64) as u64) + .wrapping_mul(i.wrapping_add(4 as u64)) as u32) + << 16 as i32) as i32; + memcpy( + &mut *randb + .as_mut_ptr() + .offset(i.wrapping_mul(::std::mem::size_of::() as u64) as isize) + as *mut u8 as *mut libc::c_void, + &mut tv as *mut curltime as *const libc::c_void, + ::std::mem::size_of::() as u64, + ); + } + i = i.wrapping_add(1); + } + unsafe { + RAND_add( + randb.as_mut_ptr() as *const libc::c_void, + len as i32, + len as libc::c_double / 2 as libc::c_double, + ); + } + if rand_enough() { + break; + } + } + /* generates a default path for the random seed file */ + fname[0 as usize] = 0 as libc::c_char; /* blank it first */ + unsafe { + RAND_file_name( + fname.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + if fname[0 as usize] != 0 { + /* we got a file name to try */ + unsafe { + RAND_load_file(fname.as_mut_ptr(), 1024 as i64); + } + if rand_enough() { + return CURLE_OK; + } + } + unsafe { + Curl_infof( + data, + b"libcurl is now using a weak random seed!\0" as *const u8 as *const libc::c_char, + ); + } + return (if rand_enough() as i32 != 0 { + CURLE_OK as i32 + } else { + CURLE_SSL_CONNECT_ERROR as i32 + }) as CURLcode; + } + + extern "C" fn do_file_type(mut type_0: *const libc::c_char) -> i32 { + unsafe { + if type_0.is_null() || *type_0.offset(0 as isize) == 0 { + return 1 as i32; + } + if Curl_strcasecompare(type_0, b"PEM\0" as *const u8 as *const libc::c_char) != 0 { + return 1 as i32; + } + if Curl_strcasecompare(type_0, b"DER\0" as *const u8 as *const libc::c_char) != 0 { + return 2 as i32; + } + if Curl_strcasecompare(type_0, b"ENG\0" as *const u8 as *const libc::c_char) != 0 { + return 42 as i32; + } + if Curl_strcasecompare(type_0, b"P12\0" as *const u8 as *const libc::c_char) != 0 { + return 43 as i32; + } + return -(1 as i32); + } + } + + /* + * Supply default password to the engine user interface conversation. + * The password is passed by OpenSSL engine from ENGINE_load_private_key() + * last argument to the ui and can be obtained by UI_get0_user_data(ui) here. + */ + #[cfg(USE_OPENSSL_ENGINE)] + extern "C" fn ssl_ui_reader(mut ui: *mut UI, mut uis: *mut UI_STRING) -> i32 { + let mut password: *const libc::c_char = 0 as *const libc::c_char; + match unsafe { UI_get_string_type(uis) as u32 } { + 1 | 2 => { + password = unsafe { UI_get0_user_data(ui) as *const libc::c_char }; + if !password.is_null() && unsafe { UI_get_input_flags(uis) & 0x2 as i32 != 0 } { + unsafe { + UI_set_result(ui, uis, password); + } + return 1 as i32; + } + } + _ => {} + } + return unsafe { + (UI_method_get_reader(UI_OpenSSL())).expect("non-null function pointer")(ui, uis) + }; + } + + /* + * Suppress interactive request for a default password if available. + */ + #[cfg(USE_OPENSSL_ENGINE)] + extern "C" fn ssl_ui_writer(mut ui: *mut UI, mut uis: *mut UI_STRING) -> i32 { + unsafe { + match UI_get_string_type(uis) as u32 { + 1 | 2 => { + if !(UI_get0_user_data(ui)).is_null() && UI_get_input_flags(uis) & 0x2 as i32 != 0 { + return 1 as i32; + } + } + _ => {} + } + return (UI_method_get_writer(UI_OpenSSL())).expect("non-null function pointer")(ui, uis); + } + } + + /* + * Check if a given string is a PKCS#11 URI + */ + #[cfg(USE_OPENSSL_ENGINE)] + extern "C" fn is_pkcs11_uri(mut string: *const libc::c_char) -> bool { + unsafe { + return !string.is_null() + && Curl_strncasecompare( + string, + b"pkcs11:\0" as *const u8 as *const libc::c_char, + 7 as size_t, + ) != 0; + } + } + extern "C" fn SSL_CTX_use_certificate_blob( + mut ctx: *mut SSL_CTX, + mut blob: *const curl_blob, + mut type_0: i32, + mut key_passwd: *const libc::c_char, + ) -> i32 { + let mut current_block: u64; + let mut ret: i32 = 0 as i32; + let mut x: *mut X509 = 0 as *mut X509; + /* the typecast of blob->len is fine since it is guaranteed to never be + larger than CURL_MAX_INPUT_LENGTH */ + let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; + if in_0.is_null() { + return CURLE_OUT_OF_MEMORY as i32; + } + 'end: loop { + if type_0 == 2 as i32 { + /* j = ERR_R_ASN1_LIB; */ + x = unsafe { d2i_X509_bio(in_0, 0 as *mut *mut X509) }; + } else if type_0 == 1 as i32 { + /* ERR_R_PEM_LIB; */ + x = unsafe { + PEM_read_bio_X509( + in_0, + 0 as *mut *mut X509, + Some( + passwd_callback + as unsafe extern "C" fn( + *mut libc::c_char, + i32, + i32, + *mut libc::c_void, + ) -> i32, + ), + key_passwd as *mut libc::c_void, + ) + }; + } else { + ret = 0 as i32; + break 'end; + } + if x.is_null() { + ret = 0 as i32; + break 'end; + } + ret = unsafe { SSL_CTX_use_certificate(ctx, x) }; + break 'end; + } + unsafe { + X509_free(x); + BIO_free(in_0); + } + return ret; + } + + extern "C" fn SSL_CTX_use_PrivateKey_blob( + mut ctx: *mut SSL_CTX, + mut blob: *const curl_blob, + mut type_0: i32, + mut key_passwd: *const libc::c_char, + ) -> i32 { + /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ + let mut current_block: u64; + let mut ret: i32 = 0 as i32; + let mut pkey: *mut EVP_PKEY = 0 as *mut EVP_PKEY; + let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; + if in_0.is_null() { + return CURLE_OUT_OF_MEMORY as i32; + } + 'end: loop { + if type_0 == 1 as i32 { + pkey = unsafe { + PEM_read_bio_PrivateKey( + in_0, + 0 as *mut *mut EVP_PKEY, + Some( + passwd_callback + as unsafe extern "C" fn( + *mut libc::c_char, + i32, + i32, + *mut libc::c_void, + ) -> i32, + ), + key_passwd as *mut libc::c_void, + ) + }; + } else if type_0 == 2 as i32 { + pkey = unsafe { d2i_PrivateKey_bio(in_0, 0 as *mut *mut EVP_PKEY) }; + } else { + ret = 0 as i32; + break 'end; + } + if pkey.is_null() { + ret = 0 as i32; + break 'end; + } + unsafe { + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + } + break 'end; + } + unsafe { + BIO_free(in_0); + } + return ret; + } + extern "C" fn SSL_CTX_use_certificate_chain_blob( + mut ctx: *mut SSL_CTX, + mut blob: *const curl_blob, + mut key_passwd: *const libc::c_char, + ) -> i32 { + /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ + // TODO - 672 与OPENSSL_VERSION_NUMBER有关的条件编译 + let mut current_block: u64; + let mut ret: i32 = 0 as i32; + let mut x: *mut X509 = 0 as *mut X509; + let mut passwd_callback_userdata: *mut libc::c_void = key_passwd as *mut libc::c_void; + let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; + if in_0.is_null() { + return CURLE_OUT_OF_MEMORY as i32; + } + unsafe { + ERR_clear_error(); + x = PEM_read_bio_X509_AUX( + in_0, + 0 as *mut *mut X509, + Some( + passwd_callback + as unsafe extern "C" fn(*mut libc::c_char, i32, i32, *mut libc::c_void) -> i32, + ), + key_passwd as *mut libc::c_void, + ); + } + 'end: loop { + if x.is_null() { + ret = 0 as i32; + break 'end; + } + ret = unsafe { SSL_CTX_use_certificate(ctx, x) }; + if unsafe { ERR_peek_error() } != 0 as u64 { + ret = 0 as i32; + } + if ret != 0 { + let mut ca: *mut X509 = 0 as *mut X509; + let mut err: u64 = 0; + if unsafe { + SSL_CTX_ctrl( + ctx, + 88 as i32, + 0 as i64, + 0 as *mut libc::c_void as *mut libc::c_char as *mut libc::c_void, + ) + } == 0 + { + ret = 0 as i32; + break 'end; + } + loop { + ca = unsafe { + PEM_read_bio_X509( + in_0, + 0 as *mut *mut X509, + Some( + passwd_callback + as unsafe extern "C" fn( + *mut libc::c_char, + i32, + i32, + *mut libc::c_void, + ) -> i32, + ), + passwd_callback_userdata, + ) + }; + if ca.is_null() { + break; + } + if unsafe { + SSL_CTX_ctrl( + ctx, + 89 as i32, + 0 as i64, + ca as *mut libc::c_char as *mut libc::c_void, + ) + } == 0 + { + unsafe { + X509_free(ca); + } + ret = 0 as i32; + break 'end; + } + } + err = unsafe { ERR_peek_last_error() }; + if (err >> 24 as i64 & 0xff as u64) as i32 == 9 as i32 + && (err & 0xfff as u64) as i32 == 108 as i32 + { + unsafe { ERR_clear_error() }; + } else { + ret = 0 as i32; + } + } + break 'end; + } + unsafe { + X509_free(x); + BIO_free(in_0); + } + return ret; + } + + extern "C" fn cert_stuff( + mut data: *mut Curl_easy, + mut ctx: *mut SSL_CTX, + mut cert_file: *mut libc::c_char, + mut cert_blob: *const curl_blob, + mut cert_type: *const libc::c_char, + mut key_file: *mut libc::c_char, + mut key_blob: *const curl_blob, + mut key_type: *const libc::c_char, + mut key_passwd: *mut libc::c_char, + ) -> i32 { + let mut current_block: u64; + let mut error_buffer: [libc::c_char; 256] = [0; 256]; + let mut check_privkey: bool = 1 as i32 != 0; + let mut file_type: i32 = do_file_type(cert_type); + if !cert_file.is_null() || !cert_blob.is_null() || file_type == 42 as i32 { + let mut ssl: *mut SSL = 0 as *mut SSL; + let mut x509: *mut X509 = 0 as *mut X509; + let mut cert_done: i32 = 0 as i32; + let mut cert_use_result: i32 = 0; + if !key_passwd.is_null() { + /* set the password in the callback userdata */ + unsafe { + SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd as *mut libc::c_void); + /* Set passwd callback: */ + SSL_CTX_set_default_passwd_cb( + ctx, + Some( + passwd_callback + as unsafe extern "C" fn( + *mut libc::c_char, + i32, + i32, + *mut libc::c_void, + ) -> i32, + ), + ); + } + } + + match file_type { + 1 => { + /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ + cert_use_result = if !cert_blob.is_null() { + SSL_CTX_use_certificate_chain_blob(ctx, cert_blob, key_passwd) + } else { + unsafe { SSL_CTX_use_certificate_chain_file(ctx, cert_file) } + }; + if cert_use_result != 1 as i32 { + unsafe { + Curl_failf( + data, + b"could not load PEM client certificate, OpenSSL error %s, (no key found, wrong pass phrase, or wrong file format?)\0" + as *const u8 as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + return 0 as i32; + } + } + 2 => { + /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but + we use the case above for PEM so this can only be performed with + ASN1 files. */ + cert_use_result = if !cert_blob.is_null() { + SSL_CTX_use_certificate_blob(ctx, cert_blob, file_type, key_passwd) + } else { + unsafe { SSL_CTX_use_certificate_file(ctx, cert_file, file_type) } + }; + if cert_use_result != 1 as i32 { + unsafe { + Curl_failf( + data, + b"could not load ASN1 client certificate, OpenSSL error %s, (no key found, wrong pass phrase, or wrong file format?)\0" + as *const u8 as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + return 0 as i32; + } + } + // DONE - 804 + 42 => { + unsafe { + /* Implicitly use pkcs11 engine if none was provided and the + * cert_file is a PKCS#11 URI */ + #[cfg(all(USE_OPENSSL_ENGINE, ENGINE_CTRL_GET_CMD_FROM_NAME))] + if ((*data).state.engine).is_null() { + if is_pkcs11_uri(cert_file) { + if ossl_set_engine( + data, + b"pkcs11\0" as *const u8 as *const libc::c_char, + ) as u32 + != CURLE_OK as u32 + { + return 0 as i32; + } + } + } + #[cfg(all(USE_OPENSSL_ENGINE, ENGINE_CTRL_GET_CMD_FROM_NAME))] + if !((*data).state.engine).is_null() { + let mut cmd_name: *const libc::c_char = + b"LOAD_CERT_CTRL\0" as *const u8 as *const libc::c_char; + let mut params: C2RustUnnamed_13 = C2RustUnnamed_13 { + cert_id: 0 as *const libc::c_char, + cert: 0 as *mut X509, + }; + params.cert_id = cert_file; + params.cert = 0 as *mut X509; + /* Does the engine supports LOAD_CERT_CTRL ? */ + if ENGINE_ctrl( + (*data).state.engine as *mut ENGINE, + 13 as i32, + 0 as i64, + cmd_name as *mut libc::c_void, + None, + ) == 0 + { + Curl_failf( + data, + b"ssl engine does not support loading certificates\0" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + /* Load the certificate from the engine */ + if ENGINE_ctrl_cmd( + (*data).state.engine as *mut ENGINE, + cmd_name, + 0 as i64, + &mut params as *mut C2RustUnnamed_13 as *mut libc::c_void, + None, + 1 as i32, + ) == 0 + { + Curl_failf( + data, + b"ssl engine cannot load client cert with id '%s' [%s]\0" + as *const u8 + as *const libc::c_char, + cert_file, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return 0 as i32; + } + if (params.cert).is_null() { + Curl_failf( + data, + b"ssl engine didn't initialized the certificate properly.\0" + as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + if SSL_CTX_use_certificate(ctx, params.cert) != 1 as i32 { + Curl_failf( + data, + b"unable to set client certificate\0" as *const u8 + as *const libc::c_char, + ); + X509_free(params.cert); + return 0 as i32; + } + X509_free(params.cert); /* we don't need the handle any more... */ + } else { + Curl_failf( + data, + b"crypto engine not set, can't load certificate\0" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + #[cfg(any(not(USE_OPENSSL_ENGINE), not(ENGINE_CTRL_GET_CMD_FROM_NAME)))] + Curl_failf( + data, + b"file type ENG for certificate not implemented" as *const u8 + as *const libc::c_char, + ); + } + #[cfg(any(not(USE_OPENSSL_ENGINE), not(ENGINE_CTRL_GET_CMD_FROM_NAME)))] + return 0 as i32; + } + 43 => { + let mut cert_bio: *mut BIO = 0 as *mut BIO; + let mut p12: *mut PKCS12 = 0 as *mut PKCS12; + let mut pri: *mut EVP_PKEY = 0 as *mut EVP_PKEY; + let mut ca: *mut stack_st_X509 = 0 as *mut stack_st_X509; + if !cert_blob.is_null() { + unsafe { + cert_bio = BIO_new_mem_buf((*cert_blob).data, (*cert_blob).len as i32); + if cert_bio.is_null() { + Curl_failf( + data, + b"BIO_new_mem_buf NULL, OpenSSL error %s\0" as *const u8 + as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + return 0 as i32; + } + } else { + unsafe { + cert_bio = BIO_new(BIO_s_file()); + if cert_bio.is_null() { + Curl_failf( + data, + b"BIO_new return NULL, OpenSSL error %s\0" as *const u8 + as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return 0 as i32; + } + if BIO_ctrl( + cert_bio, + 108 as i32, + (0x1 as i32 | 0x2 as i32) as i64, + cert_file as *mut libc::c_void, + ) as i32 + <= 0 as i32 + { + Curl_failf( + data, + b"could not open PKCS12 file '%s'\0" as *const u8 + as *const libc::c_char, + cert_file, + ); + BIO_free(cert_bio); + return 0 as i32; + } + } + } + unsafe { + p12 = d2i_PKCS12_bio(cert_bio, 0 as *mut *mut PKCS12); + BIO_free(cert_bio); + if p12.is_null() { + Curl_failf( data, - b"could not load PEM client certificate, OpenSSL error %s, (no key found, wrong pass phrase, or wrong file format?)\0" + b"error reading PKCS12 file '%s'\0" as *const u8 as *const libc::c_char, + if !cert_blob.is_null() { + b"(memory blob)\0" as *const u8 as *const libc::c_char + } else { + cert_file as *const libc::c_char + }, + ); + return 0 as i32; + } + PKCS12_PBE_add(); + if PKCS12_parse(p12, key_passwd, &mut pri, &mut x509, &mut ca) == 0 { + Curl_failf( + data, + b"could not parse PKCS12 file, check password, OpenSSL error %s\0" as *const u8 as *const libc::c_char, ossl_strerror( ERR_get_error(), @@ -741,3287 +959,3087 @@ extern "C" fn cert_stuff( ::std::mem::size_of::<[libc::c_char; 256]>() as u64, ), ); - } - return 0 as i32; - } - } - 2 => { - /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but - we use the case above for PEM so this can only be performed with - ASN1 files. */ - cert_use_result = if !cert_blob.is_null() { - SSL_CTX_use_certificate_blob(ctx, cert_blob, file_type, key_passwd) - } else { - unsafe { SSL_CTX_use_certificate_file(ctx, cert_file, file_type) } - }; - if cert_use_result != 1 as i32 { - unsafe { - Curl_failf( + PKCS12_free(p12); + return 0 as i32; + } + + PKCS12_free(p12); + } + 'fail: loop { + if unsafe { SSL_CTX_use_certificate(ctx, x509) } != 1 as i32 { + unsafe { + Curl_failf( + data, + b"could not load PKCS12 client certificate, OpenSSL error %s\0" + as *const u8 + as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + break 'fail; + } + if unsafe { SSL_CTX_use_PrivateKey(ctx, pri) } != 1 as i32 { + unsafe { + Curl_failf( + data, + b"unable to use private key from PKCS12 file '%s'\0" as *const u8 + as *const libc::c_char, + cert_file, + ); + } + break 'fail; + } + if unsafe { SSL_CTX_check_private_key(ctx) } == 0 { + unsafe { + Curl_failf( data, - b"could not load ASN1 client certificate, OpenSSL error %s, (no key found, wrong pass phrase, or wrong file format?)\0" + b"private key from PKCS12 file '%s' does not match certificate in same file\0" as *const u8 as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), + cert_file, ); - } - return 0 as i32; - } - } - // DONE - 804 - 42 => { - unsafe { - /* Implicitly use pkcs11 engine if none was provided and the - * cert_file is a PKCS#11 URI */ - #[cfg(all(USE_OPENSSL_ENGINE, ENGINE_CTRL_GET_CMD_FROM_NAME))] - if ((*data).state.engine).is_null() { - if is_pkcs11_uri(cert_file) { - if ossl_set_engine( - data, - b"pkcs11\0" as *const u8 as *const libc::c_char, - ) as u32 - != CURLE_OK as u32 - { - return 0 as i32; - } - } - } - #[cfg(all(USE_OPENSSL_ENGINE, ENGINE_CTRL_GET_CMD_FROM_NAME))] - if !((*data).state.engine).is_null() { - let mut cmd_name: *const libc::c_char = - b"LOAD_CERT_CTRL\0" as *const u8 as *const libc::c_char; - let mut params: C2RustUnnamed_13 = C2RustUnnamed_13 { - cert_id: 0 as *const libc::c_char, - cert: 0 as *mut X509, - }; - params.cert_id = cert_file; - params.cert = 0 as *mut X509; - /* Does the engine supports LOAD_CERT_CTRL ? */ - if ENGINE_ctrl( - (*data).state.engine as *mut ENGINE, - 13 as i32, - 0 as i64, - cmd_name as *mut libc::c_void, - None, - ) == 0 - { - Curl_failf( - data, - b"ssl engine does not support loading certificates\0" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - /* Load the certificate from the engine */ - if ENGINE_ctrl_cmd( - (*data).state.engine as *mut ENGINE, - cmd_name, - 0 as i64, - &mut params as *mut C2RustUnnamed_13 as *mut libc::c_void, - None, - 1 as i32, - ) == 0 - { - Curl_failf( - data, - b"ssl engine cannot load client cert with id '%s' [%s]\0" - as *const u8 - as *const libc::c_char, - cert_file, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return 0 as i32; - } - if (params.cert).is_null() { - Curl_failf( - data, - b"ssl engine didn't initialized the certificate properly.\0" - as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - if SSL_CTX_use_certificate(ctx, params.cert) != 1 as i32 { - Curl_failf( - data, - b"unable to set client certificate\0" as *const u8 - as *const libc::c_char, - ); - X509_free(params.cert); - return 0 as i32; - } - X509_free(params.cert); /* we don't need the handle any more... */ - } else { - Curl_failf( - data, - b"crypto engine not set, can't load certificate\0" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - #[cfg(any(not(USE_OPENSSL_ENGINE), not(ENGINE_CTRL_GET_CMD_FROM_NAME)))] - Curl_failf( - data, - b"file type ENG for certificate not implemented" as *const u8 - as *const libc::c_char, - ); - } - #[cfg(any(not(USE_OPENSSL_ENGINE), not(ENGINE_CTRL_GET_CMD_FROM_NAME)))] - return 0 as i32; - } - 43 => { - let mut cert_bio: *mut BIO = 0 as *mut BIO; - let mut p12: *mut PKCS12 = 0 as *mut PKCS12; - let mut pri: *mut EVP_PKEY = 0 as *mut EVP_PKEY; - let mut ca: *mut stack_st_X509 = 0 as *mut stack_st_X509; - if !cert_blob.is_null() { - unsafe { - cert_bio = BIO_new_mem_buf((*cert_blob).data, (*cert_blob).len as i32); - if cert_bio.is_null() { - Curl_failf( - data, - b"BIO_new_mem_buf NULL, OpenSSL error %s\0" as *const u8 - as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - } - return 0 as i32; - } - } else { - unsafe { - cert_bio = BIO_new(BIO_s_file()); - if cert_bio.is_null() { - Curl_failf( - data, - b"BIO_new return NULL, OpenSSL error %s\0" as *const u8 - as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return 0 as i32; - } - if BIO_ctrl( - cert_bio, - 108 as i32, - (0x1 as i32 | 0x2 as i32) as i64, - cert_file as *mut libc::c_void, - ) as i32 - <= 0 as i32 - { - Curl_failf( - data, - b"could not open PKCS12 file '%s'\0" as *const u8 - as *const libc::c_char, - cert_file, - ); - BIO_free(cert_bio); - return 0 as i32; - } - } - } - unsafe { - p12 = d2i_PKCS12_bio(cert_bio, 0 as *mut *mut PKCS12); - BIO_free(cert_bio); - if p12.is_null() { - Curl_failf( - data, - b"error reading PKCS12 file '%s'\0" as *const u8 as *const libc::c_char, - if !cert_blob.is_null() { - b"(memory blob)\0" as *const u8 as *const libc::c_char - } else { - cert_file as *const libc::c_char - }, - ); - return 0 as i32; - } - PKCS12_PBE_add(); - if PKCS12_parse(p12, key_passwd, &mut pri, &mut x509, &mut ca) == 0 { - Curl_failf( - data, - b"could not parse PKCS12 file, check password, OpenSSL error %s\0" - as *const u8 as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - PKCS12_free(p12); - return 0 as i32; - } - - PKCS12_free(p12); - } - 'fail: loop { - if unsafe { SSL_CTX_use_certificate(ctx, x509) } != 1 as i32 { - unsafe { - Curl_failf( - data, - b"could not load PKCS12 client certificate, OpenSSL error %s\0" - as *const u8 - as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - } - break 'fail; - } - if unsafe { SSL_CTX_use_PrivateKey(ctx, pri) } != 1 as i32 { - unsafe { - Curl_failf( - data, - b"unable to use private key from PKCS12 file '%s'\0" as *const u8 - as *const libc::c_char, - cert_file, - ); - } - break 'fail; - } - if unsafe { SSL_CTX_check_private_key(ctx) } == 0 { - unsafe { - Curl_failf( - data, - b"private key from PKCS12 file '%s' does not match certificate in same file\0" - as *const u8 as *const libc::c_char, - cert_file, - ); - } - break 'fail; - } - /* Set Certificate Verification chain */ - if !ca.is_null() { - while sk_X509_num(ca) != 0 { - /* - * Note that sk_X509_pop() is used below to make sure the cert is - * removed from the stack properly before getting passed to - * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously - * we used sk_X509_value() instead, but then we'd clean it in the - * subsequent sk_X509_pop_free() call. - */ - let mut x: *mut X509 = sk_X509_pop(ca); - if unsafe { SSL_CTX_add_client_CA(ctx, x) } == 0 { - unsafe { - X509_free(x); - Curl_failf( - data, - b"cannot add certificate to client CA list\0" as *const u8 - as *const libc::c_char, - ); - } - break 'fail; - } - if unsafe { - SSL_CTX_ctrl( - ctx, - 14 as i32, - 0 as i64, - x as *mut libc::c_char as *mut libc::c_void, - ) - } == 0 - { - unsafe { - X509_free(x); - Curl_failf( - data, - b"cannot add certificate to certificate chain\0" - as *const u8 - as *const libc::c_char, - ); - } - break 'fail; - } - } - break 'fail; - } - cert_done = 1 as i32; - } - unsafe { - EVP_PKEY_free(pri); - X509_free(x509); - - #[cfg(USE_AMISSL)] - sk_X509_pop_free( - ca, - Some(Curl_amiga_X509_free as unsafe extern "C" fn(*mut X509) -> ()), - ); - #[cfg(not(USE_AMISSL))] - sk_X509_pop_free(ca, Some(X509_free as unsafe extern "C" fn(*mut X509) -> ())); - if cert_done == 0 { - return 0 as i32; - } - } - } - _ => { - unsafe { - Curl_failf( - data, - b"not supported file type '%s' for certificate\0" as *const u8 - as *const libc::c_char, - cert_type, - ); - } - return 0 as i32; - } - } - if key_file.is_null() && key_blob.is_null() { - key_file = cert_file; - key_blob = cert_blob; - } else { - file_type = do_file_type(key_type); - } - let mut current_block_141: u64; - match file_type { - 1 => { - if cert_done != 0 { - current_block_141 = 14358540534591340610; - } else { - current_block_141 = 2766187242236248435; - } - } - 2 => { - current_block_141 = 2766187242236248435; - } - // DONE - 1011 - 42 => match () { - #[cfg(USE_OPENSSL_ENGINE)] - _ => { - /* XXXX still needs some work */ - let mut priv_key: *mut EVP_PKEY = 0 as *mut EVP_PKEY; - unsafe { - /* Implicitly use pkcs11 engine if none was provided and the - * key_file is a PKCS#11 URI */ - if ((*data).state.engine).is_null() { - if is_pkcs11_uri(key_file) { - if ossl_set_engine( - data, - b"pkcs11\0" as *const u8 as *const libc::c_char, - ) as u32 - != CURLE_OK as u32 - { - return 0 as i32; - } - } - } - if !((*data).state.engine).is_null() { - let mut ui_method: *mut UI_METHOD = UI_create_method( - b"curl user interface\0" as *const u8 as *const libc::c_char - as *mut libc::c_char, - ); - if ui_method.is_null() { - Curl_failf( - data, - b"unable do create OpenSSL user-interface method\0" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); - UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); - UI_method_set_reader( - ui_method, - Some( - ssl_ui_reader - as unsafe extern "C" fn(*mut UI, *mut UI_STRING) -> i32, - ), - ); - UI_method_set_writer( - ui_method, - Some( - ssl_ui_writer - as unsafe extern "C" fn(*mut UI, *mut UI_STRING) -> i32, - ), - ); - /* the typecast below was added to please mingw32 */ - priv_key = ENGINE_load_private_key( - (*data).state.engine as *mut ENGINE, - key_file, - ui_method, - key_passwd as *mut libc::c_void, - ); - UI_destroy_method(ui_method); - if priv_key.is_null() { - Curl_failf( - data, - b"failed to load private key from crypto engine\0" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - if SSL_CTX_use_PrivateKey(ctx, priv_key) != 1 as i32 { - Curl_failf( - data, - b"unable to set private key\0" as *const u8 - as *const libc::c_char, - ); - EVP_PKEY_free(priv_key); /* we don't need the handle any more... */ - return 0 as i32; - } - EVP_PKEY_free(priv_key); - } else { - Curl_failf( - data, - b"crypto engine not set, can't load private key\0" as *const u8 - as *const libc::c_char, - ); - - return 0 as i32; - } - current_block_141 = 14358540534591340610; - } - } - #[cfg(not(USE_OPENSSL_ENGINE))] - _ => unsafe { - Curl_failf( - data, - b"file type ENG for private key not supported" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - }, - }, - 43 => { - if cert_done == 0 { - unsafe { - Curl_failf( - data, - b"file type P12 for private key not supported\0" as *const u8 - as *const libc::c_char, - ); - } - return 0 as i32; - } - current_block_141 = 14358540534591340610; - } - _ => { - unsafe { - Curl_failf( - data, - b"not supported file type for private key\0" as *const u8 - as *const libc::c_char, - ); - } - return 0 as i32; - } - } - match current_block_141 { - 2766187242236248435 => { - cert_use_result = if !key_blob.is_null() { - SSL_CTX_use_PrivateKey_blob(ctx, key_blob, file_type, key_passwd) - } else { - unsafe { SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) } - }; - if cert_use_result != 1 as i32 { - unsafe { - Curl_failf( - data, - b"unable to set private key file: '%s' type %s\0" as *const u8 - as *const libc::c_char, - if !key_file.is_null() { - key_file as *const libc::c_char - } else { - b"(memory blob)\0" as *const u8 as *const libc::c_char - }, - if !key_type.is_null() { - key_type - } else { - b"PEM\0" as *const u8 as *const libc::c_char - }, - ); - } - return 0 as i32; - } - } - _ => {} - } - unsafe { - ssl = SSL_new(ctx); - if ssl.is_null() { - Curl_failf( - data, - b"unable to create an SSL structure\0" as *const u8 as *const libc::c_char, - ); - return 0 as i32; - } - x509 = SSL_get_certificate(ssl); - } - /* This version was provided by Evan Jordan and is supposed to not - leak memory as the previous version: */ - if !x509.is_null() { - unsafe { - let mut pktmp: *mut EVP_PKEY = X509_get_pubkey(x509); - EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl)); - EVP_PKEY_free(pktmp); - } - } - #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL)))] - let mut priv_key_0: *mut EVP_PKEY = unsafe { SSL_get_privatekey(ssl) }; - - #[cfg(all( - not(OPENSSL_NO_RSA), - not(OPENSSL_IS_BORINGSSL), - not(HAVE_OPAQUE_EVP_PKEY) - ))] - // TODO 未开的情况下不是 = 0,是另一种情况 - let mut pktype: i32 = 0; - #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL), HAVE_OPAQUE_EVP_PKEY))] - let mut pktype: i32 = EVP_PKEY_id(priv_key_0); - // TODO - 不开HAVE_OPAQUE_EVP_PKEY选项 - // #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL), not(HAVE_OPAQUE_EVP_PKEY)))] - #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL)))] - if pktype == 6 as i32 { - let mut rsa: *mut RSA = unsafe { EVP_PKEY_get1_RSA(priv_key_0) }; - unsafe { - if RSA_flags(rsa) & 0x1 as i32 != 0 { - check_privkey = 0 as i32 != 0; - } - RSA_free(rsa); /* Decrement reference count */ - } - } - unsafe { - SSL_free(ssl); - } - /* If we are using DSA, we can copy the parameters from - * the private key */ - if check_privkey as i32 == 1 as i32 { - /* Now we know that a key and cert have been set against - * the SSL context */ - if unsafe { SSL_CTX_check_private_key(ctx) == 0 } { - unsafe { - Curl_failf( - data, - b"Private key does not match the certificate public key\0" as *const u8 - as *const libc::c_char, - ); - } - return 0 as i32; - } - } - } - return 1 as i32; -} - -/* returns non-zero on failure */ -extern "C" fn x509_name_oneline( - mut a: *mut X509_NAME, - mut buf: *mut libc::c_char, - mut size: size_t, -) -> i32 { - let mut bio_out: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; - let mut biomem: *mut BUF_MEM = 0 as *mut BUF_MEM; - let mut rc: i32 = 0; - if bio_out.is_null() { - return 1 as i32; /* alloc failed! */ - } - rc = unsafe { X509_NAME_print_ex(bio_out, a, 0 as i32, ((3 as i32) << 16 as i32) as u64) }; - unsafe { - BIO_ctrl( - bio_out, - 115 as i32, - 0 as i64, - &mut biomem as *mut *mut BUF_MEM as *mut libc::c_char as *mut libc::c_void, - ); - if (*biomem).length < size { - size = (*biomem).length; - } else { - size = size.wrapping_sub(1); /* don't overwrite the buffer end */ - } - memcpy( - buf as *mut libc::c_void, - (*biomem).data as *const libc::c_void, - size, - ); - *buf.offset(size as isize) = 0 as libc::c_char; - BIO_free(bio_out); - } - return (rc == 0) as i32; -} - -/** - * Global SSL init - * - * @retval 0 error initializing SSL - * @retval 1 SSL initialized successfully - */ -extern "C" fn ossl_init() -> i32 { - #[cfg(OPENSSL_INIT_ENGINE_ALL_BUILTIN)] - let flag_1 = 0x200 as i64 | 0x400 as i64 | 0x1000 as i64 | 0x2000 as i64 | 0x4000 as i64; - #[cfg(not(OPENSSL_INIT_ENGINE_ALL_BUILTIN))] - let flag_1 = 0x0000 as i64; - #[cfg(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG)] - let flag_2 = 0x80 as i64; - #[cfg(not(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG))] - let flag_2 = 0x40 as i64; - let flags: uint64_t = (flag_1 | flag_2 | 0 as i64) as uint64_t; - - unsafe { - OPENSSL_init_ssl(flags, 0 as *const OPENSSL_INIT_SETTINGS); - } - Curl_tls_keylog_open(); - /* Initialize the extra data indexes */ - if ossl_get_ssl_data_index() < 0 as i32 - || ossl_get_ssl_conn_index() < 0 as i32 - || ossl_get_ssl_sockindex_index() < 0 as i32 - || ossl_get_proxy_index() < 0 as i32 - { - return 0 as i32; - } - return 1 as i32; -} - -/* Global cleanup */ -extern "C" fn ossl_cleanup() { - Curl_tls_keylog_close(); -} - -/* - * This function is used to determine connection status. - * - * Return codes: - * 1 means the connection is still in place - * 0 means the connection has been closed - * -1 means the connection status is unknown - */ -extern "C" fn ossl_check_cxn(mut conn: *mut connectdata) -> i32 { - /* SSL_peek takes data out of the raw recv buffer without peeking so we use - recv MSG_PEEK instead. Bug #795 */ - #[cfg(MSG_PEEK)] - let mut buf: libc::c_char = 0; - #[cfg(MSG_PEEK)] - let mut nread: ssize_t = recv( - (*conn).sock[0 as usize], - &mut buf as *mut libc::c_char as *mut libc::c_void, - 1 as size_t, - MSG_PEEK as i32, - ); - #[cfg(MSG_PEEK)] - if nread == 0 as i64 { - return 0 as i32; /* connection has been closed */ - } - #[cfg(MSG_PEEK)] - if nread == 1 as i64 { - return 1 as i32; /* connection still in place */ - } else { - if nread == -(1 as i32) as i64 { - let mut err: i32 = *__errno_location(); - // 写法不对,rust中如何判断宏值的相等 - // TODO - 1276 - if err == 115 as i32 || err == 11 as i32 { - return 1 as i32; /* connection still in place */ - } - // DONE - 1282 - #[cfg(ECONNABORTED)] - let ECONNABORTED_flag = err == 103; - #[cfg(not(ECONNABORTED))] - let ECONNABORTED_flag = false; - #[cfg(ENETDOWN)] - let ENETDOWN_flag = err == 100; - #[cfg(not(ENETDOWN))] - let ENETDOWN_flag = false; - #[cfg(ENETRESET)] - let ENETRESET_flag = err == 102; - #[cfg(not(ENETRESET))] - let ENETRESET_flag = false; - #[cfg(ESHUTDOWN)] - let ESHUTDOWN_flag = err == 108; - #[cfg(not(ESHUTDOWN))] - let ESHUTDOWN_flag = false; - #[cfg(ETIMEDOUT)] - let ETIMEDOUT_flag = err == 110; - #[cfg(not(ETIMEDOUT))] - let ETIMEDOUT_flag = false; - if err == 104 as i32 - || ECONNABORTED_flag - || ENETDOWN_flag - || ENETRESET_flag - || ENETDOWN_flag - || ETIMEDOUT_flag - || err == 107 as i32 - { - return 0 as i32; /* connection has been closed */ - } - } - } - return -(1 as i32); /* connection status unknown */ -} - -/* Selects an OpenSSL crypto engine - */ -extern "C" fn ossl_set_engine( - mut data: *mut Curl_easy, - mut engine: *const libc::c_char, -) -> CURLcode { - if cfg!(USE_OPENSSL_ENGINE) { - let mut e: *mut ENGINE = 0 as *mut ENGINE; - e = unsafe { ENGINE_by_id(engine) }; - if e.is_null() { - unsafe { - Curl_failf( - data, - b"SSL Engine '%s' not found\0" as *const u8 as *const libc::c_char, - engine, - ); - } - return CURLE_SSL_ENGINE_NOTFOUND; - } - unsafe { - if !((*data).state.engine).is_null() { - ENGINE_finish((*data).state.engine as *mut ENGINE); - ENGINE_free((*data).state.engine as *mut ENGINE); - (*data).state.engine = 0 as *mut libc::c_void; - } - if ENGINE_init(e) == 0 { - let mut buf: [libc::c_char; 256] = [0; 256]; - ENGINE_free(e); - Curl_failf( - data, - b"Failed to initialise SSL Engine '%s': %s\0" as *const u8 - as *const libc::c_char, - engine, - ossl_strerror( - ERR_get_error(), - buf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return CURLE_SSL_ENGINE_INITFAILED; - } - (*data).state.engine = e as *mut libc::c_void; - } - return CURLE_OK; - } else { - unsafe { - Curl_infof( - data, - b"SSL Engine not supported\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_SSL_ENGINE_NOTFOUND; - } -} - -/* Sets engine as default for all SSL operations - */ -extern "C" fn ossl_set_engine_default(mut data: *mut Curl_easy) -> CURLcode { - if cfg!(USE_OPENSSL_ENGINE) { - unsafe { - if !((*data).state.engine).is_null() { - if ENGINE_set_default((*data).state.engine as *mut ENGINE, 0xffff as i32 as u32) - > 0 as i32 - { - Curl_infof( - data, - b"set default crypto engine '%s'\0" as *const u8 as *const libc::c_char, - ENGINE_get_id((*data).state.engine as *const ENGINE), - ); - } else { - Curl_failf( - data, - b"set default crypto engine '%s' failed\0" as *const u8 - as *const libc::c_char, - ENGINE_get_id((*data).state.engine as *const ENGINE), - ); - return CURLE_SSL_ENGINE_SETFAILED; - } - } - } - } - return CURLE_OK; -} - -/* Return list of OpenSSL crypto engine names. - */ -extern "C" fn ossl_engines_list(mut data: *mut Curl_easy) -> *mut curl_slist { - let mut list: *mut curl_slist = 0 as *mut curl_slist; - if cfg!(USE_OPENSSL_ENGINE) { - let mut beg: *mut curl_slist = 0 as *mut curl_slist; - let mut e: *mut ENGINE = 0 as *mut ENGINE; - e = unsafe { ENGINE_get_first() }; - while !e.is_null() { - unsafe { - beg = curl_slist_append(list, ENGINE_get_id(e)); - if beg.is_null() { - curl_slist_free_all(list); - return 0 as *mut curl_slist; - } - } - list = beg; - e = unsafe { ENGINE_get_next(e) }; - } - } - return list; -} -extern "C" fn ossl_closeone( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut connssl: *mut ssl_connect_data, -) { - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - unsafe { - if !((*backend).handle).is_null() { - let mut buf: [libc::c_char; 32] = [0; 32]; - (*(*conn).ssl[0 as usize].backend).logger = data; - /* Maybe the server has already sent a close notify alert. - Read it to avoid an RST on the TCP connection. */ - SSL_read( - (*backend).handle, - buf.as_mut_ptr() as *mut libc::c_void, - ::std::mem::size_of::<[libc::c_char; 32]>() as i32, - ); - SSL_shutdown((*backend).handle); - SSL_set_connect_state((*backend).handle); - SSL_free((*backend).handle); - (*backend).handle = 0 as *mut SSL; - } - if !((*backend).ctx).is_null() { - SSL_CTX_free((*backend).ctx); - (*backend).ctx = 0 as *mut SSL_CTX; - } - } -} - -/* - * This function is called when an SSL connection is closed. - */ -extern "C" fn ossl_close(mut data: *mut Curl_easy, mut conn: *mut connectdata, mut sockindex: i32) { - unsafe { - ossl_closeone( - data, - conn, - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize), - ); - #[cfg(not(CURL_DISABLE_PROXY))] - ossl_closeone( - data, - conn, - &mut *((*conn).proxy_ssl).as_mut_ptr().offset(sockindex as isize), - ); - } -} - -/* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ -extern "C" fn ossl_shutdown( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) -> i32 { - let mut retval: i32 = 0 as i32; - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - let mut buf: [libc::c_char; 256] = [0; 256]; /* We will use this for the OpenSSL error buffer, so it has - to be at least 256 bytes long. */ - let mut sslerror: u64 = 0; - let mut nread: ssize_t = 0; - let mut buffsize: i32 = 0; - let mut err: i32 = 0; - let mut done: bool = 0 as i32 != 0; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - let mut loop_0: i32 = 10 as i32; - /* This has only been tested on the proftpd server, and the mod_tls code - sends a close notify alert without waiting for a close notify alert in - response. Thus we wait for a close notify alert from the server, but - we do not send one. Let's hope other servers do the same... */ - #[cfg(not(CURL_DISABLE_FTP))] - unsafe { - if (*data).set.ftp_ccc as u32 == CURLFTPSSL_CCC_ACTIVE as u32 { - SSL_shutdown((*backend).handle); - } - } - if unsafe { !((*backend).handle).is_null() } { - buffsize = ::std::mem::size_of::<[libc::c_char; 256]>() as i32; - while !done && { - let fresh5 = loop_0; - loop_0 = loop_0 - 1; - fresh5 != 0 - } { - let mut what: i32 = unsafe { - Curl_socket_check( - (*conn).sock[sockindex as usize], - -(1 as i32), - -(1 as i32), - 10000 as timediff_t, - ) - }; - if what > 0 as i32 { - /* Something to read, let's do it and hope that it is the close - notify alert from the server */ - unsafe { - ERR_clear_error(); - nread = SSL_read( - (*backend).handle, - buf.as_mut_ptr() as *mut libc::c_void, - buffsize, - ) as ssize_t; - err = SSL_get_error((*backend).handle, nread as i32); - } - match err { - 0 | 6 => { - /* This is the expected response. There was no data but only - the close notify alert */ - done = 1 as i32 != 0; - } - 2 => unsafe { - Curl_infof( - data, - b"SSL_ERROR_WANT_READ\0" as *const u8 as *const libc::c_char, - ); - }, - 3 => { - /* SSL wants a write. Really odd. Let's bail out. */ - unsafe { - Curl_infof( - data, - b"SSL_ERROR_WANT_WRITE\0" as *const u8 as *const libc::c_char, - ); - } - done = 1 as i32 != 0; - } - _ => { - /* openssl/ssl.h says "look at error stack/return value/errno" */ - unsafe { - sslerror = ERR_get_error(); - Curl_failf( - data, - b"OpenSSL SSL_read on shutdown: %s, errno %d\0" as *const u8 - as *const libc::c_char, - if sslerror != 0 { - ossl_strerror( - sslerror, - buf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ) as *const libc::c_char - } else { - SSL_ERROR_to_str(err) - }, - *__errno_location(), - ); - } - done = 1 as i32 != 0; - } - } - } else if 0 as i32 == what { - /* timeout */ - unsafe { - Curl_failf( - data, - b"SSL shutdown timeout\0" as *const u8 as *const libc::c_char, - ); - } - done = 1 as i32 != 0; - } else { - /* anything that gets here is fatally bad */ - unsafe { - Curl_failf( - data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, - *__errno_location(), - ); - } - retval = -(1 as i32); - done = 1 as i32 != 0; - } - } /* while()-loop for the select() */ - if unsafe { ((*data).set).verbose() != 0 } { - if cfg!(HAVE_SSL_GET_SHUTDOWN) { - unsafe { - match SSL_get_shutdown((*backend).handle) { - 1 => { - Curl_infof( - data, - b"SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\0" as *const u8 - as *const libc::c_char, - ); - } - 2 => { - Curl_infof( - data, - b"SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\0" as *const u8 - as *const libc::c_char, - ); - } - 3 => { - Curl_infof( + } + break 'fail; + } + /* Set Certificate Verification chain */ + if !ca.is_null() { + while sk_X509_num(ca) != 0 { + /* + * Note that sk_X509_pop() is used below to make sure the cert is + * removed from the stack properly before getting passed to + * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously + * we used sk_X509_value() instead, but then we'd clean it in the + * subsequent sk_X509_pop_free() call. + */ + let mut x: *mut X509 = sk_X509_pop(ca); + if unsafe { SSL_CTX_add_client_CA(ctx, x) } == 0 { + unsafe { + X509_free(x); + Curl_failf( + data, + b"cannot add certificate to client CA list\0" as *const u8 + as *const libc::c_char, + ); + } + break 'fail; + } + if unsafe { + SSL_CTX_ctrl( + ctx, + 14 as i32, + 0 as i64, + x as *mut libc::c_char as *mut libc::c_void, + ) + } == 0 + { + unsafe { + X509_free(x); + Curl_failf( + data, + b"cannot add certificate to certificate chain\0" + as *const u8 + as *const libc::c_char, + ); + } + break 'fail; + } + } + break 'fail; + } + cert_done = 1 as i32; + } + unsafe { + EVP_PKEY_free(pri); + X509_free(x509); + + #[cfg(USE_AMISSL)] + sk_X509_pop_free( + ca, + Some(Curl_amiga_X509_free as unsafe extern "C" fn(*mut X509) -> ()), + ); + #[cfg(not(USE_AMISSL))] + sk_X509_pop_free(ca, Some(X509_free as unsafe extern "C" fn(*mut X509) -> ())); + if cert_done == 0 { + return 0 as i32; + } + } + } + _ => { + unsafe { + Curl_failf( + data, + b"not supported file type '%s' for certificate\0" as *const u8 + as *const libc::c_char, + cert_type, + ); + } + return 0 as i32; + } + } + if key_file.is_null() && key_blob.is_null() { + key_file = cert_file; + key_blob = cert_blob; + } else { + file_type = do_file_type(key_type); + } + let mut current_block_141: u64; + match file_type { + 1 => { + if cert_done != 0 { + current_block_141 = 14358540534591340610; + } else { + current_block_141 = 2766187242236248435; + } + } + 2 => { + current_block_141 = 2766187242236248435; + } + // DONE - 1011 + 42 => match () { + #[cfg(USE_OPENSSL_ENGINE)] + _ => { + /* XXXX still needs some work */ + let mut priv_key: *mut EVP_PKEY = 0 as *mut EVP_PKEY; + unsafe { + /* Implicitly use pkcs11 engine if none was provided and the + * key_file is a PKCS#11 URI */ + if ((*data).state.engine).is_null() { + if is_pkcs11_uri(key_file) { + if ossl_set_engine( + data, + b"pkcs11\0" as *const u8 as *const libc::c_char, + ) as u32 + != CURLE_OK as u32 + { + return 0 as i32; + } + } + } + if !((*data).state.engine).is_null() { + let mut ui_method: *mut UI_METHOD = UI_create_method( + b"curl user interface\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + if ui_method.is_null() { + Curl_failf( + data, + b"unable do create OpenSSL user-interface method\0" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); + UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); + UI_method_set_reader( + ui_method, + Some( + ssl_ui_reader + as unsafe extern "C" fn(*mut UI, *mut UI_STRING) -> i32, + ), + ); + UI_method_set_writer( + ui_method, + Some( + ssl_ui_writer + as unsafe extern "C" fn(*mut UI, *mut UI_STRING) -> i32, + ), + ); + /* the typecast below was added to please mingw32 */ + priv_key = ENGINE_load_private_key( + (*data).state.engine as *mut ENGINE, + key_file, + ui_method, + key_passwd as *mut libc::c_void, + ); + UI_destroy_method(ui_method); + if priv_key.is_null() { + Curl_failf( + data, + b"failed to load private key from crypto engine\0" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + if SSL_CTX_use_PrivateKey(ctx, priv_key) != 1 as i32 { + Curl_failf( + data, + b"unable to set private key\0" as *const u8 + as *const libc::c_char, + ); + EVP_PKEY_free(priv_key); /* we don't need the handle any more... */ + return 0 as i32; + } + EVP_PKEY_free(priv_key); + } else { + Curl_failf( data, - b"SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|SSL_RECEIVED__SHUTDOWN\0" - as *const u8 as *const libc::c_char, + b"crypto engine not set, can't load private key\0" as *const u8 + as *const libc::c_char, ); - } - _ => {} - } - } - } - } - unsafe { - SSL_free((*backend).handle); - (*backend).handle = 0 as *mut SSL; - } - } - return retval; -} - -extern "C" fn ossl_session_free(mut ptr: *mut libc::c_void) { - unsafe { - SSL_SESSION_free(ptr as *mut SSL_SESSION); /* free the ID */ - } -} - -/* - * This function is called when the 'data' struct is going away. Close - * down everything and free all resources! - */ -extern "C" fn ossl_close_all(mut data: *mut Curl_easy) { - unsafe { - #[cfg(USE_OPENSSL_ENGINE)] - if !((*data).state.engine).is_null() { - ENGINE_finish((*data).state.engine as *mut ENGINE); - ENGINE_free((*data).state.engine as *mut ENGINE); - (*data).state.engine = 0 as *mut libc::c_void; - } - // TODO - 1560 - // #[cfg(all(not(HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED), HAVE_ERR_REMOVE_THREAD_STATE))] - } -} - -/* - * Match subjectAltName against the host name. This requires a conversion - * in CURL_DOES_CONVERSIONS builds. - */ -// TODO - 1579 开启 CURL_DOES_CONVERSIONS 选项 -// #[cfg(CURL_DOES_CONVERSIONS)] -#[cfg(not(CURL_DOES_CONVERSIONS))] -extern "C" fn subj_alt_hostcheck( - mut data: *mut Curl_easy, - mut match_pattern: *const libc::c_char, - mut hostname: *const libc::c_char, - mut dispname: *const libc::c_char, -) -> bool { - unsafe { - if Curl_cert_hostcheck(match_pattern, hostname) != 0 { - Curl_infof( - data, - b" subjectAltName: host \"%s\" matched cert's \"%s\"\0" as *const u8 - as *const libc::c_char, - dispname, - match_pattern, - ); - return 1 as i32 != 0; - } - return 0 as i32 != 0; - } -} - -/* Quote from RFC2818 section 3.1 "Server Identity" - - If a subjectAltName extension of type dNSName is present, that MUST - be used as the identity. Otherwise, the (most specific) Common Name - field in the Subject field of the certificate MUST be used. Although - the use of the Common Name is existing practice, it is deprecated and - Certification Authorities are encouraged to use the dNSName instead. - - Matching is performed using the matching rules specified by - [RFC2459]. If more than one identity of a given type is present in - the certificate (e.g., more than one dNSName name, a match in any one - of the set is considered acceptable.) Names may contain the wildcard - character * which is considered to match any single domain name - component or component fragment. E.g., *.a.com matches foo.a.com but - not bar.foo.a.com. f*.com matches foo.com but not bar.com. - - In some cases, the URI is specified as an IP address rather than a - hostname. In this case, the iPAddress subjectAltName must be present - in the certificate and must exactly match the IP in the URI. - -*/ -extern "C" fn verifyhost( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut server_cert: *mut X509, -) -> CURLcode { - let mut matched: bool = 0 as i32 != 0; - let mut target: i32 = 2 as i32; /* target type, GEN_DNS or GEN_IPADD */ - let mut addrlen: size_t = 0 as size_t; - let mut altnames: *mut stack_st_GENERAL_NAME = 0 as *mut stack_st_GENERAL_NAME; - #[cfg(ENABLE_IPV6)] - let mut addr: in6_addr = in6_addr { - __in6_u: C2RustUnnamed_8 { - __u6_addr8: [0; 16], - }, - }; - #[cfg(not(ENABLE_IPV6))] - let mut addr: in_addr = in_addr { s_addr: 0 }; - // TODO - 1650 - // #[cfg(not(ENABLE_IPV6))] - let mut result: CURLcode = CURLE_OK; - let mut dNSName: bool = 0 as i32 != 0; /* if a dNSName field exists in the cert */ - let mut iPAddress: bool = 0 as i32 != 0; /* if a iPAddress field exists in the cert */ - #[cfg(not(CURL_DISABLE_PROXY))] - let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).http_proxy.host.name } - } else { - unsafe { (*conn).host.name } - }; - #[cfg(CURL_DISABLE_PROXY)] - let hostname: *const libc::c_char = unsafe { (*conn).host.name }; - #[cfg(not(CURL_DISABLE_PROXY))] - let dispname: *const libc::c_char = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).http_proxy.host.dispname } - } else { - unsafe { (*conn).host.dispname } - }; - #[cfg(CURL_DISABLE_PROXY)] - let dispname: *const libc::c_char = unsafe { (*conn).host.dispname }; - // DONE - 1661 - #[cfg(ENABLE_IPV6)] - if unsafe { - ((*conn).bits).ipv6_ip() as i32 != 0 - && inet_pton( - 10 as i32, - hostname, - &mut addr as *mut in6_addr as *mut libc::c_void, - ) != 0 - } { - target = 7 as i32; - addrlen = ::std::mem::size_of::() as u64; - } else if unsafe { - inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in6_addr as *mut libc::c_void, - ) - } != 0 - { - target = 7 as i32; - addrlen = ::std::mem::size_of::() as u64; - } - #[cfg(not(ENABLE_IPV6))] - if unsafe { - inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in_addr as *mut libc::c_void, - ) - } != 0 - { - target = 7 as i32; - addrlen = ::std::mem::size_of::() as u64; - } - /* get a "list" of alternative names */ - altnames = unsafe { X509_get_ext_d2i(server_cert, 85 as i32, 0 as *mut i32, 0 as *mut i32) } - as *mut stack_st_GENERAL_NAME; - if !altnames.is_null() { - unsafe { - // TODO 待确认 - #[cfg(OPENSSL_IS_BORINGSSL)] - let mut numalts: ibc::c_int = 0; - #[cfg(OPENSSL_IS_BORINGSSL)] - let mut i: ibc::c_int = 0; - #[cfg(not(OPENSSL_IS_BORINGSSL))] - let mut numalts: i32 = 0; - #[cfg(not(OPENSSL_IS_BORINGSSL))] - let mut i: i32 = 0; - let mut dnsmatched: bool = 0 as i32 != 0; - let mut ipmatched: bool = 0 as i32 != 0; - /* get amount of alternatives, RFC2459 claims there MUST be at least - one, but we don't depend on it... */ - numalts = sk_GENERAL_NAME_num(altnames); - /* loop through all alternatives - until a dnsmatch */ - i = 0 as i32; - while i < numalts && !dnsmatched { - /* get a handle to alternative name number i */ - let mut check: *const GENERAL_NAME = sk_GENERAL_NAME_value(altnames, i); - if (*check).type_0 == 2 as i32 { - dNSName = 1 as i32 != 0; - } else if (*check).type_0 == 7 as i32 { - iPAddress = 1 as i32 != 0; - } - /* only check alternatives of the same type the target is */ - if (*check).type_0 == target { - /* get data and length */ - let mut altptr: *const libc::c_char = - ASN1_STRING_get0_data((*check).d.ia5) as *mut libc::c_char; - let mut altlen: size_t = ASN1_STRING_length((*check).d.ia5) as size_t; - match target { - 2 => { - /* name/pattern comparison */ - /* The OpenSSL man page explicitly says: "In general it cannot be - assumed that the data returned by ASN1_STRING_data() is null - terminated or does not contain embedded nulls." But also that - "The actual format of the data will depend on the actual string - type itself: for example for an IA5String the data will be ASCII" - - It has been however verified that in 0.9.6 and 0.9.7, IA5String - is always null-terminated. - */ - if altlen == strlen(altptr) - && subj_alt_hostcheck(data, altptr, hostname, dispname) as i32 != 0 - { - /* if this isn't true, there was an embedded zero in the name - string and we cannot match it. */ - dnsmatched = 1 as i32 != 0; - } - } - 7 => { - /* IP address comparison */ - #[cfg(ENABLE_IPV6)] - let ENABLE_IPV6_a = memcmp( - altptr as *const libc::c_void, - &mut addr as *mut in6_addr as *const libc::c_void, - altlen, - ) == 0; - #[cfg(not(ENABLE_IPV6))] - let ENABLE_IPV6_a = memcmp( - altptr as *const libc::c_void, - &mut addr as *mut in_addr as *const libc::c_void, - altlen, - ) == 0; - /* compare alternative IP address if the data chunk is the same size - our server IP address is */ - if altlen == addrlen && ENABLE_IPV6_a { - ipmatched = 1 as i32 != 0; - Curl_infof( - data, - b" subjectAltName: host \"%s\" matched cert's IP address!\0" - as *const u8 - as *const libc::c_char, - dispname, - ); - } - } - _ => {} - } - } - i += 1; - } - GENERAL_NAMES_free(altnames); - if dnsmatched as i32 != 0 || ipmatched as i32 != 0 { - matched = 1 as i32 != 0; - } - } - } - /* an alternative name matched */ - if !matched { - if dNSName as i32 != 0 || iPAddress as i32 != 0 { - unsafe { - Curl_infof( - data, - b" subjectAltName does not match %s\0" as *const u8 as *const libc::c_char, - dispname, - ); - Curl_failf( - data, - b"SSL: no alternative certificate subject name matches target host name '%s'\0" - as *const u8 as *const libc::c_char, - dispname, - ); - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else { - /* we have to look to the last occurrence of a commonName in the - distinguished one to get the most significant one. */ - let mut j: i32 = 0; - let mut i_0: i32 = -(1 as i32); - /* The following is done because of a bug in 0.9.6b */ - let mut nulstr: *mut u8 = b"\0" as *const u8 as *const libc::c_char as *mut u8; - let mut peer_CN: *mut u8 = nulstr; - let mut name: *mut X509_NAME = unsafe { X509_get_subject_name(server_cert) }; - if !name.is_null() { - loop { - j = unsafe { X509_NAME_get_index_by_NID(name, 13 as i32, i_0) }; - if !(j >= 0 as i32) { - break; - } - i_0 = j; - } - } - /* we have the name entry and we will now convert this to a string - that we can use for comparison. Doing this we support BMPstring, - UTF8, etc. */ - - if i_0 >= 0 as i32 { - let mut tmp: *mut ASN1_STRING = - unsafe { X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i_0)) }; - if !tmp.is_null() { - unsafe { - /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input - is already UTF-8 encoded. We check for this case and copy the raw - string manually to avoid the problem. This code can be made - conditional in the future when OpenSSL has been fixed. */ - if ASN1_STRING_type(tmp) == 12 as i32 { - j = ASN1_STRING_length(tmp); - if j >= 0 as i32 { - peer_CN = CRYPTO_malloc( - (j + 1 as i32) as size_t, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 1786 as i32, - ) as *mut u8; - if !peer_CN.is_null() { - memcpy( - peer_CN as *mut libc::c_void, - ASN1_STRING_get0_data(tmp) as *const libc::c_void, - j as u64, - ); - *peer_CN.offset(j as isize) = '\0' as i32 as u8; - } - } - } else { - /* not a UTF8 name */ - j = ASN1_STRING_to_UTF8(&mut peer_CN, tmp); - } - if !peer_CN.is_null() - && curlx_uztosi(strlen(peer_CN as *mut libc::c_char)) != j - { - /* there was a terminating zero before the end of string, this - cannot match and we return failure! */ - Curl_failf( - data, - b"SSL: illegal cert name field\0" as *const u8 - as *const libc::c_char, - ); - result = CURLE_PEER_FAILED_VERIFICATION; - } - } - } - } - if peer_CN == nulstr { - peer_CN = 0 as *mut u8; - } else { - /* convert peer_CN from UTF8 */ - let mut rc: CURLcode = CURLE_OK as CURLcode; - /* Curl_convert_from_utf8 calls failf if unsuccessful */ - if rc as u64 != 0 { - unsafe { - CRYPTO_free( - peer_CN as *mut libc::c_void, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 1813 as i32, - ); - } - return rc; - } - } - if !(result as u64 != 0) { - /* error already detected, pass through */ - if peer_CN.is_null() { - unsafe { - Curl_failf( - data, - b"SSL: unable to obtain common name from peer certificate\0" - as *const u8 as *const libc::c_char, - ); - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else if unsafe { Curl_cert_hostcheck(peer_CN as *const libc::c_char, hostname) } - == 0 - { - unsafe { - Curl_failf( - data, - b"SSL: certificate subject name '%s' does not match target host name '%s'\0" - as *const u8 as *const libc::c_char, - peer_CN, - dispname, - ); - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else { - unsafe { - Curl_infof( - data, - b" common name: %s (matched)\0" as *const u8 as *const libc::c_char, - peer_CN, - ); - } - } - } - if !peer_CN.is_null() { - unsafe { - CRYPTO_free( - peer_CN as *mut libc::c_void, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 1835 as i32, - ); - } - } - } - } - return result; -} - -#[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP)))] -extern "C" fn verifystatus( - mut data: *mut Curl_easy, - mut connssl: *mut ssl_connect_data, -) -> CURLcode { - let mut current_block: u64; - let mut i: i32 = 0; - let mut ocsp_status: i32 = 0; - let mut status: *mut u8 = 0 as *mut u8; - let mut p: *const u8 = 0 as *const u8; - let mut result: CURLcode = CURLE_OK; - let mut rsp: *mut OCSP_RESPONSE = 0 as *mut OCSP_RESPONSE; - let mut br: *mut OCSP_BASICRESP = 0 as *mut OCSP_BASICRESP; - let mut st: *mut X509_STORE = 0 as *mut X509_STORE; - let mut ch: *mut stack_st_X509 = 0 as *mut stack_st_X509; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - let mut cert: *mut X509 = 0 as *mut X509; - let mut id: *mut OCSP_CERTID = 0 as *mut OCSP_CERTID; - let mut cert_status: i32 = 0; - let mut crl_reason: i32 = 0; - let mut rev: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; - let mut thisupd: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; - let mut nextupd: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; - let mut ret: i32 = 0; - let mut len: i64 = unsafe { - SSL_ctrl( - (*backend).handle, - 70 as i32, - 0 as i64, - &mut status as *mut *mut u8 as *mut libc::c_void, - ) - }; - 'end: loop { - if status.is_null() { - unsafe { - Curl_failf( - data, - b"No OCSP response received\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - p = status; - rsp = unsafe { d2i_OCSP_RESPONSE(0 as *mut *mut OCSP_RESPONSE, &mut p, len) }; - if rsp.is_null() { - unsafe { - Curl_failf( - data, - b"Invalid OCSP response\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - ocsp_status = unsafe { OCSP_response_status(rsp) }; - if ocsp_status != 0 as i32 { - unsafe { - Curl_failf( - data, - b"Invalid OCSP response status: %s (%d)\0" as *const u8 as *const libc::c_char, - OCSP_response_status_str(ocsp_status as i64), - ocsp_status, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - br = unsafe { OCSP_response_get1_basic(rsp) }; - if br.is_null() { - unsafe { - Curl_failf( - data, - b"Invalid OCSP response\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - unsafe { - ch = SSL_get_peer_cert_chain((*backend).handle); - st = SSL_CTX_get_cert_store((*backend).ctx); - } - /* The authorized responder cert in the OCSP response MUST be signed by the - peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert, - no problem, but if it's an intermediate cert OpenSSL has a bug where it - expects this issuer to be present in the chain embedded in the OCSP - response. So we add it if necessary. */ - - /* First make sure the peer cert chain includes both a peer and an issuer, - and the OCSP response contains a responder cert. */ - // TODO - 1894 这里有一段跟OPENSSL_VERSION_NUMBER相关的条件编译 - if cfg!(any( - OPENSSL_VERSION_NUMBER_LT_0X1000201FL, - all( - LIBRESSL_VERSION_NUMBER, - LIBRESSL_VERSION_NUMBER_LT_0X2040200FL - ) - )) { - // TODO - } - if unsafe { OCSP_basic_verify(br, ch, st, 0 as u64) <= 0 as i32 } { - unsafe { - Curl_failf( - data, - b"OCSP response verification failed\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - cert = unsafe { SSL_get_peer_certificate((*backend).handle) }; - if cert.is_null() { - unsafe { - Curl_failf( - data, - b"Error getting peer certificate\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - /* Find issuer of responder cert and add it to the OCSP response chain */ - i = 0 as i32; - while i < sk_X509_num(ch) { - let mut issuer: *mut X509 = sk_X509_value(ch, i); - if unsafe { X509_check_issued(issuer, cert) } == 0 as i32 { - id = unsafe { OCSP_cert_to_id(EVP_sha1(), cert, issuer) }; - break; - } else { - i += 1; - } - } - unsafe { - X509_free(cert); - } - if id.is_null() { - unsafe { - Curl_failf( - data, - b"Error computing OCSP ID\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - /* Find the single OCSP response corresponding to the certificate ID */ - unsafe { - ret = OCSP_resp_find_status( - br, - id, - &mut cert_status, - &mut crl_reason, - &mut rev, - &mut thisupd, - &mut nextupd, - ); - OCSP_CERTID_free(id); - } - if ret != 1 as i32 { - unsafe { - Curl_failf( - data, - b"Could not find certificate ID in OCSP response\0" as *const u8 - as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - /* Validate the corresponding single OCSP response */ - unsafe { - if OCSP_check_validity(thisupd, nextupd, 300 as i64, -(1 as i64)) == 0 { - Curl_failf( - data, - b"OCSP response has expired\0" as *const u8 as *const libc::c_char, - ); - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - Curl_infof( - data, - b"SSL certificate status: %s (%d)\0" as *const u8 as *const libc::c_char, - OCSP_cert_status_str(cert_status as i64), - cert_status, - ); - } - let mut current_block_63: u64; - match cert_status { - 0 => { - current_block_63 = 13484060386966298149; - } - 1 => { - result = CURLE_SSL_INVALIDCERTSTATUS; - unsafe { - Curl_failf( - data, - b"SSL certificate revocation reason: %s (%d)\0" as *const u8 - as *const libc::c_char, - OCSP_crl_reason_str(crl_reason as i64), - crl_reason, - ); - } - current_block_63 = 11531555616992456840; - break 'end; - } - 2 | _ => { - current_block_63 = 11531555616992456840; - } - } - match current_block_63 { - 11531555616992456840 => { - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - _ => {} - } - break 'end; - } - if !br.is_null() { - unsafe { - OCSP_BASICRESP_free(br); - } - } - unsafe { - OCSP_RESPONSE_free(rsp); - } - return result; -} - -#[cfg(SSL_CTRL_SET_MSG_CALLBACK)] -extern "C" fn ssl_msg_type(mut ssl_ver: i32, mut msg: i32) -> *const libc::c_char { - if ssl_ver == 0x3 as i32 { - match msg { - 0 => return b"Hello request\0" as *const u8 as *const libc::c_char, - 1 => return b"Client hello\0" as *const u8 as *const libc::c_char, - 2 => return b"Server hello\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_NEWSESSION_TICKET)] - 4 => return b"Newsession Ticket\0" as *const u8 as *const libc::c_char, - 11 => return b"Certificate\0" as *const u8 as *const libc::c_char, - 12 => return b"Server key exchange\0" as *const u8 as *const libc::c_char, - 16 => return b"Client key exchange\0" as *const u8 as *const libc::c_char, - 13 => return b"Request CERT\0" as *const u8 as *const libc::c_char, - 14 => return b"Server finished\0" as *const u8 as *const libc::c_char, - 15 => return b"CERT verify\0" as *const u8 as *const libc::c_char, - 20 => return b"Finished\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_CERTIFICATE_STATUS)] - 22 => return b"Certificate Status\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_ENCRYPTED_EXTENSIONS)] - 8 => return b"Encrypted Extensions\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_SUPPLEMENTAL_DATA)] - 23 => return b"Supplemental data\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_END_OF_EARLY_DATA)] - 5 => return b"End of early data\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_KEY_UPDATE)] - 24 => return b"Key update\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_NEXT_PROTO)] - 67 => return b"Next protocol\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_MESSAGE_HASH)] - 254 => return b"Message hash\0" as *const u8 as *const libc::c_char, - _ => {} - } - } - return b"Unknown\0" as *const u8 as *const libc::c_char; -} - -#[cfg(SSL_CTRL_SET_MSG_CALLBACK)] -extern "C" fn tls_rt_type(mut type_0: i32) -> *const libc::c_char { - match type_0 { - #[cfg(SSL3_RT_HEADER)] - 256 => return b"TLS header\0" as *const u8 as *const libc::c_char, - 20 => return b"TLS change cipher\0" as *const u8 as *const libc::c_char, - 21 => return b"TLS alert\0" as *const u8 as *const libc::c_char, - 22 => return b"TLS handshake\0" as *const u8 as *const libc::c_char, - 23 => return b"TLS app data\0" as *const u8 as *const libc::c_char, - _ => return b"TLS Unknown\0" as *const u8 as *const libc::c_char, - }; -} - -/* - * Our callback from the SSL/TLS layers. - */ -#[cfg(SSL_CTRL_SET_MSG_CALLBACK)] -extern "C" fn ossl_trace( - mut direction: i32, - mut ssl_ver: i32, - mut content_type: i32, - mut buf: *const libc::c_void, - mut len: size_t, - mut ssl: *mut SSL, - mut userp: *mut libc::c_void, -) { - let mut unknown: [libc::c_char; 32] = [0; 32]; - let mut verstr: *const libc::c_char = 0 as *const libc::c_char; - let mut conn: *mut connectdata = userp as *mut connectdata; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(0 as isize) as *mut ssl_connect_data }; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - let mut data: *mut Curl_easy = unsafe { (*backend).logger }; - if conn.is_null() - || data.is_null() - || unsafe { ((*data).set.fdebug).is_none() } - || direction != 0 as i32 && direction != 1 as i32 - { - return; - } - match ssl_ver { - #[cfg(SSL2_VERSION)] - 2 => { - verstr = b"SSLv2\0" as *const u8 as *const libc::c_char; - } - #[cfg(SSL3_VERSION)] - 768 => { - verstr = b"SSLv3\0" as *const u8 as *const libc::c_char; - } - 769 => { - verstr = b"TLSv1.0\0" as *const u8 as *const libc::c_char; - } - #[cfg(TLS1_1_VERSION)] - 770 => { - verstr = b"TLSv1.1\0" as *const u8 as *const libc::c_char; - } - #[cfg(TLS1_2_VERSION)] - 771 => { - verstr = b"TLSv1.2\0" as *const u8 as *const libc::c_char; - } - #[cfg(TLS1_3_VERSION)] - 772 => { - verstr = b"TLSv1.3\0" as *const u8 as *const libc::c_char; - } - 0 => {} - _ => { - unsafe { - curl_msnprintf( - unknown.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 32]>() as u64, - b"(%x)\0" as *const u8 as *const libc::c_char, - ssl_ver, - ); - } - verstr = unknown.as_mut_ptr(); - } - } - /* Log progress for interesting records only (like Handshake or Alert), skip - * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0). - * For TLS 1.3, skip notification of the decrypted inner Content-Type. - */ - // DONE - 2168 - #[cfg(SSL3_RT_INNER_CONTENT_TYPE)] - let SSL3_RT_INNER_CONTENT_TYPE_flag = content_type != 0x101; - #[cfg(not(SSL3_RT_INNER_CONTENT_TYPE))] - let SSL3_RT_INNER_CONTENT_TYPE_flag = true; - if ssl_ver != 0 && SSL3_RT_INNER_CONTENT_TYPE_flag { - let mut msg_name: *const libc::c_char = 0 as *const libc::c_char; - let mut tls_rt_name: *const libc::c_char = 0 as *const libc::c_char; - let mut ssl_buf: [libc::c_char; 1024] = [0; 1024]; - let mut msg_type: i32 = 0; - let mut txt_len: i32 = 0; - /* the info given when the version is zero is not that useful for us */ - - ssl_ver >>= 8 as i32; /* check the upper 8 bits only below */ - /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL - * always pass-up content-type as 0. But the interesting message-type - * is at 'buf[0]'. - */ - if ssl_ver == 0x3 as i32 && content_type != 0 { - tls_rt_name = tls_rt_type(content_type); - } else { - tls_rt_name = b"\0" as *const u8 as *const libc::c_char; - } - if content_type == 20 as i32 { - msg_type = unsafe { *(buf as *mut libc::c_char) } as i32; - msg_name = b"Change cipher spec\0" as *const u8 as *const libc::c_char; - } else if content_type == 21 as i32 { - msg_type = unsafe { - ((*(buf as *mut libc::c_char).offset(0 as isize) as i32) << 8 as i32) - + *(buf as *mut libc::c_char).offset(1 as isize) as i32 - }; - msg_name = unsafe { SSL_alert_desc_string_long(msg_type) }; - } else { - msg_type = unsafe { *(buf as *mut libc::c_char) } as i32; - msg_name = ssl_msg_type(ssl_ver, msg_type); - } - txt_len = unsafe { - curl_msnprintf( - ssl_buf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 1024]>() as u64, - b"%s (%s), %s, %s (%d):\n\0" as *const u8 as *const libc::c_char, - verstr, - if direction != 0 { - b"OUT\0" as *const u8 as *const libc::c_char - } else { - b"IN\0" as *const u8 as *const libc::c_char - }, - tls_rt_name, - msg_name, - msg_type, - ) - }; - if 0 as i32 <= txt_len - && (txt_len as u64) < ::std::mem::size_of::<[libc::c_char; 1024]>() as u64 - { - unsafe { - Curl_debug(data, CURLINFO_TEXT, ssl_buf.as_mut_ptr(), txt_len as size_t); - } - } - } - unsafe { - Curl_debug( - data, - (if direction == 1 as i32 { - CURLINFO_SSL_DATA_OUT as i32 - } else { - CURLINFO_SSL_DATA_IN as i32 - }) as curl_infotype, - buf as *mut libc::c_char, - len, - ); - } -} - -#[cfg(all(USE_OPENSSL, HAS_NPN))] -extern "C" fn select_next_protocol( - mut out: *mut *mut u8, - mut outlen: *mut u8, - mut in_0: *const u8, - mut inlen: u32, - mut key: *const libc::c_char, - mut keylen: u32, -) -> i32 { - let mut i: u32 = 0; - i = 0 as u32; - while i.wrapping_add(keylen) <= inlen { - if unsafe { - memcmp( - &*in_0.offset(i.wrapping_add(1 as u32) as isize) as *const u8 - as *const libc::c_void, - key as *const libc::c_void, - keylen as u64, - ) - } == 0 as i32 - { - unsafe { - *out = &*in_0.offset(i.wrapping_add(1 as u32) as isize) as *const u8 as *mut u8; - *outlen = *in_0.offset(i as isize); - } - return 0 as i32; - } - i = unsafe { i.wrapping_add((*in_0.offset(i as isize) as i32 + 1 as i32) as u32) }; - } - return -(1 as i32); -} - -#[cfg(all(USE_OPENSSL, HAS_NPN))] -extern "C" fn select_next_proto_cb( - mut ssl: *mut SSL, - mut out: *mut *mut u8, - mut outlen: *mut u8, - mut in_0: *const u8, - mut inlen: u32, - mut arg: *mut libc::c_void, -) -> i32 { - unsafe { - let mut data: *mut Curl_easy = arg as *mut Curl_easy; - let mut conn: *mut connectdata = (*data).conn; - #[cfg(USE_HTTP2)] - if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 - && select_next_protocol( - out, - outlen, - in_0, - inlen, - b"h2\0" as *const u8 as *const libc::c_char, - 2 as u32, - ) == 0 - { - Curl_infof( - data, - b"NPN, negotiated HTTP2 (%s)\0" as *const u8 as *const libc::c_char, - b"h2\0" as *const u8 as *const libc::c_char, - ); - (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; - return 0 as i32; - } - if select_next_protocol( - out, - outlen, - in_0, - inlen, - b"http/1.1\0" as *const u8 as *const libc::c_char, - 8 as u32, - ) == 0 - { - Curl_infof( - data, - b"NPN, negotiated HTTP1.1\0" as *const u8 as *const libc::c_char, - ); - (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; - return 0 as i32; - } - Curl_infof( - data, - b"NPN, no overlap, use HTTP1.1\0" as *const u8 as *const libc::c_char, - ); - *out = b"http/1.1\0" as *const u8 as *const libc::c_char as *mut u8; - *outlen = 8 as u8; - (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; - return 0 as i32; - } -} -// TODO -// USE_OPENSSL以及与OPENSSL_VERSION_NUMBER相关的条件编译 -#[cfg(USE_OPENSSL)] -extern "C" fn set_ssl_version_min_max( - mut ctx: *mut SSL_CTX, - mut conn: *mut connectdata, -) -> CURLcode { - #[cfg(not(CURL_DISABLE_PROXY))] - let mut curl_ssl_version_min: i64 = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).proxy_ssl_config.version } - } else { - unsafe { (*conn).ssl_config.version } - }; - #[cfg(CURL_DISABLE_PROXY)] - let mut curl_ssl_version_min: i64 = unsafe { (*conn).ssl_config.version }; - - let mut curl_ssl_version_max: i64 = 0; - // TODO - 2307 - // #[cfg(any(OPENSSL_IS_BORINGSSL, LIBRESSL_VERSION_NUMBER))] - // TODO - 2307 - // #[cfg(any(OPENSSL_IS_BORINGSSL, LIBRESSL_VERSION_NUMBER))] - #[cfg(all(not(OPENSSL_IS_BORINGSSL), not(LIBRESSL_VERSION_NUMBER)))] - let mut ossl_ssl_version_min: i64 = 0 as i64; - #[cfg(all(not(OPENSSL_IS_BORINGSSL), not(LIBRESSL_VERSION_NUMBER)))] - let mut ossl_ssl_version_max: i64 = 0 as i64; - match curl_ssl_version_min { - 1 | 4 => { - ossl_ssl_version_min = 0x301 as i64; - } - 5 => { - ossl_ssl_version_min = 0x302 as i64; - } - 6 => { - ossl_ssl_version_min = 0x303 as i64; - } - #[cfg(TLS1_3_VERSION)] - 7 => { - ossl_ssl_version_min = 0x304 as i64; - } - _ => {} - } - /* CURL_SSLVERSION_DEFAULT means that no option was selected. - We don't want to pass 0 to SSL_CTX_set_min_proto_version as - it would enable all versions down to the lowest supported by - the library. - So we skip this, and stay with the library default - */ - if curl_ssl_version_min != CURL_SSLVERSION_DEFAULT as i64 { - if unsafe { - SSL_CTX_ctrl( - ctx, - 123 as i32, - ossl_ssl_version_min, - 0 as *mut libc::c_void, - ) - } == 0 - { - return CURLE_SSL_CONNECT_ERROR; - } - } - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_version_max = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype } as u32 - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).proxy_ssl_config.version_max } - } else { - unsafe { (*conn).ssl_config.version_max } - }; - /* ... then, TLS max version */ - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_version_max = unsafe { (*conn).ssl_config.version_max }; - - curl_ssl_version_max = SSL_CONN_CONFIG_version_max; - let mut current_block_15: u64; - /* convert curl max SSL version option to OpenSSL constant */ - match curl_ssl_version_max { - 262144 => { - ossl_ssl_version_max = 0x301 as i64; - current_block_15 = 18386322304582297246; - } - 327680 => { - ossl_ssl_version_max = 0x302 as i64; - current_block_15 = 18386322304582297246; - } - 393216 => { - ossl_ssl_version_max = 0x303 as i64; - current_block_15 = 18386322304582297246; - } - #[cfg(TLS1_3_VERSION)] - 458752 => { - ossl_ssl_version_max = 0x304 as i64; - current_block_15 = 18386322304582297246; - } - // TODO 这里翻译的很奇怪,感觉没有必要这样 - 0 => { - current_block_15 = 9181747712041856033; - } - 65536 | _ => { - current_block_15 = 9181747712041856033; - } - } - match current_block_15 { - 9181747712041856033 => { - /* SSL_CTX_set_max_proto_version states that: - setting the maximum to 0 will enable - protocol versions up to the highest version - supported by the library */ - ossl_ssl_version_max = 0 as i64; - } - _ => {} - } - if unsafe { - SSL_CTX_ctrl( - ctx, - 124 as i32, - ossl_ssl_version_max, - 0 as *mut libc::c_void, - ) - } == 0 - { - return CURLE_SSL_CONNECT_ERROR; - } - return CURLE_OK; -} - -/* The "new session" callback must return zero if the session can be removed - * or non-zero if the session has been put into the session cache. + + return 0 as i32; + } + current_block_141 = 14358540534591340610; + } + } + #[cfg(not(USE_OPENSSL_ENGINE))] + _ => unsafe { + Curl_failf( + data, + b"file type ENG for private key not supported" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + }, + }, + 43 => { + if cert_done == 0 { + unsafe { + Curl_failf( + data, + b"file type P12 for private key not supported\0" as *const u8 + as *const libc::c_char, + ); + } + return 0 as i32; + } + current_block_141 = 14358540534591340610; + } + _ => { + unsafe { + Curl_failf( + data, + b"not supported file type for private key\0" as *const u8 + as *const libc::c_char, + ); + } + return 0 as i32; + } + } + match current_block_141 { + 2766187242236248435 => { + cert_use_result = if !key_blob.is_null() { + SSL_CTX_use_PrivateKey_blob(ctx, key_blob, file_type, key_passwd) + } else { + unsafe { SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) } + }; + if cert_use_result != 1 as i32 { + unsafe { + Curl_failf( + data, + b"unable to set private key file: '%s' type %s\0" as *const u8 + as *const libc::c_char, + if !key_file.is_null() { + key_file as *const libc::c_char + } else { + b"(memory blob)\0" as *const u8 as *const libc::c_char + }, + if !key_type.is_null() { + key_type + } else { + b"PEM\0" as *const u8 as *const libc::c_char + }, + ); + } + return 0 as i32; + } + } + _ => {} + } + unsafe { + ssl = SSL_new(ctx); + if ssl.is_null() { + Curl_failf( + data, + b"unable to create an SSL structure\0" as *const u8 as *const libc::c_char, + ); + return 0 as i32; + } + x509 = SSL_get_certificate(ssl); + } + /* This version was provided by Evan Jordan and is supposed to not + leak memory as the previous version: */ + if !x509.is_null() { + unsafe { + let mut pktmp: *mut EVP_PKEY = X509_get_pubkey(x509); + EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl)); + EVP_PKEY_free(pktmp); + } + } + #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL)))] + let mut priv_key_0: *mut EVP_PKEY = unsafe { SSL_get_privatekey(ssl) }; + + #[cfg(all( + not(OPENSSL_NO_RSA), + not(OPENSSL_IS_BORINGSSL), + not(HAVE_OPAQUE_EVP_PKEY) + ))] + // TODO 未开的情况下不是 = 0,是另一种情况 + let mut pktype: i32 = 0; + #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL), HAVE_OPAQUE_EVP_PKEY))] + let mut pktype: i32 = EVP_PKEY_id(priv_key_0); + // TODO - 不开HAVE_OPAQUE_EVP_PKEY选项 + // #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL), not(HAVE_OPAQUE_EVP_PKEY)))] + #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL)))] + if pktype == 6 as i32 { + let mut rsa: *mut RSA = unsafe { EVP_PKEY_get1_RSA(priv_key_0) }; + unsafe { + if RSA_flags(rsa) & 0x1 as i32 != 0 { + check_privkey = 0 as i32 != 0; + } + RSA_free(rsa); /* Decrement reference count */ + } + } + unsafe { + SSL_free(ssl); + } + /* If we are using DSA, we can copy the parameters from + * the private key */ + if check_privkey as i32 == 1 as i32 { + /* Now we know that a key and cert have been set against + * the SSL context */ + if unsafe { SSL_CTX_check_private_key(ctx) == 0 } { + unsafe { + Curl_failf( + data, + b"Private key does not match the certificate public key\0" as *const u8 + as *const libc::c_char, + ); + } + return 0 as i32; + } + } + } + return 1 as i32; + } + + /* returns non-zero on failure */ + extern "C" fn x509_name_oneline( + mut a: *mut X509_NAME, + mut buf: *mut libc::c_char, + mut size: size_t, + ) -> i32 { + let mut bio_out: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; + let mut biomem: *mut BUF_MEM = 0 as *mut BUF_MEM; + let mut rc: i32 = 0; + if bio_out.is_null() { + return 1 as i32; /* alloc failed! */ + } + rc = unsafe { X509_NAME_print_ex(bio_out, a, 0 as i32, ((3 as i32) << 16 as i32) as u64) }; + unsafe { + BIO_ctrl( + bio_out, + 115 as i32, + 0 as i64, + &mut biomem as *mut *mut BUF_MEM as *mut libc::c_char as *mut libc::c_void, + ); + if (*biomem).length < size { + size = (*biomem).length; + } else { + size = size.wrapping_sub(1); /* don't overwrite the buffer end */ + } + memcpy( + buf as *mut libc::c_void, + (*biomem).data as *const libc::c_void, + size, + ); + *buf.offset(size as isize) = 0 as libc::c_char; + BIO_free(bio_out); + } + return (rc == 0) as i32; + } + + /** + * Global SSL init + * + * @retval 0 error initializing SSL + * @retval 1 SSL initialized successfully + */ + extern "C" fn ossl_init() -> i32 { + #[cfg(OPENSSL_INIT_ENGINE_ALL_BUILTIN)] + let flag_1 = 0x200 as i64 | 0x400 as i64 | 0x1000 as i64 | 0x2000 as i64 | 0x4000 as i64; + #[cfg(not(OPENSSL_INIT_ENGINE_ALL_BUILTIN))] + let flag_1 = 0x0000 as i64; + #[cfg(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG)] + let flag_2 = 0x80 as i64; + #[cfg(not(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG))] + let flag_2 = 0x40 as i64; + let flags: uint64_t = (flag_1 | flag_2 | 0 as i64) as uint64_t; + + unsafe { + OPENSSL_init_ssl(flags, 0 as *const OPENSSL_INIT_SETTINGS); + } + Curl_tls_keylog_open(); + /* Initialize the extra data indexes */ + if ossl_get_ssl_data_index() < 0 as i32 + || ossl_get_ssl_conn_index() < 0 as i32 + || ossl_get_ssl_sockindex_index() < 0 as i32 + || ossl_get_proxy_index() < 0 as i32 + { + return 0 as i32; + } + return 1 as i32; + } + + /* Global cleanup */ + extern "C" fn ossl_cleanup() { + Curl_tls_keylog_close(); + } + + /* + * This function is used to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ + extern "C" fn ossl_check_cxn(mut conn: *mut connectdata) -> i32 { + /* SSL_peek takes data out of the raw recv buffer without peeking so we use + recv MSG_PEEK instead. Bug #795 */ + #[cfg(MSG_PEEK)] + let mut buf: libc::c_char = 0; + #[cfg(MSG_PEEK)] + let mut nread: ssize_t = recv( + (*conn).sock[0 as usize], + &mut buf as *mut libc::c_char as *mut libc::c_void, + 1 as size_t, + MSG_PEEK as i32, + ); + #[cfg(MSG_PEEK)] + if nread == 0 as i64 { + return 0 as i32; /* connection has been closed */ + } + #[cfg(MSG_PEEK)] + if nread == 1 as i64 { + return 1 as i32; /* connection still in place */ + } else { + if nread == -(1 as i32) as i64 { + let mut err: i32 = *__errno_location(); + // 写法不对,rust中如何判断宏值的相等 + // TODO - 1276 + if err == 115 as i32 || err == 11 as i32 { + return 1 as i32; /* connection still in place */ + } + // DONE - 1282 + #[cfg(ECONNABORTED)] + let ECONNABORTED_flag = err == 103; + #[cfg(not(ECONNABORTED))] + let ECONNABORTED_flag = false; + #[cfg(ENETDOWN)] + let ENETDOWN_flag = err == 100; + #[cfg(not(ENETDOWN))] + let ENETDOWN_flag = false; + #[cfg(ENETRESET)] + let ENETRESET_flag = err == 102; + #[cfg(not(ENETRESET))] + let ENETRESET_flag = false; + #[cfg(ESHUTDOWN)] + let ESHUTDOWN_flag = err == 108; + #[cfg(not(ESHUTDOWN))] + let ESHUTDOWN_flag = false; + #[cfg(ETIMEDOUT)] + let ETIMEDOUT_flag = err == 110; + #[cfg(not(ETIMEDOUT))] + let ETIMEDOUT_flag = false; + if err == 104 as i32 + || ECONNABORTED_flag + || ENETDOWN_flag + || ENETRESET_flag + || ENETDOWN_flag + || ETIMEDOUT_flag + || err == 107 as i32 + { + return 0 as i32; /* connection has been closed */ + } + } + } + return -(1 as i32); /* connection status unknown */ + } + + /* Selects an OpenSSL crypto engine + */ + extern "C" fn ossl_set_engine( + mut data: *mut Curl_easy, + mut engine: *const libc::c_char, + ) -> CURLcode { + if cfg!(USE_OPENSSL_ENGINE) { + let mut e: *mut ENGINE = 0 as *mut ENGINE; + e = unsafe { ENGINE_by_id(engine) }; + if e.is_null() { + unsafe { + Curl_failf( + data, + b"SSL Engine '%s' not found\0" as *const u8 as *const libc::c_char, + engine, + ); + } + return CURLE_SSL_ENGINE_NOTFOUND; + } + unsafe { + if !((*data).state.engine).is_null() { + ENGINE_finish((*data).state.engine as *mut ENGINE); + ENGINE_free((*data).state.engine as *mut ENGINE); + (*data).state.engine = 0 as *mut libc::c_void; + } + if ENGINE_init(e) == 0 { + let mut buf: [libc::c_char; 256] = [0; 256]; + ENGINE_free(e); + Curl_failf( + data, + b"Failed to initialise SSL Engine '%s': %s\0" as *const u8 + as *const libc::c_char, + engine, + ossl_strerror( + ERR_get_error(), + buf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return CURLE_SSL_ENGINE_INITFAILED; + } + (*data).state.engine = e as *mut libc::c_void; + } + return CURLE_OK; + } else { + unsafe { + Curl_infof( + data, + b"SSL Engine not supported\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_SSL_ENGINE_NOTFOUND; + } + } + + /* Sets engine as default for all SSL operations + */ + extern "C" fn ossl_set_engine_default(mut data: *mut Curl_easy) -> CURLcode { + if cfg!(USE_OPENSSL_ENGINE) { + unsafe { + if !((*data).state.engine).is_null() { + if ENGINE_set_default((*data).state.engine as *mut ENGINE, 0xffff as i32 as u32) + > 0 as i32 + { + Curl_infof( + data, + b"set default crypto engine '%s'\0" as *const u8 as *const libc::c_char, + ENGINE_get_id((*data).state.engine as *const ENGINE), + ); + } else { + Curl_failf( + data, + b"set default crypto engine '%s' failed\0" as *const u8 + as *const libc::c_char, + ENGINE_get_id((*data).state.engine as *const ENGINE), + ); + return CURLE_SSL_ENGINE_SETFAILED; + } + } + } + } + return CURLE_OK; + } + + /* Return list of OpenSSL crypto engine names. + */ + extern "C" fn ossl_engines_list(mut data: *mut Curl_easy) -> *mut curl_slist { + let mut list: *mut curl_slist = 0 as *mut curl_slist; + if cfg!(USE_OPENSSL_ENGINE) { + let mut beg: *mut curl_slist = 0 as *mut curl_slist; + let mut e: *mut ENGINE = 0 as *mut ENGINE; + e = unsafe { ENGINE_get_first() }; + while !e.is_null() { + unsafe { + beg = curl_slist_append(list, ENGINE_get_id(e)); + if beg.is_null() { + curl_slist_free_all(list); + return 0 as *mut curl_slist; + } + } + list = beg; + e = unsafe { ENGINE_get_next(e) }; + } + } + return list; + } + extern "C" fn ossl_closeone( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut connssl: *mut ssl_connect_data, + ) { + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + if !((*backend).handle).is_null() { + let mut buf: [libc::c_char; 32] = [0; 32]; + (*(*conn).ssl[0 as usize].backend).logger = data; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + SSL_read( + (*backend).handle, + buf.as_mut_ptr() as *mut libc::c_void, + ::std::mem::size_of::<[libc::c_char; 32]>() as i32, + ); + SSL_shutdown((*backend).handle); + SSL_set_connect_state((*backend).handle); + SSL_free((*backend).handle); + (*backend).handle = 0 as *mut SSL; + } + if !((*backend).ctx).is_null() { + SSL_CTX_free((*backend).ctx); + (*backend).ctx = 0 as *mut SSL_CTX; + } + } + } + + /* + * This function is called when an SSL connection is closed. + */ + extern "C" fn ossl_close(mut data: *mut Curl_easy, mut conn: *mut connectdata, mut sockindex: i32) { + unsafe { + ossl_closeone( + data, + conn, + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize), + ); + #[cfg(not(CURL_DISABLE_PROXY))] + ossl_closeone( + data, + conn, + &mut *((*conn).proxy_ssl).as_mut_ptr().offset(sockindex as isize), + ); + } + } + + /* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ + extern "C" fn ossl_shutdown( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) -> i32 { + let mut retval: i32 = 0 as i32; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut buf: [libc::c_char; 256] = [0; 256]; /* We will use this for the OpenSSL error buffer, so it has + to be at least 256 bytes long. */ + let mut sslerror: u64 = 0; + let mut nread: ssize_t = 0; + let mut buffsize: i32 = 0; + let mut err: i32 = 0; + let mut done: bool = 0 as i32 != 0; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut loop_0: i32 = 10 as i32; + /* This has only been tested on the proftpd server, and the mod_tls code + sends a close notify alert without waiting for a close notify alert in + response. Thus we wait for a close notify alert from the server, but + we do not send one. Let's hope other servers do the same... */ + #[cfg(not(CURL_DISABLE_FTP))] + unsafe { + if (*data).set.ftp_ccc as u32 == CURLFTPSSL_CCC_ACTIVE as u32 { + SSL_shutdown((*backend).handle); + } + } + if unsafe { !((*backend).handle).is_null() } { + buffsize = ::std::mem::size_of::<[libc::c_char; 256]>() as i32; + while !done && { + let fresh5 = loop_0; + loop_0 = loop_0 - 1; + fresh5 != 0 + } { + let mut what: i32 = unsafe { + Curl_socket_check( + (*conn).sock[sockindex as usize], + -(1 as i32), + -(1 as i32), + 10000 as timediff_t, + ) + }; + if what > 0 as i32 { + /* Something to read, let's do it and hope that it is the close + notify alert from the server */ + unsafe { + ERR_clear_error(); + nread = SSL_read( + (*backend).handle, + buf.as_mut_ptr() as *mut libc::c_void, + buffsize, + ) as ssize_t; + err = SSL_get_error((*backend).handle, nread as i32); + } + match err { + 0 | 6 => { + /* This is the expected response. There was no data but only + the close notify alert */ + done = 1 as i32 != 0; + } + 2 => unsafe { + Curl_infof( + data, + b"SSL_ERROR_WANT_READ\0" as *const u8 as *const libc::c_char, + ); + }, + 3 => { + /* SSL wants a write. Really odd. Let's bail out. */ + unsafe { + Curl_infof( + data, + b"SSL_ERROR_WANT_WRITE\0" as *const u8 as *const libc::c_char, + ); + } + done = 1 as i32 != 0; + } + _ => { + /* openssl/ssl.h says "look at error stack/return value/errno" */ + unsafe { + sslerror = ERR_get_error(); + Curl_failf( + data, + b"OpenSSL SSL_read on shutdown: %s, errno %d\0" as *const u8 + as *const libc::c_char, + if sslerror != 0 { + ossl_strerror( + sslerror, + buf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ) as *const libc::c_char + } else { + SSL_ERROR_to_str(err) + }, + *__errno_location(), + ); + } + done = 1 as i32 != 0; + } + } + } else if 0 as i32 == what { + /* timeout */ + unsafe { + Curl_failf( + data, + b"SSL shutdown timeout\0" as *const u8 as *const libc::c_char, + ); + } + done = 1 as i32 != 0; + } else { + /* anything that gets here is fatally bad */ + unsafe { + Curl_failf( + data, + b"select/poll on SSL socket, errno: %d\0" as *const u8 + as *const libc::c_char, + *__errno_location(), + ); + } + retval = -(1 as i32); + done = 1 as i32 != 0; + } + } /* while()-loop for the select() */ + if unsafe { ((*data).set).verbose() != 0 } { + if cfg!(HAVE_SSL_GET_SHUTDOWN) { + unsafe { + match SSL_get_shutdown((*backend).handle) { + 1 => { + Curl_infof( + data, + b"SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\0" as *const u8 + as *const libc::c_char, + ); + } + 2 => { + Curl_infof( + data, + b"SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\0" as *const u8 + as *const libc::c_char, + ); + } + 3 => { + Curl_infof( + data, + b"SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|SSL_RECEIVED__SHUTDOWN\0" + as *const u8 as *const libc::c_char, + ); + } + _ => {} + } + } + } + } + unsafe { + SSL_free((*backend).handle); + (*backend).handle = 0 as *mut SSL; + } + } + return retval; + } + + extern "C" fn ossl_session_free(mut ptr: *mut libc::c_void) { + unsafe { + SSL_SESSION_free(ptr as *mut SSL_SESSION); /* free the ID */ + } + } + + /* + * This function is called when the 'data' struct is going away. Close + * down everything and free all resources! + */ + extern "C" fn ossl_close_all(mut data: *mut Curl_easy) { + unsafe { + #[cfg(USE_OPENSSL_ENGINE)] + if !((*data).state.engine).is_null() { + ENGINE_finish((*data).state.engine as *mut ENGINE); + ENGINE_free((*data).state.engine as *mut ENGINE); + (*data).state.engine = 0 as *mut libc::c_void; + } + // TODO - 1560 + // #[cfg(all(not(HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED), HAVE_ERR_REMOVE_THREAD_STATE))] + } + } + + /* + * Match subjectAltName against the host name. This requires a conversion + * in CURL_DOES_CONVERSIONS builds. + */ + // TODO - 1579 开启 CURL_DOES_CONVERSIONS 选项 + // #[cfg(CURL_DOES_CONVERSIONS)] + #[cfg(not(CURL_DOES_CONVERSIONS))] + extern "C" fn subj_alt_hostcheck( + mut data: *mut Curl_easy, + mut match_pattern: *const libc::c_char, + mut hostname: *const libc::c_char, + mut dispname: *const libc::c_char, + ) -> bool { + unsafe { + if Curl_cert_hostcheck(match_pattern, hostname) != 0 { + Curl_infof( + data, + b" subjectAltName: host \"%s\" matched cert's \"%s\"\0" as *const u8 + as *const libc::c_char, + dispname, + match_pattern, + ); + return 1 as i32 != 0; + } + return 0 as i32 != 0; + } + } + + /* Quote from RFC2818 section 3.1 "Server Identity" + + If a subjectAltName extension of type dNSName is present, that MUST + be used as the identity. Otherwise, the (most specific) Common Name + field in the Subject field of the certificate MUST be used. Although + the use of the Common Name is existing practice, it is deprecated and + Certification Authorities are encouraged to use the dNSName instead. + + Matching is performed using the matching rules specified by + [RFC2459]. If more than one identity of a given type is present in + the certificate (e.g., more than one dNSName name, a match in any one + of the set is considered acceptable.) Names may contain the wildcard + character * which is considered to match any single domain name + component or component fragment. E.g., *.a.com matches foo.a.com but + not bar.foo.a.com. f*.com matches foo.com but not bar.com. + + In some cases, the URI is specified as an IP address rather than a + hostname. In this case, the iPAddress subjectAltName must be present + in the certificate and must exactly match the IP in the URI. + */ -// TODO 这里有个与OPENSSL_VERSION_NUMBER相关的条件编译 -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_new_session_cb(mut ssl: *mut SSL, mut ssl_sessionid: *mut SSL_SESSION) -> i32 { - let mut res: i32 = 0 as i32; - let mut conn: *mut connectdata = 0 as *mut connectdata; - let mut data: *mut Curl_easy = 0 as *mut Curl_easy; - let mut sockindex: i32 = 0; - let mut sockindex_ptr: *mut curl_socket_t = 0 as *mut curl_socket_t; - let mut data_idx: i32 = ossl_get_ssl_data_index(); - let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); - let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); - let mut proxy_idx: i32 = ossl_get_proxy_index(); - let mut isproxy: bool = false; - if data_idx < 0 as i32 - || connectdata_idx < 0 as i32 - || sockindex_idx < 0 as i32 - || proxy_idx < 0 as i32 - { - return 0 as i32; - } - conn = unsafe { SSL_get_ex_data(ssl, connectdata_idx) as *mut connectdata }; - if conn.is_null() { - return 0 as i32; - } - data = unsafe { SSL_get_ex_data(ssl, data_idx) as *mut Curl_easy }; - /* The sockindex has been stored as a pointer to an array element */ - sockindex_ptr = unsafe { SSL_get_ex_data(ssl, sockindex_idx) as *mut curl_socket_t }; - sockindex = unsafe { sockindex_ptr.offset_from(((*conn).sock).as_mut_ptr()) as i32 }; - isproxy = if unsafe { !(SSL_get_ex_data(ssl, proxy_idx)).is_null() } { - 1 as i32 - } else { - 0 as i32 - } != 0; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } - } else { - unsafe { ((*data).set.ssl.primary).sessionid() as i32 } - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() }; - if SSL_SET_OPTION_primary_sessionid != 0 { - let mut incache: bool = false; - let mut old_ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - Curl_ssl_sessionid_lock(data); - if isproxy { - incache = 0 as i32 != 0; - } else { - incache = !Curl_ssl_getsessionid( - data, - conn, - isproxy, - &mut old_ssl_sessionid, - 0 as *mut size_t, - sockindex, - ); - } - if incache { - if old_ssl_sessionid != ssl_sessionid as *mut libc::c_void { - unsafe { - Curl_infof( - data, - b"old SSL session ID is stale, removing\0" as *const u8 - as *const libc::c_char, - ); - } - Curl_ssl_delsessionid(data, old_ssl_sessionid); - incache = 0 as i32 != 0; - } - } - if !incache { - if Curl_ssl_addsessionid( - data, - conn, - isproxy, - ssl_sessionid as *mut libc::c_void, - 0 as size_t, - sockindex, - ) as u64 - == 0 - { - /* the session has been put into the session cache */ - res = 1 as i32; - } else { - unsafe { - Curl_failf( - data, - b"failed to store ssl session\0" as *const u8 as *const libc::c_char, - ); - } - } - } - Curl_ssl_sessionid_unlock(data); - } - return res; -} - -#[cfg(USE_OPENSSL)] -extern "C" fn load_cacert_from_memory( - mut ctx: *mut SSL_CTX, - mut ca_info_blob: *const curl_blob, -) -> CURLcode { - /* these need to be freed at the end */ - let mut cbio: *mut BIO = 0 as *mut BIO; - let mut inf: *mut stack_st_X509_INFO = 0 as *mut stack_st_X509_INFO; - /* everything else is just a reference */ - let mut i: i32 = 0; - let mut count: i32 = 0 as i32; - let mut cts: *mut X509_STORE = 0 as *mut X509_STORE; - let mut itmp: *mut X509_INFO = 0 as *mut X509_INFO; - if unsafe { (*ca_info_blob).len } > 2147483647 as size_t { - return CURLE_SSL_CACERT_BADFILE; - } - cts = unsafe { SSL_CTX_get_cert_store(ctx) }; - if cts.is_null() { - return CURLE_OUT_OF_MEMORY; - } - cbio = unsafe { BIO_new_mem_buf((*ca_info_blob).data, (*ca_info_blob).len as i32) }; - if cbio.is_null() { - return CURLE_OUT_OF_MEMORY; - } - inf = unsafe { - PEM_X509_INFO_read_bio( - cbio, - 0 as *mut stack_st_X509_INFO, - None, - 0 as *mut libc::c_void, - ) - }; - if inf.is_null() { - unsafe { - BIO_free(cbio); - } - return CURLE_SSL_CACERT_BADFILE; - } - /* add each entry from PEM file to x509_store */ - i = 0 as i32; - while i < sk_X509_INFO_num(inf) { - itmp = sk_X509_INFO_value(inf, i); - if unsafe { !((*itmp).x509).is_null() } { - if unsafe { X509_STORE_add_cert(cts, (*itmp).x509) } != 0 { - count += 1; - } else { - /* set count to 0 to return an error */ - count = 0 as i32; - break; - } - } - if unsafe { !((*itmp).crl).is_null() } { - if unsafe { X509_STORE_add_crl(cts, (*itmp).crl) } != 0 { - count += 1; - } else { - /* set count to 0 to return an error */ - count = 0 as i32; - break; - } - } - i += 1; - } - sk_X509_INFO_pop_free( - inf, - Some(X509_INFO_free as unsafe extern "C" fn(*mut X509_INFO) -> ()), - ); - unsafe { - BIO_free(cbio); - } - /* if we didn't end up importing anything, treat that as an error */ - return (if count > 0 as i32 { - CURLE_OK as i32 - } else { - CURLE_SSL_CACERT_BADFILE as i32 - }) as CURLcode; -} - -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_connect_step1( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut ciphers: *mut libc::c_char = 0 as *mut libc::c_char; - let mut req_method: *const SSL_METHOD = 0 as *const SSL_METHOD; - let mut lookup: *mut X509_LOOKUP = 0 as *mut X509_LOOKUP; - let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } - as *mut ssl_connect_data; - let mut ctx_options: ctx_option_t = 0 as ctx_option_t; - let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - let mut sni: bool = false; - let hostname: *const libc::c_char = unsafe { (*conn).host.name }; - let mut addr: in_addr = in_addr { s_addr: 0 }; - let ssl_version: i64 = unsafe { (*conn).ssl_config.version }; - let ssl_authtype: CURL_TLSAUTH = unsafe { (*data).set.ssl.authtype }; - let ssl_cert: *mut libc::c_char = unsafe { (*data).set.ssl.primary.clientcert }; - let mut ssl_cert_blob: *const curl_blob = unsafe { (*data).set.ssl.primary.cert_blob }; - let mut ca_info_blob: *const curl_blob = unsafe { (*conn).ssl_config.ca_info_blob }; - let ssl_cert_type: *const libc::c_char = unsafe { (*data).set.ssl.cert_type }; - let ssl_cafile: *const libc::c_char = if !ca_info_blob.is_null() { - 0 as *mut libc::c_char - } else { - unsafe { (*conn).ssl_config.CAfile } - }; - let ssl_capath: *const libc::c_char = unsafe { (*conn).ssl_config.CApath }; - let verifypeer: bool = unsafe { ((*conn).ssl_config).verifypeer() } != 0; - let ssl_crlfile: *const libc::c_char = unsafe { (*data).set.ssl.CRLfile }; /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ - let mut error_buffer: [libc::c_char; 256] = [0; 256]; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - let mut imported_native_ca: bool = 0 as i32 != 0; - /* Make funny stuff to get random input */ - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ssl_connect_1 as u32 == unsafe { (*connssl).connecting_state as u32 } { - } else { - unsafe { - __assert_fail( - b"ssl_connect_1 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 2628 as u32, - (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( - b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - } - result = ossl_seed(data); - if result as u64 != 0 { - return result; - } - unsafe { - (*data).set.ssl.certverifyresult = (0 as i32 == 0) as i64; - } - /* check to see if we've been told to use an explicit SSL/TLS version */ - match ssl_version { - 0 | 1 | 4 | 5 | 6 | 7 => { - req_method = unsafe { TLS_client_method() }; /* it will be handled later with the context options */ - sni = 1 as i32 != 0; - } - 2 => { - unsafe { - Curl_failf( - data, - b"No SSLv2 support\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_NOT_BUILT_IN; - } - 3 => { - unsafe { - Curl_failf( - data, - b"No SSLv3 support\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_NOT_BUILT_IN; - } - _ => { - unsafe { - Curl_failf( - data, - b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 - as *const libc::c_char, - ); - } - return CURLE_SSL_CONNECT_ERROR; - } - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe { ((*backend).ctx).is_null() } { - } else { - unsafe { - __assert_fail( - b"!backend->ctx\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 2665 as u32, - (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( - b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - } - unsafe { - (*backend).ctx = SSL_CTX_new(req_method); - if ((*backend).ctx).is_null() { - Curl_failf( - data, - b"SSL: couldn't create a context: %s\0" as *const u8 as *const libc::c_char, - ossl_strerror( - ERR_peek_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return CURLE_OUT_OF_MEMORY; - } - SSL_CTX_ctrl( - (*backend).ctx, - 33 as i32, - 0x10 as i64, - 0 as *mut libc::c_void, - ); - if ((*data).set.fdebug).is_some() && ((*data).set).verbose() as i32 != 0 { - /* the SSL trace callback is only used for verbose logging */ - SSL_CTX_set_msg_callback( - (*backend).ctx, - Some( - ossl_trace - as unsafe extern "C" fn( - i32, - i32, - i32, - *const libc::c_void, - size_t, - *mut SSL, - *mut libc::c_void, - ) -> (), - ), - ); - SSL_CTX_ctrl( - (*backend).ctx, - 16 as i32, - 0 as i64, - conn as *mut libc::c_void, - ); - (*(*conn).ssl[0 as usize].backend).logger = data; - } - } - /* OpenSSL contains code to work around lots of bugs and flaws in various - SSL-implementations. SSL_CTX_set_options() is used to enabled those - work-arounds. The man page for this option states that SSL_OP_ALL enables - all the work-arounds and that "It is usually safe to use SSL_OP_ALL to - enable the bug workaround options if compatibility with somewhat broken - implementations is desired." - - The "-no_ticket" option was introduced in OpenSSL 0.9.8j. It's a flag to - disable "rfc4507bis session ticket support". rfc4507bis was later turned - into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077 - - The enabled extension concerns the session management. I wonder how often - libcurl stops a connection and then resumes a TLS session. Also, sending - the session data is some overhead. I suggest that you just use your - proposed patch (which explicitly disables TICKET). - - If someone writes an application with libcurl and OpenSSL who wants to - enable the feature, one can do this in the SSL callback. - - SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper - interoperability with web server Netscape Enterprise Server 2.0.1 which - was released back in 1996. - - Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has - become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate - CVE-2010-4180 when using previous OpenSSL versions we no longer enable - this option regardless of OpenSSL version and SSL_OP_ALL definition. - - OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability - (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to - SSL_OP_ALL that _disables_ that work-around despite the fact that - SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to - keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit - must not be set. - */ - ctx_options = - (0x80000000 as u32 | 0x800 as u32 | 0x4 as u32 | 0x10 as u32 | 0x40 as u32) as ctx_option_t; - ctx_options |= 0x4000 as i64; - ctx_options |= 0x20000 as i64; - ctx_options &= !(0 as i32) as i64; - if unsafe { ((*data).set.ssl).enable_beast() == 0 } { - ctx_options &= !(0x800 as u32) as i64; - } - let mut current_block_41: u64; - match ssl_version { - 2 | 3 => return CURLE_NOT_BUILT_IN, - 0 | 1 => { - current_block_41 = 14687600604451543688; - } - 4 => { - current_block_41 = 14687600604451543688; - } - 5 => { - current_block_41 = 9382186424990608957; - } - 6 | 7 => { - current_block_41 = 4869852262838046136; - } - _ => { - unsafe { - Curl_failf( - data, - b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 - as *const libc::c_char, - ); - } - return CURLE_SSL_CONNECT_ERROR; - } - } - match current_block_41 { - 14687600604451543688 => { - current_block_41 = 9382186424990608957; - } - _ => {} - } - match current_block_41 { - 9382186424990608957 => {} - _ => {} - } - /* asking for any TLS version as the minimum, means no SSL versions - allowed */ - ctx_options |= 0 as i64; - ctx_options |= 0x2000000 as i64; - result = unsafe { set_ssl_version_min_max((*backend).ctx, conn) }; - if result as u32 != CURLE_OK as u32 { - return result; - } - unsafe { - SSL_CTX_set_options((*backend).ctx, ctx_options as u64); - - // ************************************************************************ - #[cfg(HAS_NPN)] - if ((*conn).bits).tls_enable_npn() != 0 { - SSL_CTX_set_next_proto_select_cb( - (*backend).ctx, - Some( - select_next_proto_cb - as unsafe extern "C" fn( - *mut SSL, - *mut *mut u8, - *mut u8, - *const u8, - u32, - *mut libc::c_void, - ) -> i32, - ), - data as *mut libc::c_void, - ); - } - } - #[cfg(HAS_APLN)] - if unsafe { ((*conn).bits).tls_enable_alpn() != 0 } { - let mut cur: i32 = 0 as i32; - let mut protocols: [u8; 128] = [0; 128]; - if cfg!(USE_HTTP2) { - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let CURL_DISABLE_PROXY_flag_1 = (!(CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32) - || ((*conn).bits).tunnel_proxy() == 0); - #[cfg(CURL_DISABLE_PROXY)] - let CURL_DISABLE_PROXY_flag_1 = true; - if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 - && CURL_DISABLE_PROXY_flag_1 - { - let fresh10 = cur; - cur = cur + 1; - protocols[fresh10 as usize] = 2 as u8; - memcpy( - &mut *protocols.as_mut_ptr().offset(cur as isize) as *mut u8 - as *mut libc::c_void, - b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, - 2 as u64, - ); - cur += 2 as i32; - Curl_infof( - data, - b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, - b"h2\0" as *const u8 as *const libc::c_char, - ); - } - } - } - let fresh11 = cur; - cur = cur + 1; - protocols[fresh11 as usize] = 8 as u8; - unsafe { - memcpy( - &mut *protocols.as_mut_ptr().offset(cur as isize) as *mut u8 as *mut libc::c_void, - b"http/1.1\0" as *const u8 as *const libc::c_char as *const libc::c_void, - 8 as u64, - ); - } - cur += 8 as i32; - unsafe { - Curl_infof( - data, - b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, - b"http/1.1\0" as *const u8 as *const libc::c_char, - ); - } - /* expects length prefixed preference ordered list of protocols in wire - * format - */ - if unsafe { SSL_CTX_set_alpn_protos((*backend).ctx, protocols.as_mut_ptr(), cur as u32) } - != 0 - { - unsafe { - Curl_failf( - data, - b"Error setting ALPN\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_SSL_CONNECT_ERROR; - } - } - - if !ssl_cert.is_null() || !ssl_cert_blob.is_null() || !ssl_cert_type.is_null() { - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let cert_stuff_flag = cert_stuff( - data, - (*backend).ctx, - ssl_cert, - ssl_cert_blob, - ssl_cert_type, - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key - } else { - (*data).set.ssl.key - }), - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key_blob - } else { - (*data).set.ssl.key_blob - }), - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key_type - } else { - (*data).set.ssl.key_type - }), - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key_passwd - } else { - (*data).set.ssl.key_passwd - }), - ); - #[cfg(CURL_DISABLE_PROXY)] - let cert_stuff_flag = cert_stuff( - data, - (*backend).ctx, - ssl_cert, - ssl_cert_blob, - ssl_cert_type, - (*data).set.ssl.key, - (*data).set.ssl.key_blob, - (*data).set.ssl.key_type, - (*data).set.ssl.key_passwd, - ); - if result as u64 == 0 && cert_stuff_flag == 0 { - result = CURLE_SSL_CERTPROBLEM; - } - if result as u64 != 0 { - /* failf() is already done in cert_stuff() */ - return result; - } - } - } - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_cipher_list = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.cipher_list - } else { - (*conn).ssl_config.cipher_list - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_cipher_list = (*conn).ssl_config.cipher_list; - ciphers = SSL_CONN_CONFIG_cipher_list; - if ciphers.is_null() { - ciphers = 0 as *mut libc::c_char; - } - if !ciphers.is_null() { - if SSL_CTX_set_cipher_list((*backend).ctx, ciphers) == 0 { - Curl_failf( - data, - b"failed setting cipher list: %s\0" as *const u8 as *const libc::c_char, - ciphers, - ); - return CURLE_SSL_CIPHER; - } - Curl_infof( - data, - b"Cipher selection: %s\0" as *const u8 as *const libc::c_char, - ciphers, - ); - } - - // *************************************************************** - #[cfg(all(HAVE_SSL_CTX_SET_CIPHERSUITES, not(CURL_DISABLE_PROXY)))] - let mut ciphers13: *mut libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.cipher_list13 - } else { - (*conn).ssl_config.cipher_list13 - }; - - #[cfg(all(HAVE_SSL_CTX_SET_CIPHERSUITES, CURL_DISABLE_PROXY))] - let mut ciphers13: *mut libc::c_char = (*conn).ssl_config.cipher_list13; - #[cfg(HAVE_SSL_CTX_SET_CIPHERSUITES)] - if !ciphers13.is_null() { - if SSL_CTX_set_ciphersuites((*backend).ctx, ciphers13) == 0 { - Curl_failf( - data, - b"failed setting TLS 1.3 cipher suite: %s\0" as *const u8 - as *const libc::c_char, - ciphers13, - ); - return CURLE_SSL_CIPHER; - } - Curl_infof( - data, - b"TLS 1.3 cipher selection: %s\0" as *const u8 as *const libc::c_char, - ciphers13, - ); - } - /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ - #[cfg(HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH)] - SSL_CTX_set_post_handshake_auth((*backend).ctx, 1 as i32); - #[cfg(all(HAVE_SSL_CTX_SET_EC_CURVES, not(CURL_DISABLE_PROXY)))] - let mut curves: *mut libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.curves - } else { - (*conn).ssl_config.curves - }; - #[cfg(all(HAVE_SSL_CTX_SET_EC_CURVES, CURL_DISABLE_PROXY))] - let mut curves: *mut libc::c_char = (*conn).ssl_config.curves; - #[cfg(HAVE_SSL_CTX_SET_EC_CURVES)] - if !curves.is_null() { - if SSL_CTX_ctrl( - (*backend).ctx, - 92 as i32, - 0 as i64, - curves as *mut libc::c_void, - ) == 0 - { - Curl_failf( - data, - b"failed setting curves list: '%s'\0" as *const u8 as *const libc::c_char, - curves, - ); - return CURLE_SSL_CIPHER; - } - } - // #[cfg(USE_OPENSSL_SRP)] - if ssl_authtype as u32 == CURL_TLSAUTH_SRP as u32 { - #[cfg(not(CURL_DISABLE_PROXY))] - let ssl_username: *mut libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }; - #[cfg(CURL_DISABLE_PROXY)] - let ssl_username: *mut libc::c_char = (*data).set.ssl.username; - Curl_infof( - data, - b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, - ssl_username, - ); - if SSL_CTX_set_srp_username((*backend).ctx, ssl_username) == 0 { - Curl_failf( - data, - b"Unable to set SRP user name\0" as *const u8 as *const libc::c_char, - ); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - #[cfg(not(CURL_DISABLE_PROXY))] - if SSL_CTX_set_srp_password( - (*backend).ctx, - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.password - } else { - (*data).set.ssl.password - }), - ) == 0 - { - Curl_failf( - data, - b"failed setting SRP password\0" as *const u8 as *const libc::c_char, - ); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - #[cfg(CURL_DISABLE_PROXY)] - if SSL_CTX_set_srp_password((*backend).ctx, (*data).set.ssl.password) == 0 { - Curl_failf( - data, - b"failed setting SRP password\0" as *const u8 as *const libc::c_char, - ); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - #[cfg(not(CURL_DISABLE_PROXY))] - if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.cipher_list - } else { - (*conn).ssl_config.cipher_list - } - .is_null() - { - Curl_infof( - data, - b"Setting cipher list SRP\0" as *const u8 as *const libc::c_char, - ); - if SSL_CTX_set_cipher_list( - (*backend).ctx, - b"SRP\0" as *const u8 as *const libc::c_char, - ) == 0 - { - Curl_failf( - data, - b"failed setting SRP cipher list\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CIPHER; - } - } - #[cfg(CURL_DISABLE_PROXY)] - if ((*conn).ssl_config.cipher_list).is_null() { - Curl_infof( - data, - b"Setting cipher list SRP\0" as *const u8 as *const libc::c_char, - ); - if SSL_CTX_set_cipher_list( - (*backend).ctx, - b"SRP\0" as *const u8 as *const libc::c_char, - ) == 0 - { - Curl_failf( - data, - b"failed setting SRP cipher list\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CIPHER; - } - } - } - } - if !ca_info_blob.is_null() { - result = unsafe { load_cacert_from_memory((*backend).ctx, ca_info_blob) }; - if result as u64 != 0 { - if result as u32 == CURLE_OUT_OF_MEMORY as u32 - || verifypeer as i32 != 0 && !imported_native_ca - { - /* Fail if we insist on successfully verifying the server. */ - unsafe { - Curl_failf( - data, - b"error importing CA certificate blob\0" as *const u8 - as *const libc::c_char, - ); - } - return result; - } - /* Continue with warning if certificate verification isn't required. */ - unsafe { - Curl_infof( - data, - b"error importing CA certificate blob, continuing anyway\0" as *const u8 - as *const libc::c_char, - ); - } - } - } - if !ssl_cafile.is_null() || !ssl_capath.is_null() { - /* tell SSL where to find CA certificates that are used to verify - the server's certificate. */ - if unsafe { SSL_CTX_load_verify_locations((*backend).ctx, ssl_cafile, ssl_capath) } == 0 { - if verifypeer as i32 != 0 && !imported_native_ca { - /* Fail if we insist on successfully verifying the server. */ - unsafe { - Curl_failf( - data, - b"error setting certificate verify locations: CAfile: %s CApath: %s\0" - as *const u8 as *const libc::c_char, - if !ssl_cafile.is_null() { - ssl_cafile - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - if !ssl_capath.is_null() { - ssl_capath - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - } - return CURLE_SSL_CACERT_BADFILE; - } - /* Just continue with a warning if no strict certificate verification - is required. */ - unsafe { - Curl_infof( - data, - b"error setting certificate verify locations, continuing anyway:\0" as *const u8 - as *const libc::c_char, - ); - } - } else { - /* Everything is fine. */ - unsafe { - Curl_infof( - data, - b"successfully set certificate verify locations:\0" as *const u8 - as *const libc::c_char, - ); - } - } - unsafe { - Curl_infof( - data, - b" CAfile: %s\0" as *const u8 as *const libc::c_char, - if !ssl_cafile.is_null() { - ssl_cafile - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - Curl_infof( - data, - b" CApath: %s\0" as *const u8 as *const libc::c_char, - if !ssl_capath.is_null() { - ssl_capath - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - } - } - - if !ssl_crlfile.is_null() { - /* tell OpenSSL where to find CRL file that is used to check certificate - * revocation */ - lookup = unsafe { - X509_STORE_add_lookup(SSL_CTX_get_cert_store((*backend).ctx), X509_LOOKUP_file()) - }; - if lookup.is_null() || unsafe { X509_load_crl_file(lookup, ssl_crlfile, 1 as i32) } == 0 { - unsafe { - Curl_failf( - data, - b"error loading CRL file: %s\0" as *const u8 as *const libc::c_char, - ssl_crlfile, - ); - } - return CURLE_SSL_CRL_BADFILE; - } - /* Everything is fine. */ - unsafe { - Curl_infof( - data, - b"successfully loaded CRL file:\0" as *const u8 as *const libc::c_char, - ); - X509_STORE_set_flags( - SSL_CTX_get_cert_store((*backend).ctx), - (0x4 as i32 | 0x8 as i32) as u64, - ); - Curl_infof( - data, - b" CRLfile: %s\0" as *const u8 as *const libc::c_char, - ssl_crlfile, - ); - } - } - if verifypeer { - /* Try building a chain using issuers in the trusted store first to avoid - problems with server-sent legacy intermediates. Newer versions of - OpenSSL do alternate chain checking by default but we do not know how to - determine that in a reliable manner. - https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest - */ - unsafe { - X509_STORE_set_flags(SSL_CTX_get_cert_store((*backend).ctx), 0x8000 as u64); - if ((*data).set.ssl).no_partialchain() == 0 && ssl_crlfile.is_null() { - /* Have intermediate certificates in the trust store be treated as - trust-anchors, in the same way as self-signed root CA certificates - are. This allows users to verify servers using the intermediate cert - only, instead of needing the whole chain. - - Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we - cannot do partial chains with a CRL check. - */ - X509_STORE_set_flags(SSL_CTX_get_cert_store((*backend).ctx), 0x80000 as u64); - } - } - } - /* OpenSSL always tries to verify the peer, this only says whether it should - * fail to connect if the verification fails, or if it should continue - * anyway. In the latter case the result of the verification is checked with - * SSL_get_verify_result() below. */ - unsafe { - SSL_CTX_set_verify( - (*backend).ctx, - if verifypeer as i32 != 0 { - 0x1 as i32 - } else { - 0 as i32 - }, - None, - ); - /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ - #[cfg(HAVE_KEYLOG_CALLBACK)] - if Curl_tls_keylog_enabled() { - SSL_CTX_set_keylog_callback( - (*backend).ctx, - Some( - ossl_keylog_callback - as unsafe extern "C" fn(*const SSL, *const libc::c_char) -> (), - ), - ); - } - SSL_CTX_ctrl( - (*backend).ctx, - 44 as i32, - (0x1 as i32 | (0x100 as i32 | 0x200 as i32)) as i64, - 0 as *mut libc::c_void, - ); - /* Enable the session cache because it's a prerequisite for the "new session" - * callback. Use the "external storage" mode to prevent OpenSSL from creating - * an internal session cache. + extern "C" fn verifyhost( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut server_cert: *mut X509, + ) -> CURLcode { + let mut matched: bool = 0 as i32 != 0; + let mut target: i32 = 2 as i32; /* target type, GEN_DNS or GEN_IPADD */ + let mut addrlen: size_t = 0 as size_t; + let mut altnames: *mut stack_st_GENERAL_NAME = 0 as *mut stack_st_GENERAL_NAME; + #[cfg(ENABLE_IPV6)] + let mut addr: in6_addr = in6_addr { + __in6_u: C2RustUnnamed_8 { + __u6_addr8: [0; 16], + }, + }; + #[cfg(not(ENABLE_IPV6))] + let mut addr: in_addr = in_addr { s_addr: 0 }; + // TODO - 1650 + // #[cfg(not(ENABLE_IPV6))] + let mut result: CURLcode = CURLE_OK; + let mut dNSName: bool = 0 as i32 != 0; /* if a dNSName field exists in the cert */ + let mut iPAddress: bool = 0 as i32 != 0; /* if a iPAddress field exists in the cert */ + #[cfg(not(CURL_DISABLE_PROXY))] + let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).http_proxy.host.name } + } else { + unsafe { (*conn).host.name } + }; + #[cfg(CURL_DISABLE_PROXY)] + let hostname: *const libc::c_char = unsafe { (*conn).host.name }; + #[cfg(not(CURL_DISABLE_PROXY))] + let dispname: *const libc::c_char = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).http_proxy.host.dispname } + } else { + unsafe { (*conn).host.dispname } + }; + #[cfg(CURL_DISABLE_PROXY)] + let dispname: *const libc::c_char = unsafe { (*conn).host.dispname }; + // DONE - 1661 + #[cfg(ENABLE_IPV6)] + if unsafe { + ((*conn).bits).ipv6_ip() as i32 != 0 + && inet_pton( + 10 as i32, + hostname, + &mut addr as *mut in6_addr as *mut libc::c_void, + ) != 0 + } { + target = 7 as i32; + addrlen = ::std::mem::size_of::() as u64; + } else if unsafe { + inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in6_addr as *mut libc::c_void, + ) + } != 0 + { + target = 7 as i32; + addrlen = ::std::mem::size_of::() as u64; + } + #[cfg(not(ENABLE_IPV6))] + if unsafe { + inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in_addr as *mut libc::c_void, + ) + } != 0 + { + target = 7 as i32; + addrlen = ::std::mem::size_of::() as u64; + } + /* get a "list" of alternative names */ + altnames = unsafe { X509_get_ext_d2i(server_cert, 85 as i32, 0 as *mut i32, 0 as *mut i32) } + as *mut stack_st_GENERAL_NAME; + if !altnames.is_null() { + unsafe { + // TODO 待确认 + #[cfg(OPENSSL_IS_BORINGSSL)] + let mut numalts: ibc::c_int = 0; + #[cfg(OPENSSL_IS_BORINGSSL)] + let mut i: ibc::c_int = 0; + #[cfg(not(OPENSSL_IS_BORINGSSL))] + let mut numalts: i32 = 0; + #[cfg(not(OPENSSL_IS_BORINGSSL))] + let mut i: i32 = 0; + let mut dnsmatched: bool = 0 as i32 != 0; + let mut ipmatched: bool = 0 as i32 != 0; + /* get amount of alternatives, RFC2459 claims there MUST be at least + one, but we don't depend on it... */ + numalts = sk_GENERAL_NAME_num(altnames); + /* loop through all alternatives - until a dnsmatch */ + i = 0 as i32; + while i < numalts && !dnsmatched { + /* get a handle to alternative name number i */ + let mut check: *const GENERAL_NAME = sk_GENERAL_NAME_value(altnames, i); + if (*check).type_0 == 2 as i32 { + dNSName = 1 as i32 != 0; + } else if (*check).type_0 == 7 as i32 { + iPAddress = 1 as i32 != 0; + } + /* only check alternatives of the same type the target is */ + if (*check).type_0 == target { + /* get data and length */ + let mut altptr: *const libc::c_char = + ASN1_STRING_get0_data((*check).d.ia5) as *mut libc::c_char; + let mut altlen: size_t = ASN1_STRING_length((*check).d.ia5) as size_t; + match target { + 2 => { + /* name/pattern comparison */ + /* The OpenSSL man page explicitly says: "In general it cannot be + assumed that the data returned by ASN1_STRING_data() is null + terminated or does not contain embedded nulls." But also that + "The actual format of the data will depend on the actual string + type itself: for example for an IA5String the data will be ASCII" + + It has been however verified that in 0.9.6 and 0.9.7, IA5String + is always null-terminated. + */ + if altlen == strlen(altptr) + && subj_alt_hostcheck(data, altptr, hostname, dispname) as i32 != 0 + { + /* if this isn't true, there was an embedded zero in the name + string and we cannot match it. */ + dnsmatched = 1 as i32 != 0; + } + } + 7 => { + /* IP address comparison */ + #[cfg(ENABLE_IPV6)] + let ENABLE_IPV6_a = memcmp( + altptr as *const libc::c_void, + &mut addr as *mut in6_addr as *const libc::c_void, + altlen, + ) == 0; + #[cfg(not(ENABLE_IPV6))] + let ENABLE_IPV6_a = memcmp( + altptr as *const libc::c_void, + &mut addr as *mut in_addr as *const libc::c_void, + altlen, + ) == 0; + /* compare alternative IP address if the data chunk is the same size + our server IP address is */ + if altlen == addrlen && ENABLE_IPV6_a { + ipmatched = 1 as i32 != 0; + Curl_infof( + data, + b" subjectAltName: host \"%s\" matched cert's IP address!\0" + as *const u8 + as *const libc::c_char, + dispname, + ); + } + } + _ => {} + } + } + i += 1; + } + GENERAL_NAMES_free(altnames); + if dnsmatched as i32 != 0 || ipmatched as i32 != 0 { + matched = 1 as i32 != 0; + } + } + } + /* an alternative name matched */ + if !matched { + if dNSName as i32 != 0 || iPAddress as i32 != 0 { + unsafe { + Curl_infof( + data, + b" subjectAltName does not match %s\0" as *const u8 as *const libc::c_char, + dispname, + ); + Curl_failf( + data, + b"SSL: no alternative certificate subject name matches target host name '%s'\0" + as *const u8 as *const libc::c_char, + dispname, + ); + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else { + /* we have to look to the last occurrence of a commonName in the + distinguished one to get the most significant one. */ + let mut j: i32 = 0; + let mut i_0: i32 = -(1 as i32); + /* The following is done because of a bug in 0.9.6b */ + let mut nulstr: *mut u8 = b"\0" as *const u8 as *const libc::c_char as *mut u8; + let mut peer_CN: *mut u8 = nulstr; + let mut name: *mut X509_NAME = unsafe { X509_get_subject_name(server_cert) }; + if !name.is_null() { + loop { + j = unsafe { X509_NAME_get_index_by_NID(name, 13 as i32, i_0) }; + if !(j >= 0 as i32) { + break; + } + i_0 = j; + } + } + /* we have the name entry and we will now convert this to a string + that we can use for comparison. Doing this we support BMPstring, + UTF8, etc. */ + + if i_0 >= 0 as i32 { + let mut tmp: *mut ASN1_STRING = + unsafe { X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i_0)) }; + if !tmp.is_null() { + unsafe { + /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input + is already UTF-8 encoded. We check for this case and copy the raw + string manually to avoid the problem. This code can be made + conditional in the future when OpenSSL has been fixed. */ + if ASN1_STRING_type(tmp) == 12 as i32 { + j = ASN1_STRING_length(tmp); + if j >= 0 as i32 { + peer_CN = CRYPTO_malloc( + (j + 1 as i32) as size_t, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 1786 as i32, + ) as *mut u8; + if !peer_CN.is_null() { + memcpy( + peer_CN as *mut libc::c_void, + ASN1_STRING_get0_data(tmp) as *const libc::c_void, + j as u64, + ); + *peer_CN.offset(j as isize) = '\0' as i32 as u8; + } + } + } else { + /* not a UTF8 name */ + j = ASN1_STRING_to_UTF8(&mut peer_CN, tmp); + } + if !peer_CN.is_null() + && curlx_uztosi(strlen(peer_CN as *mut libc::c_char)) != j + { + /* there was a terminating zero before the end of string, this + cannot match and we return failure! */ + Curl_failf( + data, + b"SSL: illegal cert name field\0" as *const u8 + as *const libc::c_char, + ); + result = CURLE_PEER_FAILED_VERIFICATION; + } + } + } + } + if peer_CN == nulstr { + peer_CN = 0 as *mut u8; + } else { + /* convert peer_CN from UTF8 */ + let mut rc: CURLcode = CURLE_OK as CURLcode; + /* Curl_convert_from_utf8 calls failf if unsuccessful */ + if rc as u64 != 0 { + unsafe { + CRYPTO_free( + peer_CN as *mut libc::c_void, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 1813 as i32, + ); + } + return rc; + } + } + if !(result as u64 != 0) { + /* error already detected, pass through */ + if peer_CN.is_null() { + unsafe { + Curl_failf( + data, + b"SSL: unable to obtain common name from peer certificate\0" + as *const u8 as *const libc::c_char, + ); + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else if unsafe { Curl_cert_hostcheck(peer_CN as *const libc::c_char, hostname) } + == 0 + { + unsafe { + Curl_failf( + data, + b"SSL: certificate subject name '%s' does not match target host name '%s'\0" + as *const u8 as *const libc::c_char, + peer_CN, + dispname, + ); + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else { + unsafe { + Curl_infof( + data, + b" common name: %s (matched)\0" as *const u8 as *const libc::c_char, + peer_CN, + ); + } + } + } + if !peer_CN.is_null() { + unsafe { + CRYPTO_free( + peer_CN as *mut libc::c_void, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 1835 as i32, + ); + } + } + } + } + return result; + } + + #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP)))] + extern "C" fn verifystatus( + mut data: *mut Curl_easy, + mut connssl: *mut ssl_connect_data, + ) -> CURLcode { + let mut current_block: u64; + let mut i: i32 = 0; + let mut ocsp_status: i32 = 0; + let mut status: *mut u8 = 0 as *mut u8; + let mut p: *const u8 = 0 as *const u8; + let mut result: CURLcode = CURLE_OK; + let mut rsp: *mut OCSP_RESPONSE = 0 as *mut OCSP_RESPONSE; + let mut br: *mut OCSP_BASICRESP = 0 as *mut OCSP_BASICRESP; + let mut st: *mut X509_STORE = 0 as *mut X509_STORE; + let mut ch: *mut stack_st_X509 = 0 as *mut stack_st_X509; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut cert: *mut X509 = 0 as *mut X509; + let mut id: *mut OCSP_CERTID = 0 as *mut OCSP_CERTID; + let mut cert_status: i32 = 0; + let mut crl_reason: i32 = 0; + let mut rev: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; + let mut thisupd: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; + let mut nextupd: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; + let mut ret: i32 = 0; + let mut len: i64 = unsafe { + SSL_ctrl( + (*backend).handle, + 70 as i32, + 0 as i64, + &mut status as *mut *mut u8 as *mut libc::c_void, + ) + }; + 'end: loop { + if status.is_null() { + unsafe { + Curl_failf( + data, + b"No OCSP response received\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + p = status; + rsp = unsafe { d2i_OCSP_RESPONSE(0 as *mut *mut OCSP_RESPONSE, &mut p, len) }; + if rsp.is_null() { + unsafe { + Curl_failf( + data, + b"Invalid OCSP response\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + ocsp_status = unsafe { OCSP_response_status(rsp) }; + if ocsp_status != 0 as i32 { + unsafe { + Curl_failf( + data, + b"Invalid OCSP response status: %s (%d)\0" as *const u8 as *const libc::c_char, + OCSP_response_status_str(ocsp_status as i64), + ocsp_status, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + br = unsafe { OCSP_response_get1_basic(rsp) }; + if br.is_null() { + unsafe { + Curl_failf( + data, + b"Invalid OCSP response\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + unsafe { + ch = SSL_get_peer_cert_chain((*backend).handle); + st = SSL_CTX_get_cert_store((*backend).ctx); + } + /* The authorized responder cert in the OCSP response MUST be signed by the + peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert, + no problem, but if it's an intermediate cert OpenSSL has a bug where it + expects this issuer to be present in the chain embedded in the OCSP + response. So we add it if necessary. */ + + /* First make sure the peer cert chain includes both a peer and an issuer, + and the OCSP response contains a responder cert. */ + // TODO - 1894 这里有一段跟OPENSSL_VERSION_NUMBER相关的条件编译 + if cfg!(any( + OPENSSL_VERSION_NUMBER_LT_0X1000201FL, + all( + LIBRESSL_VERSION_NUMBER, + LIBRESSL_VERSION_NUMBER_LT_0X2040200FL + ) + )) { + // TODO + } + if unsafe { OCSP_basic_verify(br, ch, st, 0 as u64) <= 0 as i32 } { + unsafe { + Curl_failf( + data, + b"OCSP response verification failed\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + cert = unsafe { SSL_get_peer_certificate((*backend).handle) }; + if cert.is_null() { + unsafe { + Curl_failf( + data, + b"Error getting peer certificate\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + /* Find issuer of responder cert and add it to the OCSP response chain */ + i = 0 as i32; + while i < sk_X509_num(ch) { + let mut issuer: *mut X509 = sk_X509_value(ch, i); + if unsafe { X509_check_issued(issuer, cert) } == 0 as i32 { + id = unsafe { OCSP_cert_to_id(EVP_sha1(), cert, issuer) }; + break; + } else { + i += 1; + } + } + unsafe { + X509_free(cert); + } + if id.is_null() { + unsafe { + Curl_failf( + data, + b"Error computing OCSP ID\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + /* Find the single OCSP response corresponding to the certificate ID */ + unsafe { + ret = OCSP_resp_find_status( + br, + id, + &mut cert_status, + &mut crl_reason, + &mut rev, + &mut thisupd, + &mut nextupd, + ); + OCSP_CERTID_free(id); + } + if ret != 1 as i32 { + unsafe { + Curl_failf( + data, + b"Could not find certificate ID in OCSP response\0" as *const u8 + as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + /* Validate the corresponding single OCSP response */ + unsafe { + if OCSP_check_validity(thisupd, nextupd, 300 as i64, -(1 as i64)) == 0 { + Curl_failf( + data, + b"OCSP response has expired\0" as *const u8 as *const libc::c_char, + ); + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + Curl_infof( + data, + b"SSL certificate status: %s (%d)\0" as *const u8 as *const libc::c_char, + OCSP_cert_status_str(cert_status as i64), + cert_status, + ); + } + let mut current_block_63: u64; + match cert_status { + 0 => { + current_block_63 = 13484060386966298149; + } + 1 => { + result = CURLE_SSL_INVALIDCERTSTATUS; + unsafe { + Curl_failf( + data, + b"SSL certificate revocation reason: %s (%d)\0" as *const u8 + as *const libc::c_char, + OCSP_crl_reason_str(crl_reason as i64), + crl_reason, + ); + } + current_block_63 = 11531555616992456840; + break 'end; + } + 2 | _ => { + current_block_63 = 11531555616992456840; + } + } + match current_block_63 { + 11531555616992456840 => { + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + _ => {} + } + break 'end; + } + if !br.is_null() { + unsafe { + OCSP_BASICRESP_free(br); + } + } + unsafe { + OCSP_RESPONSE_free(rsp); + } + return result; + } + + #[cfg(SSL_CTRL_SET_MSG_CALLBACK)] + extern "C" fn ssl_msg_type(mut ssl_ver: i32, mut msg: i32) -> *const libc::c_char { + if ssl_ver == 0x3 as i32 { + match msg { + 0 => return b"Hello request\0" as *const u8 as *const libc::c_char, + 1 => return b"Client hello\0" as *const u8 as *const libc::c_char, + 2 => return b"Server hello\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_NEWSESSION_TICKET)] + 4 => return b"Newsession Ticket\0" as *const u8 as *const libc::c_char, + 11 => return b"Certificate\0" as *const u8 as *const libc::c_char, + 12 => return b"Server key exchange\0" as *const u8 as *const libc::c_char, + 16 => return b"Client key exchange\0" as *const u8 as *const libc::c_char, + 13 => return b"Request CERT\0" as *const u8 as *const libc::c_char, + 14 => return b"Server finished\0" as *const u8 as *const libc::c_char, + 15 => return b"CERT verify\0" as *const u8 as *const libc::c_char, + 20 => return b"Finished\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_CERTIFICATE_STATUS)] + 22 => return b"Certificate Status\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_ENCRYPTED_EXTENSIONS)] + 8 => return b"Encrypted Extensions\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_SUPPLEMENTAL_DATA)] + 23 => return b"Supplemental data\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_END_OF_EARLY_DATA)] + 5 => return b"End of early data\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_KEY_UPDATE)] + 24 => return b"Key update\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_NEXT_PROTO)] + 67 => return b"Next protocol\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_MESSAGE_HASH)] + 254 => return b"Message hash\0" as *const u8 as *const libc::c_char, + _ => {} + } + } + return b"Unknown\0" as *const u8 as *const libc::c_char; + } + + #[cfg(SSL_CTRL_SET_MSG_CALLBACK)] + extern "C" fn tls_rt_type(mut type_0: i32) -> *const libc::c_char { + match type_0 { + #[cfg(SSL3_RT_HEADER)] + 256 => return b"TLS header\0" as *const u8 as *const libc::c_char, + 20 => return b"TLS change cipher\0" as *const u8 as *const libc::c_char, + 21 => return b"TLS alert\0" as *const u8 as *const libc::c_char, + 22 => return b"TLS handshake\0" as *const u8 as *const libc::c_char, + 23 => return b"TLS app data\0" as *const u8 as *const libc::c_char, + _ => return b"TLS Unknown\0" as *const u8 as *const libc::c_char, + }; + } + + /* + * Our callback from the SSL/TLS layers. + */ + #[cfg(SSL_CTRL_SET_MSG_CALLBACK)] + extern "C" fn ossl_trace( + mut direction: i32, + mut ssl_ver: i32, + mut content_type: i32, + mut buf: *const libc::c_void, + mut len: size_t, + mut ssl: *mut SSL, + mut userp: *mut libc::c_void, + ) { + let mut unknown: [libc::c_char; 32] = [0; 32]; + let mut verstr: *const libc::c_char = 0 as *const libc::c_char; + let mut conn: *mut connectdata = userp as *mut connectdata; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(0 as isize) as *mut ssl_connect_data }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut data: *mut Curl_easy = unsafe { (*backend).logger }; + if conn.is_null() + || data.is_null() + || unsafe { ((*data).set.fdebug).is_none() } + || direction != 0 as i32 && direction != 1 as i32 + { + return; + } + match ssl_ver { + #[cfg(SSL2_VERSION)] + 2 => { + verstr = b"SSLv2\0" as *const u8 as *const libc::c_char; + } + #[cfg(SSL3_VERSION)] + 768 => { + verstr = b"SSLv3\0" as *const u8 as *const libc::c_char; + } + 769 => { + verstr = b"TLSv1.0\0" as *const u8 as *const libc::c_char; + } + #[cfg(TLS1_1_VERSION)] + 770 => { + verstr = b"TLSv1.1\0" as *const u8 as *const libc::c_char; + } + #[cfg(TLS1_2_VERSION)] + 771 => { + verstr = b"TLSv1.2\0" as *const u8 as *const libc::c_char; + } + #[cfg(TLS1_3_VERSION)] + 772 => { + verstr = b"TLSv1.3\0" as *const u8 as *const libc::c_char; + } + 0 => {} + _ => { + unsafe { + curl_msnprintf( + unknown.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 32]>() as u64, + b"(%x)\0" as *const u8 as *const libc::c_char, + ssl_ver, + ); + } + verstr = unknown.as_mut_ptr(); + } + } + /* Log progress for interesting records only (like Handshake or Alert), skip + * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0). + * For TLS 1.3, skip notification of the decrypted inner Content-Type. + */ + // DONE - 2168 + #[cfg(SSL3_RT_INNER_CONTENT_TYPE)] + let SSL3_RT_INNER_CONTENT_TYPE_flag = content_type != 0x101; + #[cfg(not(SSL3_RT_INNER_CONTENT_TYPE))] + let SSL3_RT_INNER_CONTENT_TYPE_flag = true; + if ssl_ver != 0 && SSL3_RT_INNER_CONTENT_TYPE_flag { + let mut msg_name: *const libc::c_char = 0 as *const libc::c_char; + let mut tls_rt_name: *const libc::c_char = 0 as *const libc::c_char; + let mut ssl_buf: [libc::c_char; 1024] = [0; 1024]; + let mut msg_type: i32 = 0; + let mut txt_len: i32 = 0; + /* the info given when the version is zero is not that useful for us */ + + ssl_ver >>= 8 as i32; /* check the upper 8 bits only below */ + /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL + * always pass-up content-type as 0. But the interesting message-type + * is at 'buf[0]'. + */ + if ssl_ver == 0x3 as i32 && content_type != 0 { + tls_rt_name = tls_rt_type(content_type); + } else { + tls_rt_name = b"\0" as *const u8 as *const libc::c_char; + } + if content_type == 20 as i32 { + msg_type = unsafe { *(buf as *mut libc::c_char) } as i32; + msg_name = b"Change cipher spec\0" as *const u8 as *const libc::c_char; + } else if content_type == 21 as i32 { + msg_type = unsafe { + ((*(buf as *mut libc::c_char).offset(0 as isize) as i32) << 8 as i32) + + *(buf as *mut libc::c_char).offset(1 as isize) as i32 + }; + msg_name = unsafe { SSL_alert_desc_string_long(msg_type) }; + } else { + msg_type = unsafe { *(buf as *mut libc::c_char) } as i32; + msg_name = ssl_msg_type(ssl_ver, msg_type); + } + txt_len = unsafe { + curl_msnprintf( + ssl_buf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 1024]>() as u64, + b"%s (%s), %s, %s (%d):\n\0" as *const u8 as *const libc::c_char, + verstr, + if direction != 0 { + b"OUT\0" as *const u8 as *const libc::c_char + } else { + b"IN\0" as *const u8 as *const libc::c_char + }, + tls_rt_name, + msg_name, + msg_type, + ) + }; + if 0 as i32 <= txt_len + && (txt_len as u64) < ::std::mem::size_of::<[libc::c_char; 1024]>() as u64 + { + unsafe { + Curl_debug(data, CURLINFO_TEXT, ssl_buf.as_mut_ptr(), txt_len as size_t); + } + } + } + unsafe { + Curl_debug( + data, + (if direction == 1 as i32 { + CURLINFO_SSL_DATA_OUT as i32 + } else { + CURLINFO_SSL_DATA_IN as i32 + }) as curl_infotype, + buf as *mut libc::c_char, + len, + ); + } + } + + #[cfg(all(USE_OPENSSL, HAS_NPN))] + extern "C" fn select_next_protocol( + mut out: *mut *mut u8, + mut outlen: *mut u8, + mut in_0: *const u8, + mut inlen: u32, + mut key: *const libc::c_char, + mut keylen: u32, + ) -> i32 { + let mut i: u32 = 0; + i = 0 as u32; + while i.wrapping_add(keylen) <= inlen { + if unsafe { + memcmp( + &*in_0.offset(i.wrapping_add(1 as u32) as isize) as *const u8 + as *const libc::c_void, + key as *const libc::c_void, + keylen as u64, + ) + } == 0 as i32 + { + unsafe { + *out = &*in_0.offset(i.wrapping_add(1 as u32) as isize) as *const u8 as *mut u8; + *outlen = *in_0.offset(i as isize); + } + return 0 as i32; + } + i = unsafe { i.wrapping_add((*in_0.offset(i as isize) as i32 + 1 as i32) as u32) }; + } + return -(1 as i32); + } + + #[cfg(all(USE_OPENSSL, HAS_NPN))] + extern "C" fn select_next_proto_cb( + mut ssl: *mut SSL, + mut out: *mut *mut u8, + mut outlen: *mut u8, + mut in_0: *const u8, + mut inlen: u32, + mut arg: *mut libc::c_void, + ) -> i32 { + unsafe { + let mut data: *mut Curl_easy = arg as *mut Curl_easy; + let mut conn: *mut connectdata = (*data).conn; + #[cfg(USE_HTTP2)] + if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 + && select_next_protocol( + out, + outlen, + in_0, + inlen, + b"h2\0" as *const u8 as *const libc::c_char, + 2 as u32, + ) == 0 + { + Curl_infof( + data, + b"NPN, negotiated HTTP2 (%s)\0" as *const u8 as *const libc::c_char, + b"h2\0" as *const u8 as *const libc::c_char, + ); + (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; + return 0 as i32; + } + if select_next_protocol( + out, + outlen, + in_0, + inlen, + b"http/1.1\0" as *const u8 as *const libc::c_char, + 8 as u32, + ) == 0 + { + Curl_infof( + data, + b"NPN, negotiated HTTP1.1\0" as *const u8 as *const libc::c_char, + ); + (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; + return 0 as i32; + } + Curl_infof( + data, + b"NPN, no overlap, use HTTP1.1\0" as *const u8 as *const libc::c_char, + ); + *out = b"http/1.1\0" as *const u8 as *const libc::c_char as *mut u8; + *outlen = 8 as u8; + (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; + return 0 as i32; + } + } + // TODO + // USE_OPENSSL以及与OPENSSL_VERSION_NUMBER相关的条件编译 + #[cfg(USE_OPENSSL)] + extern "C" fn set_ssl_version_min_max( + mut ctx: *mut SSL_CTX, + mut conn: *mut connectdata, + ) -> CURLcode { + #[cfg(not(CURL_DISABLE_PROXY))] + let mut curl_ssl_version_min: i64 = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.version } + } else { + unsafe { (*conn).ssl_config.version } + }; + #[cfg(CURL_DISABLE_PROXY)] + let mut curl_ssl_version_min: i64 = unsafe { (*conn).ssl_config.version }; + + let mut curl_ssl_version_max: i64 = 0; + // TODO - 2307 + // #[cfg(any(OPENSSL_IS_BORINGSSL, LIBRESSL_VERSION_NUMBER))] + // TODO - 2307 + // #[cfg(any(OPENSSL_IS_BORINGSSL, LIBRESSL_VERSION_NUMBER))] + #[cfg(all(not(OPENSSL_IS_BORINGSSL), not(LIBRESSL_VERSION_NUMBER)))] + let mut ossl_ssl_version_min: i64 = 0 as i64; + #[cfg(all(not(OPENSSL_IS_BORINGSSL), not(LIBRESSL_VERSION_NUMBER)))] + let mut ossl_ssl_version_max: i64 = 0 as i64; + match curl_ssl_version_min { + 1 | 4 => { + ossl_ssl_version_min = 0x301 as i64; + } + 5 => { + ossl_ssl_version_min = 0x302 as i64; + } + 6 => { + ossl_ssl_version_min = 0x303 as i64; + } + #[cfg(TLS1_3_VERSION)] + 7 => { + ossl_ssl_version_min = 0x304 as i64; + } + _ => {} + } + /* CURL_SSLVERSION_DEFAULT means that no option was selected. + We don't want to pass 0 to SSL_CTX_set_min_proto_version as + it would enable all versions down to the lowest supported by + the library. + So we skip this, and stay with the library default + */ + if curl_ssl_version_min != CURL_SSLVERSION_DEFAULT as i64 { + if unsafe { + SSL_CTX_ctrl( + ctx, + 123 as i32, + ossl_ssl_version_min, + 0 as *mut libc::c_void, + ) + } == 0 + { + return CURLE_SSL_CONNECT_ERROR; + } + } + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_version_max = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype } as u32 + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.version_max } + } else { + unsafe { (*conn).ssl_config.version_max } + }; + /* ... then, TLS max version */ + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_version_max = unsafe { (*conn).ssl_config.version_max }; + + curl_ssl_version_max = SSL_CONN_CONFIG_version_max; + let mut current_block_15: u64; + /* convert curl max SSL version option to OpenSSL constant */ + match curl_ssl_version_max { + 262144 => { + ossl_ssl_version_max = 0x301 as i64; + current_block_15 = 18386322304582297246; + } + 327680 => { + ossl_ssl_version_max = 0x302 as i64; + current_block_15 = 18386322304582297246; + } + 393216 => { + ossl_ssl_version_max = 0x303 as i64; + current_block_15 = 18386322304582297246; + } + #[cfg(TLS1_3_VERSION)] + 458752 => { + ossl_ssl_version_max = 0x304 as i64; + current_block_15 = 18386322304582297246; + } + // TODO 这里翻译的很奇怪,感觉没有必要这样 + 0 => { + current_block_15 = 9181747712041856033; + } + 65536 | _ => { + current_block_15 = 9181747712041856033; + } + } + match current_block_15 { + 9181747712041856033 => { + /* SSL_CTX_set_max_proto_version states that: + setting the maximum to 0 will enable + protocol versions up to the highest version + supported by the library */ + ossl_ssl_version_max = 0 as i64; + } + _ => {} + } + if unsafe { + SSL_CTX_ctrl( + ctx, + 124 as i32, + ossl_ssl_version_max, + 0 as *mut libc::c_void, + ) + } == 0 + { + return CURLE_SSL_CONNECT_ERROR; + } + return CURLE_OK; + } + + /* The "new session" callback must return zero if the session can be removed + * or non-zero if the session has been put into the session cache. + */ + // TODO 这里有个与OPENSSL_VERSION_NUMBER相关的条件编译 + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_new_session_cb(mut ssl: *mut SSL, mut ssl_sessionid: *mut SSL_SESSION) -> i32 { + let mut res: i32 = 0 as i32; + let mut conn: *mut connectdata = 0 as *mut connectdata; + let mut data: *mut Curl_easy = 0 as *mut Curl_easy; + let mut sockindex: i32 = 0; + let mut sockindex_ptr: *mut curl_socket_t = 0 as *mut curl_socket_t; + let mut data_idx: i32 = ossl_get_ssl_data_index(); + let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); + let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); + let mut proxy_idx: i32 = ossl_get_proxy_index(); + let mut isproxy: bool = false; + if data_idx < 0 as i32 + || connectdata_idx < 0 as i32 + || sockindex_idx < 0 as i32 + || proxy_idx < 0 as i32 + { + return 0 as i32; + } + conn = unsafe { SSL_get_ex_data(ssl, connectdata_idx) as *mut connectdata }; + if conn.is_null() { + return 0 as i32; + } + data = unsafe { SSL_get_ex_data(ssl, data_idx) as *mut Curl_easy }; + /* The sockindex has been stored as a pointer to an array element */ + sockindex_ptr = unsafe { SSL_get_ex_data(ssl, sockindex_idx) as *mut curl_socket_t }; + sockindex = unsafe { sockindex_ptr.offset_from(((*conn).sock).as_mut_ptr()) as i32 }; + isproxy = if unsafe { !(SSL_get_ex_data(ssl, proxy_idx)).is_null() } { + 1 as i32 + } else { + 0 as i32 + } != 0; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } + } else { + unsafe { ((*data).set.ssl.primary).sessionid() as i32 } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() }; + if SSL_SET_OPTION_primary_sessionid != 0 { + let mut incache: bool = false; + let mut old_ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + Curl_ssl_sessionid_lock(data); + if isproxy { + incache = 0 as i32 != 0; + } else { + incache = !Curl_ssl_getsessionid( + data, + conn, + isproxy, + &mut old_ssl_sessionid, + 0 as *mut size_t, + sockindex, + ); + } + if incache { + if old_ssl_sessionid != ssl_sessionid as *mut libc::c_void { + unsafe { + Curl_infof( + data, + b"old SSL session ID is stale, removing\0" as *const u8 + as *const libc::c_char, + ); + } + Curl_ssl_delsessionid(data, old_ssl_sessionid); + incache = 0 as i32 != 0; + } + } + if !incache { + if Curl_ssl_addsessionid( + data, + conn, + isproxy, + ssl_sessionid as *mut libc::c_void, + 0 as size_t, + sockindex, + ) as u64 + == 0 + { + /* the session has been put into the session cache */ + res = 1 as i32; + } else { + unsafe { + Curl_failf( + data, + b"failed to store ssl session\0" as *const u8 as *const libc::c_char, + ); + } + } + } + Curl_ssl_sessionid_unlock(data); + } + return res; + } +// hanxj + #[cfg(USE_OPENSSL)] + extern "C" fn load_cacert_from_memory( + mut ctx: *mut SSL_CTX, + mut ca_info_blob: *const curl_blob, + ) -> CURLcode { + /* these need to be freed at the end */ + let mut cbio: *mut BIO = 0 as *mut BIO; + let mut inf: *mut stack_st_X509_INFO = 0 as *mut stack_st_X509_INFO; + /* everything else is just a reference */ + let mut i: i32 = 0; + let mut count: i32 = 0 as i32; + let mut cts: *mut X509_STORE = 0 as *mut X509_STORE; + let mut itmp: *mut X509_INFO = 0 as *mut X509_INFO; + if unsafe { (*ca_info_blob).len } > 2147483647 as size_t { + return CURLE_SSL_CACERT_BADFILE; + } + cts = unsafe { SSL_CTX_get_cert_store(ctx) }; + if cts.is_null() { + return CURLE_OUT_OF_MEMORY; + } + cbio = unsafe { BIO_new_mem_buf((*ca_info_blob).data, (*ca_info_blob).len as i32) }; + if cbio.is_null() { + return CURLE_OUT_OF_MEMORY; + } + inf = unsafe { + PEM_X509_INFO_read_bio( + cbio, + 0 as *mut stack_st_X509_INFO, + None, + 0 as *mut libc::c_void, + ) + }; + if inf.is_null() { + unsafe { + BIO_free(cbio); + } + return CURLE_SSL_CACERT_BADFILE; + } + /* add each entry from PEM file to x509_store */ + i = 0 as i32; + while i < sk_X509_INFO_num(inf) { + itmp = sk_X509_INFO_value(inf, i); + if unsafe { !((*itmp).x509).is_null() } { + if unsafe { X509_STORE_add_cert(cts, (*itmp).x509) } != 0 { + count += 1; + } else { + /* set count to 0 to return an error */ + count = 0 as i32; + break; + } + } + if unsafe { !((*itmp).crl).is_null() } { + if unsafe { X509_STORE_add_crl(cts, (*itmp).crl) } != 0 { + count += 1; + } else { + /* set count to 0 to return an error */ + count = 0 as i32; + break; + } + } + i += 1; + } + sk_X509_INFO_pop_free( + inf, + Some(X509_INFO_free as unsafe extern "C" fn(*mut X509_INFO) -> ()), + ); + unsafe { + BIO_free(cbio); + } + /* if we didn't end up importing anything, treat that as an error */ + return (if count > 0 as i32 { + CURLE_OK as i32 + } else { + CURLE_SSL_CACERT_BADFILE as i32 + }) as CURLcode; + } + + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_connect_step1( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut ciphers: *mut libc::c_char = 0 as *mut libc::c_char; + let mut req_method: *const SSL_METHOD = 0 as *const SSL_METHOD; + let mut lookup: *mut X509_LOOKUP = 0 as *mut X509_LOOKUP; + let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } + as *mut ssl_connect_data; + let mut ctx_options: ctx_option_t = 0 as ctx_option_t; + let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + let mut sni: bool = false; + let hostname: *const libc::c_char = unsafe { (*conn).host.name }; + let mut addr: in_addr = in_addr { s_addr: 0 }; + let ssl_version: i64 = unsafe { (*conn).ssl_config.version }; + let ssl_authtype: CURL_TLSAUTH = unsafe { (*data).set.ssl.authtype }; + let ssl_cert: *mut libc::c_char = unsafe { (*data).set.ssl.primary.clientcert }; + let mut ssl_cert_blob: *const curl_blob = unsafe { (*data).set.ssl.primary.cert_blob }; + let mut ca_info_blob: *const curl_blob = unsafe { (*conn).ssl_config.ca_info_blob }; + let ssl_cert_type: *const libc::c_char = unsafe { (*data).set.ssl.cert_type }; + let ssl_cafile: *const libc::c_char = if !ca_info_blob.is_null() { + 0 as *mut libc::c_char + } else { + unsafe { (*conn).ssl_config.CAfile } + }; + let ssl_capath: *const libc::c_char = unsafe { (*conn).ssl_config.CApath }; + let verifypeer: bool = unsafe { ((*conn).ssl_config).verifypeer() } != 0; + let ssl_crlfile: *const libc::c_char = unsafe { (*data).set.ssl.CRLfile }; /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ + let mut error_buffer: [libc::c_char; 256] = [0; 256]; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut imported_native_ca: bool = 0 as i32 != 0; + /* Make funny stuff to get random input */ + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ssl_connect_1 as u32 == unsafe { (*connssl).connecting_state as u32 } { + } else { + unsafe { + __assert_fail( + b"ssl_connect_1 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 2628 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + result = ossl_seed(data); + if result as u64 != 0 { + return result; + } + unsafe { + (*data).set.ssl.certverifyresult = (0 as i32 == 0) as i64; + } + /* check to see if we've been told to use an explicit SSL/TLS version */ + match ssl_version { + 0 | 1 | 4 | 5 | 6 | 7 => { + req_method = unsafe { TLS_client_method() }; /* it will be handled later with the context options */ + sni = 1 as i32 != 0; + } + 2 => { + unsafe { + Curl_failf( + data, + b"No SSLv2 support\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_NOT_BUILT_IN; + } + 3 => { + unsafe { + Curl_failf( + data, + b"No SSLv3 support\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_NOT_BUILT_IN; + } + _ => { + unsafe { + Curl_failf( + data, + b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 + as *const libc::c_char, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if unsafe { ((*backend).ctx).is_null() } { + } else { + unsafe { + __assert_fail( + b"!backend->ctx\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 2665 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + unsafe { + (*backend).ctx = SSL_CTX_new(req_method); + if ((*backend).ctx).is_null() { + Curl_failf( + data, + b"SSL: couldn't create a context: %s\0" as *const u8 as *const libc::c_char, + ossl_strerror( + ERR_peek_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return CURLE_OUT_OF_MEMORY; + } + SSL_CTX_ctrl( + (*backend).ctx, + 33 as i32, + 0x10 as i64, + 0 as *mut libc::c_void, + ); + if ((*data).set.fdebug).is_some() && ((*data).set).verbose() as i32 != 0 { + /* the SSL trace callback is only used for verbose logging */ + SSL_CTX_set_msg_callback( + (*backend).ctx, + Some( + ossl_trace + as unsafe extern "C" fn( + i32, + i32, + i32, + *const libc::c_void, + size_t, + *mut SSL, + *mut libc::c_void, + ) -> (), + ), + ); + SSL_CTX_ctrl( + (*backend).ctx, + 16 as i32, + 0 as i64, + conn as *mut libc::c_void, + ); + (*(*conn).ssl[0 as usize].backend).logger = data; + } + } + /* OpenSSL contains code to work around lots of bugs and flaws in various + SSL-implementations. SSL_CTX_set_options() is used to enabled those + work-arounds. The man page for this option states that SSL_OP_ALL enables + all the work-arounds and that "It is usually safe to use SSL_OP_ALL to + enable the bug workaround options if compatibility with somewhat broken + implementations is desired." + + The "-no_ticket" option was introduced in OpenSSL 0.9.8j. It's a flag to + disable "rfc4507bis session ticket support". rfc4507bis was later turned + into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077 + + The enabled extension concerns the session management. I wonder how often + libcurl stops a connection and then resumes a TLS session. Also, sending + the session data is some overhead. I suggest that you just use your + proposed patch (which explicitly disables TICKET). + + If someone writes an application with libcurl and OpenSSL who wants to + enable the feature, one can do this in the SSL callback. + + SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper + interoperability with web server Netscape Enterprise Server 2.0.1 which + was released back in 1996. + + Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has + become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate + CVE-2010-4180 when using previous OpenSSL versions we no longer enable + this option regardless of OpenSSL version and SSL_OP_ALL definition. + + OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability + (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to + SSL_OP_ALL that _disables_ that work-around despite the fact that + SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to + keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit + must not be set. + */ + ctx_options = + (0x80000000 as u32 | 0x800 as u32 | 0x4 as u32 | 0x10 as u32 | 0x40 as u32) as ctx_option_t; + ctx_options |= 0x4000 as i64; + ctx_options |= 0x20000 as i64; + ctx_options &= !(0 as i32) as i64; + if unsafe { ((*data).set.ssl).enable_beast() == 0 } { + ctx_options &= !(0x800 as u32) as i64; + } + let mut current_block_41: u64; + match ssl_version { + 2 | 3 => return CURLE_NOT_BUILT_IN, + 0 | 1 => { + current_block_41 = 14687600604451543688; + } + 4 => { + current_block_41 = 14687600604451543688; + } + 5 => { + current_block_41 = 9382186424990608957; + } + 6 | 7 => { + current_block_41 = 4869852262838046136; + } + _ => { + unsafe { + Curl_failf( + data, + b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 + as *const libc::c_char, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + } + match current_block_41 { + 14687600604451543688 => { + current_block_41 = 9382186424990608957; + } + _ => {} + } + match current_block_41 { + 9382186424990608957 => {} + _ => {} + } + /* asking for any TLS version as the minimum, means no SSL versions + allowed */ + ctx_options |= 0 as i64; + ctx_options |= 0x2000000 as i64; + result = unsafe { set_ssl_version_min_max((*backend).ctx, conn) }; + if result as u32 != CURLE_OK as u32 { + return result; + } + unsafe { + SSL_CTX_set_options((*backend).ctx, ctx_options as u64); + + // ************************************************************************ + #[cfg(HAS_NPN)] + if ((*conn).bits).tls_enable_npn() != 0 { + SSL_CTX_set_next_proto_select_cb( + (*backend).ctx, + Some( + select_next_proto_cb + as unsafe extern "C" fn( + *mut SSL, + *mut *mut u8, + *mut u8, + *const u8, + u32, + *mut libc::c_void, + ) -> i32, + ), + data as *mut libc::c_void, + ); + } + } + #[cfg(HAS_APLN)] + if unsafe { ((*conn).bits).tls_enable_alpn() != 0 } { + let mut cur: i32 = 0 as i32; + let mut protocols: [u8; 128] = [0; 128]; + if cfg!(USE_HTTP2) { + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let CURL_DISABLE_PROXY_flag_1 = (!(CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32) + || ((*conn).bits).tunnel_proxy() == 0); + #[cfg(CURL_DISABLE_PROXY)] + let CURL_DISABLE_PROXY_flag_1 = true; + if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 + && CURL_DISABLE_PROXY_flag_1 + { + let fresh10 = cur; + cur = cur + 1; + protocols[fresh10 as usize] = 2 as u8; + memcpy( + &mut *protocols.as_mut_ptr().offset(cur as isize) as *mut u8 + as *mut libc::c_void, + b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, + 2 as u64, + ); + cur += 2 as i32; + Curl_infof( + data, + b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, + b"h2\0" as *const u8 as *const libc::c_char, + ); + } + } + } + let fresh11 = cur; + cur = cur + 1; + protocols[fresh11 as usize] = 8 as u8; + unsafe { + memcpy( + &mut *protocols.as_mut_ptr().offset(cur as isize) as *mut u8 as *mut libc::c_void, + b"http/1.1\0" as *const u8 as *const libc::c_char as *const libc::c_void, + 8 as u64, + ); + } + cur += 8 as i32; + unsafe { + Curl_infof( + data, + b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, + b"http/1.1\0" as *const u8 as *const libc::c_char, + ); + } + /* expects length prefixed preference ordered list of protocols in wire + * format + */ + if unsafe { SSL_CTX_set_alpn_protos((*backend).ctx, protocols.as_mut_ptr(), cur as u32) } + != 0 + { + unsafe { + Curl_failf( + data, + b"Error setting ALPN\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + } + + if !ssl_cert.is_null() || !ssl_cert_blob.is_null() || !ssl_cert_type.is_null() { + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let cert_stuff_flag = cert_stuff( + data, + (*backend).ctx, + ssl_cert, + ssl_cert_blob, + ssl_cert_type, + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key + } else { + (*data).set.ssl.key + }), + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key_blob + } else { + (*data).set.ssl.key_blob + }), + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key_type + } else { + (*data).set.ssl.key_type + }), + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key_passwd + } else { + (*data).set.ssl.key_passwd + }), + ); + #[cfg(CURL_DISABLE_PROXY)] + let cert_stuff_flag = cert_stuff( + data, + (*backend).ctx, + ssl_cert, + ssl_cert_blob, + ssl_cert_type, + (*data).set.ssl.key, + (*data).set.ssl.key_blob, + (*data).set.ssl.key_type, + (*data).set.ssl.key_passwd, + ); + if result as u64 == 0 && cert_stuff_flag == 0 { + result = CURLE_SSL_CERTPROBLEM; + } + if result as u64 != 0 { + /* failf() is already done in cert_stuff() */ + return result; + } + } + } + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_cipher_list = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.cipher_list + } else { + (*conn).ssl_config.cipher_list + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_cipher_list = (*conn).ssl_config.cipher_list; + ciphers = SSL_CONN_CONFIG_cipher_list; + if ciphers.is_null() { + ciphers = 0 as *mut libc::c_char; + } + if !ciphers.is_null() { + if SSL_CTX_set_cipher_list((*backend).ctx, ciphers) == 0 { + Curl_failf( + data, + b"failed setting cipher list: %s\0" as *const u8 as *const libc::c_char, + ciphers, + ); + return CURLE_SSL_CIPHER; + } + Curl_infof( + data, + b"Cipher selection: %s\0" as *const u8 as *const libc::c_char, + ciphers, + ); + } + + // *************************************************************** + #[cfg(all(HAVE_SSL_CTX_SET_CIPHERSUITES, not(CURL_DISABLE_PROXY)))] + let mut ciphers13: *mut libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.cipher_list13 + } else { + (*conn).ssl_config.cipher_list13 + }; + + #[cfg(all(HAVE_SSL_CTX_SET_CIPHERSUITES, CURL_DISABLE_PROXY))] + let mut ciphers13: *mut libc::c_char = (*conn).ssl_config.cipher_list13; + #[cfg(HAVE_SSL_CTX_SET_CIPHERSUITES)] + if !ciphers13.is_null() { + if SSL_CTX_set_ciphersuites((*backend).ctx, ciphers13) == 0 { + Curl_failf( + data, + b"failed setting TLS 1.3 cipher suite: %s\0" as *const u8 + as *const libc::c_char, + ciphers13, + ); + return CURLE_SSL_CIPHER; + } + Curl_infof( + data, + b"TLS 1.3 cipher selection: %s\0" as *const u8 as *const libc::c_char, + ciphers13, + ); + } + /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ + #[cfg(HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH)] + SSL_CTX_set_post_handshake_auth((*backend).ctx, 1 as i32); + #[cfg(all(HAVE_SSL_CTX_SET_EC_CURVES, not(CURL_DISABLE_PROXY)))] + let mut curves: *mut libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.curves + } else { + (*conn).ssl_config.curves + }; + #[cfg(all(HAVE_SSL_CTX_SET_EC_CURVES, CURL_DISABLE_PROXY))] + let mut curves: *mut libc::c_char = (*conn).ssl_config.curves; + #[cfg(HAVE_SSL_CTX_SET_EC_CURVES)] + if !curves.is_null() { + if SSL_CTX_ctrl( + (*backend).ctx, + 92 as i32, + 0 as i64, + curves as *mut libc::c_void, + ) == 0 + { + Curl_failf( + data, + b"failed setting curves list: '%s'\0" as *const u8 as *const libc::c_char, + curves, + ); + return CURLE_SSL_CIPHER; + } + } + // #[cfg(USE_OPENSSL_SRP)] + if ssl_authtype as u32 == CURL_TLSAUTH_SRP as u32 { + #[cfg(not(CURL_DISABLE_PROXY))] + let ssl_username: *mut libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }; + #[cfg(CURL_DISABLE_PROXY)] + let ssl_username: *mut libc::c_char = (*data).set.ssl.username; + Curl_infof( + data, + b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, + ssl_username, + ); + if SSL_CTX_set_srp_username((*backend).ctx, ssl_username) == 0 { + Curl_failf( + data, + b"Unable to set SRP user name\0" as *const u8 as *const libc::c_char, + ); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + #[cfg(not(CURL_DISABLE_PROXY))] + if SSL_CTX_set_srp_password( + (*backend).ctx, + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.password + } else { + (*data).set.ssl.password + }), + ) == 0 + { + Curl_failf( + data, + b"failed setting SRP password\0" as *const u8 as *const libc::c_char, + ); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + #[cfg(CURL_DISABLE_PROXY)] + if SSL_CTX_set_srp_password((*backend).ctx, (*data).set.ssl.password) == 0 { + Curl_failf( + data, + b"failed setting SRP password\0" as *const u8 as *const libc::c_char, + ); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + #[cfg(not(CURL_DISABLE_PROXY))] + if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.cipher_list + } else { + (*conn).ssl_config.cipher_list + } + .is_null() + { + Curl_infof( + data, + b"Setting cipher list SRP\0" as *const u8 as *const libc::c_char, + ); + if SSL_CTX_set_cipher_list( + (*backend).ctx, + b"SRP\0" as *const u8 as *const libc::c_char, + ) == 0 + { + Curl_failf( + data, + b"failed setting SRP cipher list\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CIPHER; + } + } + #[cfg(CURL_DISABLE_PROXY)] + if ((*conn).ssl_config.cipher_list).is_null() { + Curl_infof( + data, + b"Setting cipher list SRP\0" as *const u8 as *const libc::c_char, + ); + if SSL_CTX_set_cipher_list( + (*backend).ctx, + b"SRP\0" as *const u8 as *const libc::c_char, + ) == 0 + { + Curl_failf( + data, + b"failed setting SRP cipher list\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CIPHER; + } + } + } + } + if !ca_info_blob.is_null() { + result = unsafe { load_cacert_from_memory((*backend).ctx, ca_info_blob) }; + if result as u64 != 0 { + if result as u32 == CURLE_OUT_OF_MEMORY as u32 + || verifypeer as i32 != 0 && !imported_native_ca + { + /* Fail if we insist on successfully verifying the server. */ + unsafe { + Curl_failf( + data, + b"error importing CA certificate blob\0" as *const u8 + as *const libc::c_char, + ); + } + return result; + } + /* Continue with warning if certificate verification isn't required. */ + unsafe { + Curl_infof( + data, + b"error importing CA certificate blob, continuing anyway\0" as *const u8 + as *const libc::c_char, + ); + } + } + } + if !ssl_cafile.is_null() || !ssl_capath.is_null() { + /* tell SSL where to find CA certificates that are used to verify + the server's certificate. */ + if unsafe { SSL_CTX_load_verify_locations((*backend).ctx, ssl_cafile, ssl_capath) } == 0 { + if verifypeer as i32 != 0 && !imported_native_ca { + /* Fail if we insist on successfully verifying the server. */ + unsafe { + Curl_failf( + data, + b"error setting certificate verify locations: CAfile: %s CApath: %s\0" + as *const u8 as *const libc::c_char, + if !ssl_cafile.is_null() { + ssl_cafile + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + if !ssl_capath.is_null() { + ssl_capath + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + } + return CURLE_SSL_CACERT_BADFILE; + } + /* Just continue with a warning if no strict certificate verification + is required. */ + unsafe { + Curl_infof( + data, + b"error setting certificate verify locations, continuing anyway:\0" as *const u8 + as *const libc::c_char, + ); + } + } else { + /* Everything is fine. */ + unsafe { + Curl_infof( + data, + b"successfully set certificate verify locations:\0" as *const u8 + as *const libc::c_char, + ); + } + } + unsafe { + Curl_infof( + data, + b" CAfile: %s\0" as *const u8 as *const libc::c_char, + if !ssl_cafile.is_null() { + ssl_cafile + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + Curl_infof( + data, + b" CApath: %s\0" as *const u8 as *const libc::c_char, + if !ssl_capath.is_null() { + ssl_capath + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + } + } + + if !ssl_crlfile.is_null() { + /* tell OpenSSL where to find CRL file that is used to check certificate + * revocation */ + lookup = unsafe { + X509_STORE_add_lookup(SSL_CTX_get_cert_store((*backend).ctx), X509_LOOKUP_file()) + }; + if lookup.is_null() || unsafe { X509_load_crl_file(lookup, ssl_crlfile, 1 as i32) } == 0 { + unsafe { + Curl_failf( + data, + b"error loading CRL file: %s\0" as *const u8 as *const libc::c_char, + ssl_crlfile, + ); + } + return CURLE_SSL_CRL_BADFILE; + } + /* Everything is fine. */ + unsafe { + Curl_infof( + data, + b"successfully loaded CRL file:\0" as *const u8 as *const libc::c_char, + ); + X509_STORE_set_flags( + SSL_CTX_get_cert_store((*backend).ctx), + (0x4 as i32 | 0x8 as i32) as u64, + ); + Curl_infof( + data, + b" CRLfile: %s\0" as *const u8 as *const libc::c_char, + ssl_crlfile, + ); + } + } + if verifypeer { + /* Try building a chain using issuers in the trusted store first to avoid + problems with server-sent legacy intermediates. Newer versions of + OpenSSL do alternate chain checking by default but we do not know how to + determine that in a reliable manner. + https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest */ - SSL_CTX_sess_set_new_cb( - (*backend).ctx, - Some(ossl_new_session_cb as unsafe extern "C" fn(*mut SSL, *mut SSL_SESSION) -> i32), - ); - /* give application a chance to interfere with SSL set up. */ - if ((*data).set.ssl.fsslctx).is_some() { - Curl_set_in_callback(data, 1 as i32 != 0); - result = (Some(((*data).set.ssl.fsslctx).expect("non-null function pointer"))) - .expect("non-null function pointer")( - data, - (*backend).ctx as *mut libc::c_void, - (*data).set.ssl.fsslctxp, - ); - Curl_set_in_callback(data, 0 as i32 != 0); - if result as u64 != 0 { - Curl_failf( - data, - b"error signaled by ssl ctx callback\0" as *const u8 as *const libc::c_char, - ); - return result; - } - } - /* Let's make an SSL structure */ - if !((*backend).handle).is_null() { - SSL_free((*backend).handle); - } - (*backend).handle = SSL_new((*backend).ctx); - if ((*backend).handle).is_null() { - Curl_failf( - data, - b"SSL: couldn't create a context (handle)!\0" as *const u8 as *const libc::c_char, - ); - return CURLE_OUT_OF_MEMORY; - } - if ((*conn).ssl_config).verifystatus() != 0 { - SSL_ctrl( - (*backend).handle, - 65 as i32, - 1 as i64, - 0 as *mut libc::c_void, - ); - } - SSL_set_connect_state((*backend).handle); - (*backend).server_cert = 0 as *mut X509; - if 0 as i32 - == inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in_addr as *mut libc::c_void, - ) - && sni as i32 != 0 - { - let mut nlen: size_t = strlen(hostname); - if nlen as i64 >= (*data).set.buffer_size { - /* this is seriously messed up */ - return CURLE_SSL_CONNECT_ERROR; - } - /* RFC 6066 section 3 says the SNI field is case insensitive, but browsers - send the data lowercase and subsequently there are now numerous servers - out there that don't work unless the name is lowercased */ - Curl_strntolower((*data).state.buffer, hostname, nlen); - *((*data).state.buffer).offset(nlen as isize) = 0 as libc::c_char; - if SSL_ctrl( - (*backend).handle, - 55 as i32, - 0 as i64, - (*data).state.buffer as *mut libc::c_void, - ) == 0 - { - /* Informational message */ - Curl_infof( - data, - b"WARNING: failed to configure server name indication (SNI) TLS extension\0" - as *const u8 as *const libc::c_char, - ); - } - } - } + unsafe { + X509_STORE_set_flags(SSL_CTX_get_cert_store((*backend).ctx), 0x8000 as u64); + if ((*data).set.ssl).no_partialchain() == 0 && ssl_crlfile.is_null() { + /* Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert + only, instead of needing the whole chain. + + Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we + cannot do partial chains with a CRL check. + */ + X509_STORE_set_flags(SSL_CTX_get_cert_store((*backend).ctx), 0x80000 as u64); + } + } + } + /* OpenSSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue + * anyway. In the latter case the result of the verification is checked with + * SSL_get_verify_result() below. */ + unsafe { + SSL_CTX_set_verify( + (*backend).ctx, + if verifypeer as i32 != 0 { + 0x1 as i32 + } else { + 0 as i32 + }, + None, + ); + /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ + #[cfg(HAVE_KEYLOG_CALLBACK)] + if Curl_tls_keylog_enabled() { + SSL_CTX_set_keylog_callback( + (*backend).ctx, + Some( + ossl_keylog_callback + as unsafe extern "C" fn(*const SSL, *const libc::c_char) -> (), + ), + ); + } + SSL_CTX_ctrl( + (*backend).ctx, + 44 as i32, + (0x1 as i32 | (0x100 as i32 | 0x200 as i32)) as i64, + 0 as *mut libc::c_void, + ); + /* Enable the session cache because it's a prerequisite for the "new session" + * callback. Use the "external storage" mode to prevent OpenSSL from creating + * an internal session cache. + */ + SSL_CTX_sess_set_new_cb( + (*backend).ctx, + Some(ossl_new_session_cb as unsafe extern "C" fn(*mut SSL, *mut SSL_SESSION) -> i32), + ); + /* give application a chance to interfere with SSL set up. */ + if ((*data).set.ssl.fsslctx).is_some() { + Curl_set_in_callback(data, 1 as i32 != 0); + result = (Some(((*data).set.ssl.fsslctx).expect("non-null function pointer"))) + .expect("non-null function pointer")( + data, + (*backend).ctx as *mut libc::c_void, + (*data).set.ssl.fsslctxp, + ); + Curl_set_in_callback(data, 0 as i32 != 0); + if result as u64 != 0 { + Curl_failf( + data, + b"error signaled by ssl ctx callback\0" as *const u8 as *const libc::c_char, + ); + return result; + } + } + /* Let's make an SSL structure */ + if !((*backend).handle).is_null() { + SSL_free((*backend).handle); + } + (*backend).handle = SSL_new((*backend).ctx); + if ((*backend).handle).is_null() { + Curl_failf( + data, + b"SSL: couldn't create a context (handle)!\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OUT_OF_MEMORY; + } + if ((*conn).ssl_config).verifystatus() != 0 { + SSL_ctrl( + (*backend).handle, + 65 as i32, + 1 as i64, + 0 as *mut libc::c_void, + ); + } + SSL_set_connect_state((*backend).handle); + (*backend).server_cert = 0 as *mut X509; + if 0 as i32 + == inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in_addr as *mut libc::c_void, + ) + && sni as i32 != 0 + { + let mut nlen: size_t = strlen(hostname); + if nlen as i64 >= (*data).set.buffer_size { + /* this is seriously messed up */ + return CURLE_SSL_CONNECT_ERROR; + } + /* RFC 6066 section 3 says the SNI field is case insensitive, but browsers + send the data lowercase and subsequently there are now numerous servers + out there that don't work unless the name is lowercased */ + Curl_strntolower((*data).state.buffer, hostname, nlen); + *((*data).state.buffer).offset(nlen as isize) = 0 as libc::c_char; + if SSL_ctrl( + (*backend).handle, + 55 as i32, + 0 as i64, + (*data).state.buffer as *mut libc::c_void, + ) == 0 + { + /* Informational message */ + Curl_infof( + data, + b"WARNING: failed to configure server name indication (SNI) TLS extension\0" + as *const u8 as *const libc::c_char, + ); + } + } + } + + ossl_associate_connection(data, conn, sockindex); + Curl_ssl_sessionid_lock(data); + if !Curl_ssl_getsessionid( + data, + conn, + if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0, + &mut ssl_sessionid, + 0 as *mut size_t, + sockindex, + ) { + unsafe { + /* we got a session id, use it! */ + if SSL_set_session((*backend).handle, ssl_sessionid as *mut SSL_SESSION) == 0 { + Curl_ssl_sessionid_unlock(data); + /* pass the raw socket into the SSL layers */ + Curl_failf( + data, + b"SSL: SSL_set_session failed: %s\0" as *const u8 as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + Curl_infof( + data, + b"SSL re-using session ID\0" as *const u8 as *const libc::c_char, + ); + } + } + Curl_ssl_sessionid_unlock(data); + #[cfg(not(CURL_DISABLE_PROXY))] + if unsafe { ((*conn).proxy_ssl[sockindex as usize]).use_0() } != 0 { + let bio: *mut BIO = unsafe { BIO_new(BIO_f_ssl()) }; + let mut handle: *mut SSL = + unsafe { (*(*conn).proxy_ssl[sockindex as usize].backend).handle }; + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ssl_connection_complete as u32 == (*conn).proxy_ssl[sockindex as usize].state as u32 + { + } else { + __assert_fail( + b"ssl_connection_complete == conn->proxy_ssl[sockindex].state\0" as *const u8 + as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 3264 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !handle.is_null() { + } else { + __assert_fail( + b"handle != ((void*)0)\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 3265 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !bio.is_null() { + } else { + __assert_fail( + b"bio != ((void*)0)\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 3266 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + BIO_ctrl(bio, 109 as i32, 0 as i64, handle as *mut libc::c_void); + SSL_set_bio((*backend).handle, bio, bio); + } + } else if unsafe { SSL_set_fd((*backend).handle, sockfd) == 0 } { + unsafe { + Curl_failf( + data, + b"SSL: SSL_set_fd failed: %s\0" as *const u8 as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + return CURLE_SSL_CONNECT_ERROR; + } - ossl_associate_connection(data, conn, sockindex); - Curl_ssl_sessionid_lock(data); - if !Curl_ssl_getsessionid( - data, - conn, - if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0, - &mut ssl_sessionid, - 0 as *mut size_t, - sockindex, - ) { - unsafe { - /* we got a session id, use it! */ - if SSL_set_session((*backend).handle, ssl_sessionid as *mut SSL_SESSION) == 0 { - Curl_ssl_sessionid_unlock(data); - /* pass the raw socket into the SSL layers */ - Curl_failf( - data, - b"SSL: SSL_set_session failed: %s\0" as *const u8 as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return CURLE_SSL_CONNECT_ERROR; - } - /* Informational message */ - Curl_infof( - data, - b"SSL re-using session ID\0" as *const u8 as *const libc::c_char, - ); - } - } - Curl_ssl_sessionid_unlock(data); - if unsafe { ((*conn).proxy_ssl[sockindex as usize]).use_0() } != 0 { - let bio: *mut BIO = unsafe { BIO_new(BIO_f_ssl()) }; - let mut handle: *mut SSL = - unsafe { (*(*conn).proxy_ssl[sockindex as usize].backend).handle }; - unsafe { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ssl_connection_complete as u32 == (*conn).proxy_ssl[sockindex as usize].state as u32 - { - } else { - __assert_fail( - b"ssl_connection_complete == conn->proxy_ssl[sockindex].state\0" as *const u8 - as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 3264 as u32, - (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( - b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !handle.is_null() { - } else { - __assert_fail( - b"handle != ((void*)0)\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 3265 as u32, - (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( - b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !bio.is_null() { - } else { - __assert_fail( - b"bio != ((void*)0)\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 3266 as u32, - (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( - b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - BIO_ctrl(bio, 109 as i32, 0 as i64, handle as *mut libc::c_void); - SSL_set_bio((*backend).handle, bio, bio); - } - } else if unsafe { SSL_set_fd((*backend).handle, sockfd) == 0 } { - unsafe { + unsafe { + #[cfg(CURL_DISABLE_PROXY)] + if SSL_set_fd((*backend).handle, sockfd) == 0 { + /* pass the raw socket into the SSL layers */ Curl_failf( data, b"SSL: SSL_set_fd failed: %s\0" as *const u8 as *const libc::c_char, @@ -4031,2474 +4049,2473 @@ extern "C" fn ossl_connect_step1( ::std::mem::size_of::<[libc::c_char; 256]>() as u64, ), ); - } return CURLE_SSL_CONNECT_ERROR; } - unsafe { - (*connssl).connecting_state = ssl_connect_2; - } - return CURLE_OK; -} - -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_connect_step2( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) -> CURLcode { - let mut err: i32 = 0; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } - as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - unsafe { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ssl_connect_2 as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 - { - } else { - __assert_fail( - b"ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state || ssl_connect_2_writing == connssl->connecting_state\0" - as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 3292 as u32, - (*::std::mem::transmute::< - &[u8; 75], - &[libc::c_char; 75], - >( - b"CURLcode ossl_connect_step2(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), + (*connssl).connecting_state = ssl_connect_2; + } + return CURLE_OK; + } + + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_connect_step2( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) -> CURLcode { + let mut err: i32 = 0; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } + as *mut ssl_connect_data; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ssl_connect_2 as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 + { + } else { + __assert_fail( + b"ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state || ssl_connect_2_writing == connssl->connecting_state\0" + as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 3292 as u32, + (*::std::mem::transmute::< + &[u8; 75], + &[libc::c_char; 75], + >( + b"CURLcode ossl_connect_step2(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + ERR_clear_error(); + + err = SSL_connect((*backend).handle); + } + /* 1 is fine + 0 is "not successful but was shut down controlled" + <0 is "handshake was not successful, because a fatal error occurred" */ + // TODO + // #[cfg(HAVE_KEYLOG_CALLBACK)] + if 1 as i32 != err { + let mut detail: i32 = unsafe { SSL_get_error((*backend).handle, err) }; + if 2 as i32 == detail { + unsafe { + (*connssl).connecting_state = ssl_connect_2_reading; + } + return CURLE_OK; + } + if 3 as i32 == detail { + unsafe { + (*connssl).connecting_state = ssl_connect_2_writing; + } + return CURLE_OK; + } + // TODO if的条件编译 + #[cfg(SSL_ERROR_WANT_ASYNC)] + let SSL_ERROR_WANT_ASYNC_flag_3 = true; + #[cfg(not(SSL_ERROR_WANT_ASYNC))] + let SSL_ERROR_WANT_ASYNC_flag_3 = false; + if 9 as i32 == detail && SSL_ERROR_WANT_ASYNC_flag_3 { + unsafe { + (*connssl).connecting_state = ssl_connect_2; + } + return CURLE_OK; + } else { + /* untreated error */ + let mut errdetail: u64 = 0; + let mut error_buffer: [libc::c_char; 256] = unsafe { + *::std::mem::transmute::< + &[u8; 256], + &mut [libc::c_char; 256], + >( + b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + ) + }; + let mut result: CURLcode = CURLE_OK; + let mut lerr: i64 = 0; + let mut lib: i32 = 0; + let mut reason: i32 = 0; + /* the connection failed, we're not waiting for anything else. */ + unsafe { + (*connssl).connecting_state = ssl_connect_2; + } + /* Get the earliest error code from the thread's error queue and remove + the entry. */ + errdetail = unsafe { ERR_get_error() }; + /* Extract which lib and reason */ + lib = (errdetail >> 24 as i64 & 0xff as i64 as u64) as i32; + reason = (errdetail & 0xfff as u64) as i32; + if lib == 20 as i32 && (reason == 134 as i32 || reason == 1045 as i32) { + result = CURLE_PEER_FAILED_VERIFICATION; + lerr = unsafe { SSL_get_verify_result((*backend).handle) }; + if lerr != 0 as i64 { + #[cfg(not(CURL_DISABLE_PROXY))] + if true { + *if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) + as usize] + .state as u32 + } + { + unsafe { &mut (*data).set.proxy_ssl.certverifyresult } + } else { + unsafe { &mut (*data).set.ssl.certverifyresult } + } = lerr; + } + #[cfg(CURL_DISABLE_PROXY)] + if true { + unsafe { + (*data).set.ssl.certverifyresult = lerr; + } + } + unsafe { + curl_msnprintf( + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + b"SSL certificate problem: %s\0" as *const u8 as *const libc::c_char, + X509_verify_cert_error_string(lerr), + ); + } + } else { + /* strcpy() is fine here as long as the string fits within + error_buffer */ + unsafe { + strcpy( + error_buffer.as_mut_ptr(), + b"SSL certificate verification failed\0" as *const u8 + as *const libc::c_char, + ); + } + } + // else if的条件编译 + /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on + OpenSSL version above v1.1.1, not LibreSSL nor BoringSSL */ + } else if lib == 20 as i32 && reason == 1116 as i32 { + /* If client certificate is required, communicate the + error to client */ + result = CURLE_SSL_CLIENTCERT; + ossl_strerror( + errdetail, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } else { + result = CURLE_SSL_CONNECT_ERROR; + ossl_strerror( + errdetail, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + /* detail is already set to the SSL error above */ + + /* If we e.g. use SSLv2 request-method and the server doesn't like us + * (RST connection, etc.), OpenSSL gives no explanation whatsoever and + * the SO_ERROR is also lost. + */ + if CURLE_SSL_CONNECT_ERROR as u32 == result as u32 && errdetail == 0 as u64 { + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).http_proxy.host.name + } else { + (*conn).host.name + }; + #[cfg(CURL_DISABLE_PROXY)] + let hostname: *const libc::c_char = (*conn).host.name; + #[cfg(not(CURL_DISABLE_PROXY))] + let port: i64 = (if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).port + } else { + (*conn).remote_port + }) as i64; + #[cfg(CURL_DISABLE_PROXY)] + let port: i64 = (*conn).remote_port as i64; + let mut extramsg: [libc::c_char; 80] = *::std::mem::transmute::< + &[u8; 80], + &mut [libc::c_char; 80], + >( + b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + ); + let mut sockerr: i32 = *__errno_location(); + if sockerr != 0 && detail == 5 as i32 { + Curl_strerror( + sockerr, + extramsg.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 80]>() as u64, + ); + } + Curl_failf( + data, + b"OpenSSL SSL_connect: %s in connection to %s:%ld \0" as *const u8 + as *const libc::c_char, + if extramsg[0 as usize] as i32 != 0 { + extramsg.as_mut_ptr() as *const libc::c_char + } else { + SSL_ERROR_to_str(detail) + }, + hostname, + port, + ); + } + return result; + } + /* Could be a CERT problem */ + unsafe { + Curl_failf( + data, + b"%s\0" as *const u8 as *const libc::c_char, + error_buffer.as_mut_ptr(), + ); + } + return result; + } + } else { + unsafe { + /* we connected fine, we're not waiting for anything else. */ + (*connssl).connecting_state = ssl_connect_3; + /* Informational message */ + Curl_infof( + data, + b"SSL connection using %s / %s\0" as *const u8 as *const libc::c_char, + SSL_get_version((*backend).handle), + SSL_CIPHER_get_name(SSL_get_current_cipher((*backend).handle)), + ); + /* Sets data and len to negotiated protocol, len is 0 if no protocol was + * negotiated + */ + #[cfg(HAS_APLN)] + if ((*conn).bits).tls_enable_alpn() != 0 { + let mut neg_protocol: *const u8 = 0 as *const u8; + let mut len: u32 = 0; + SSL_get0_alpn_selected((*backend).handle, &mut neg_protocol, &mut len); + if len != 0 { + Curl_infof( + data, + b"ALPN, server accepted to use %.*s\0" as *const u8 as *const libc::c_char, + len, + neg_protocol, + ); + // TODO if的条件编译 + #[cfg(USE_HTTP2)] + let USE_HTTP2_flag = true; + #[cfg(not(USE_HTTP2))] + let USE_HTTP2_flag = false; + if len == 2 as u32 + && USE_HTTP2_flag + && memcmp( + b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, + neg_protocol as *const libc::c_void, + len as u64, + ) == 0 + { + (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; + } else if len == 8 as u32 + && memcmp( + b"http/1.1\0" as *const u8 as *const libc::c_char + as *const libc::c_void, + neg_protocol as *const libc::c_void, + 8 as u64, + ) == 0 + { + (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; + } + } else { + Curl_infof( + data, + b"ALPN, server did not agree to a protocol\0" as *const u8 + as *const libc::c_char, + ); + } + Curl_multiuse_state( + data, + if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as i32 { + 2 as i32 + } else { + -(1 as i32) + }, + ); + } + } + return CURLE_OK; + }; + } + + #[cfg(USE_OPENSSL)] + extern "C" fn asn1_object_dump( + mut a: *mut ASN1_OBJECT, + mut buf: *mut libc::c_char, + mut len: size_t, + ) -> i32 { + let mut i: i32 = 0; + let mut ilen: i32 = 0; + ilen = len as i32; + if ilen < 0 as i32 { + return 1 as i32; /* buffer too big */ + } + i = unsafe { i2t_ASN1_OBJECT(buf, ilen, a) }; + if i >= ilen { + return 1 as i32; /* buffer too small */ + } + return 0 as i32; + } + // TODO-3474-参数列表有条件编译 + #[cfg(all(USE_OPENSSL, HAVE_OPAQUE_RSA_DSA_DH))] + extern "C" fn pubkey_show( + mut data: *mut Curl_easy, + mut mem: *mut BIO, + mut num: i32, + mut type_0: *const libc::c_char, + mut name: *const libc::c_char, + mut bn: *const BIGNUM, + ) { + let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut namebuf: [libc::c_char; 32] = [0; 32]; + unsafe { + curl_msnprintf( + namebuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 32]>() as u64, + b"%s(%s)\0" as *const u8 as *const libc::c_char, + type_0, + name, ); - } - ERR_clear_error(); - - err = SSL_connect((*backend).handle); - } - /* 1 is fine - 0 is "not successful but was shut down controlled" - <0 is "handshake was not successful, because a fatal error occurred" */ - // TODO - // #[cfg(HAVE_KEYLOG_CALLBACK)] - if 1 as i32 != err { - let mut detail: i32 = unsafe { SSL_get_error((*backend).handle, err) }; - if 2 as i32 == detail { - unsafe { - (*connssl).connecting_state = ssl_connect_2_reading; - } - return CURLE_OK; - } - if 3 as i32 == detail { - unsafe { - (*connssl).connecting_state = ssl_connect_2_writing; - } - return CURLE_OK; - } - // TODO if的条件编译 - #[cfg(SSL_ERROR_WANT_ASYNC)] - let SSL_ERROR_WANT_ASYNC_flag_3 = true; - #[cfg(not(SSL_ERROR_WANT_ASYNC))] - let SSL_ERROR_WANT_ASYNC_flag_3 = false; - if 9 as i32 == detail && SSL_ERROR_WANT_ASYNC_flag_3 { - unsafe { - (*connssl).connecting_state = ssl_connect_2; - } - return CURLE_OK; - } else { - /* untreated error */ - let mut errdetail: u64 = 0; - let mut error_buffer: [libc::c_char; 256] = unsafe { - *::std::mem::transmute::< - &[u8; 256], - &mut [libc::c_char; 256], - >( - b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - ) - }; - let mut result: CURLcode = CURLE_OK; - let mut lerr: i64 = 0; - let mut lib: i32 = 0; - let mut reason: i32 = 0; - /* the connection failed, we're not waiting for anything else. */ - unsafe { - (*connssl).connecting_state = ssl_connect_2; - } - /* Get the earliest error code from the thread's error queue and remove - the entry. */ - errdetail = unsafe { ERR_get_error() }; - /* Extract which lib and reason */ - lib = (errdetail >> 24 as i64 & 0xff as i64 as u64) as i32; - reason = (errdetail & 0xfff as u64) as i32; - if lib == 20 as i32 && (reason == 134 as i32 || reason == 1045 as i32) { - result = CURLE_PEER_FAILED_VERIFICATION; - lerr = unsafe { SSL_get_verify_result((*backend).handle) }; - if lerr != 0 as i64 { - #[cfg(not(CURL_DISABLE_PROXY))] - if true { - *if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) - as usize] - .state as u32 - } - { - unsafe { &mut (*data).set.proxy_ssl.certverifyresult } - } else { - unsafe { &mut (*data).set.ssl.certverifyresult } - } = lerr; - } - #[cfg(CURL_DISABLE_PROXY)] - if true { - unsafe { - (*data).set.ssl.certverifyresult = lerr; - } - } - unsafe { - curl_msnprintf( - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - b"SSL certificate problem: %s\0" as *const u8 as *const libc::c_char, - X509_verify_cert_error_string(lerr), - ); - } - } else { - /* strcpy() is fine here as long as the string fits within - error_buffer */ - unsafe { - strcpy( - error_buffer.as_mut_ptr(), - b"SSL certificate verification failed\0" as *const u8 - as *const libc::c_char, - ); - } - } - // else if的条件编译 - /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on - OpenSSL version above v1.1.1, not LibreSSL nor BoringSSL */ - } else if lib == 20 as i32 && reason == 1116 as i32 { - /* If client certificate is required, communicate the - error to client */ - result = CURLE_SSL_CLIENTCERT; - ossl_strerror( - errdetail, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } else { - result = CURLE_SSL_CONNECT_ERROR; - ossl_strerror( - errdetail, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - /* detail is already set to the SSL error above */ - - /* If we e.g. use SSLv2 request-method and the server doesn't like us - * (RST connection, etc.), OpenSSL gives no explanation whatsoever and - * the SO_ERROR is also lost. - */ - if CURLE_SSL_CONNECT_ERROR as u32 == result as u32 && errdetail == 0 as u64 { - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).http_proxy.host.name - } else { - (*conn).host.name - }; - #[cfg(CURL_DISABLE_PROXY)] - let hostname: *const libc::c_char = (*conn).host.name; - #[cfg(not(CURL_DISABLE_PROXY))] - let port: i64 = (if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).port - } else { - (*conn).remote_port - }) as i64; - #[cfg(CURL_DISABLE_PROXY)] - let port: i64 = (*conn).remote_port as i64; - let mut extramsg: [libc::c_char; 80] = *::std::mem::transmute::< - &[u8; 80], - &mut [libc::c_char; 80], - >( - b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + } + if !bn.is_null() { + unsafe { + BN_print(mem, bn); + } + } + let mut info_len: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len(data, num, namebuf.as_mut_ptr(), ptr, info_len as size_t); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + } + + #[cfg(USE_OPENSSL)] + extern "C" fn X509V3_ext( + mut data: *mut Curl_easy, + mut certnum: i32, + mut exts: *const stack_st_X509_EXTENSION, + ) { + let mut i: i32 = 0; + if sk_X509_EXTENSION_num(exts) <= 0 as i32 { + /* no extensions, bail out */ + return; + } + i = 0 as i32; + while i < sk_X509_EXTENSION_num(exts) { + let mut obj: *mut ASN1_OBJECT = 0 as *mut ASN1_OBJECT; + let mut ext: *mut X509_EXTENSION = sk_X509_EXTENSION_value(exts, i); + let mut biomem: *mut BUF_MEM = 0 as *mut BUF_MEM; + let mut namebuf: [libc::c_char; 128] = [0; 128]; + let mut bio_out: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; + if bio_out.is_null() { + return; + } + obj = unsafe { X509_EXTENSION_get_object(ext) }; + asn1_object_dump( + obj, + namebuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + if unsafe { X509V3_EXT_print(bio_out, ext, 0 as u64, 0 as i32) } == 0 { + unsafe { ASN1_STRING_print(bio_out, X509_EXTENSION_get_data(ext) as *mut ASN1_STRING) }; + } + unsafe { + BIO_ctrl( + bio_out, + 115 as i32, + 0 as i64, + &mut biomem as *mut *mut BUF_MEM as *mut libc::c_char as *mut libc::c_void, + ); + Curl_ssl_push_certinfo_len( + data, + certnum, + namebuf.as_mut_ptr(), + (*biomem).data, + (*biomem).length, + ); + BIO_free(bio_out); + } + i += 1; + } + } + + #[cfg(USE_OPENSSL)] + extern "C" fn get_cert_chain( + mut data: *mut Curl_easy, + mut connssl: *mut ssl_connect_data, + ) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut sk: *mut stack_st_X509 = 0 as *mut stack_st_X509; + let mut i: i32 = 0; + let mut numcerts: numcert_t = 0; + let mut mem: *mut BIO = 0 as *mut BIO; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + sk = unsafe { SSL_get_peer_cert_chain((*backend).handle) }; + if sk.is_null() { + return CURLE_OUT_OF_MEMORY; + } + numcerts = sk_X509_num(sk); + result = Curl_ssl_init_certinfo(data, numcerts); + if result as u64 != 0 { + return result; + } + mem = unsafe { BIO_new(BIO_s_mem()) }; + i = 0 as i32; + while i < numcerts { + let mut num: *mut ASN1_INTEGER = 0 as *mut ASN1_INTEGER; + let mut x: *mut X509 = sk_X509_value(sk, i); + let mut pubkey: *mut EVP_PKEY = 0 as *mut EVP_PKEY; + let mut j: i32 = 0; + let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut psig: *const ASN1_BIT_STRING = 0 as *const ASN1_BIT_STRING; + unsafe { + X509_NAME_print_ex( + mem, + X509_get_subject_name(x), + 0 as i32, + (1 as i32 + | 2 as i32 + | 4 as i32 + | 0x10 as i32 + | 0x100 as i32 + | 0x200 as i32 + | 8 as i32 + | (2 as i32) << 16 as i32 + | (1 as i32) << 23 as i32 + | 0 as i32) as u64, + ); + let mut info_len: i64 = BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ); + + Curl_ssl_push_certinfo_len( + data, + i, + b"Subject\0" as *const u8 as *const libc::c_char, + ptr, + info_len as size_t, + ); + } + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + unsafe { + X509_NAME_print_ex( + mem, + X509_get_issuer_name(x), + 0 as i32, + (1 as i32 + | 2 as i32 + | 4 as i32 + | 0x10 as i32 + | 0x100 as i32 + | 0x200 as i32 + | 8 as i32 + | (2 as i32) << 16 as i32 + | (1 as i32) << 23 as i32 + | 0 as i32) as u64, + ); + } + let mut info_len_0: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Issuer\0" as *const u8 as *const libc::c_char, + ptr, + info_len_0 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + unsafe { + BIO_printf( + mem, + b"%lx\0" as *const u8 as *const libc::c_char, + X509_get_version(x), + ); + } + let mut info_len_1: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Version\0" as *const u8 as *const libc::c_char, + ptr, + info_len_1 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + num = unsafe { X509_get_serialNumber(x) }; + if unsafe { (*num).type_0 } == 2 as i32 | 0x100 as i32 { + unsafe { + BIO_puts(mem, b"-\0" as *const u8 as *const libc::c_char); + } + } + j = 0 as i32; + while j < unsafe { (*num).length } { + unsafe { + BIO_printf( + mem, + b"%02x\0" as *const u8 as *const libc::c_char, + *((*num).data).offset(j as isize) as i32, + ); + } + j += 1; + } + let mut info_len_2: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Serial Number\0" as *const u8 as *const libc::c_char, + ptr, + info_len_2 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + + if cfg!(all(HAVE_X509_GET0_SIGNATURE, HAVE_X509_GET0_EXTENSIONS)) { + let mut sigalg: *const X509_ALGOR = 0 as *const X509_ALGOR; + let mut xpubkey: *mut X509_PUBKEY = 0 as *mut X509_PUBKEY; + let mut pubkeyoid: *mut ASN1_OBJECT = 0 as *mut ASN1_OBJECT; + unsafe { + X509_get0_signature(&mut psig, &mut sigalg, x); + } + if !sigalg.is_null() { + unsafe { + i2a_ASN1_OBJECT(mem, (*sigalg).algorithm); + } + let mut info_len_3: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Signature Algorithm\0" as *const u8 as *const libc::c_char, + ptr, + info_len_3 as size_t, + ); + 1 as i32 + != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + } + xpubkey = unsafe { X509_get_X509_PUBKEY(x) }; + if !xpubkey.is_null() { + unsafe { + X509_PUBKEY_get0_param( + &mut pubkeyoid, + 0 as *mut *const u8, + 0 as *mut i32, + 0 as *mut *mut X509_ALGOR, + xpubkey, ); - let mut sockerr: i32 = *__errno_location(); - if sockerr != 0 && detail == 5 as i32 { - Curl_strerror( - sockerr, - extramsg.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 80]>() as u64, - ); - } - Curl_failf( - data, - b"OpenSSL SSL_connect: %s in connection to %s:%ld \0" as *const u8 - as *const libc::c_char, - if extramsg[0 as usize] as i32 != 0 { - extramsg.as_mut_ptr() as *const libc::c_char - } else { - SSL_ERROR_to_str(detail) - }, - hostname, - port, - ); - } - return result; - } - /* Could be a CERT problem */ - unsafe { - Curl_failf( - data, - b"%s\0" as *const u8 as *const libc::c_char, - error_buffer.as_mut_ptr(), - ); - } - return result; - } - } else { - unsafe { - /* we connected fine, we're not waiting for anything else. */ - (*connssl).connecting_state = ssl_connect_3; - /* Informational message */ - Curl_infof( - data, - b"SSL connection using %s / %s\0" as *const u8 as *const libc::c_char, - SSL_get_version((*backend).handle), - SSL_CIPHER_get_name(SSL_get_current_cipher((*backend).handle)), - ); - /* Sets data and len to negotiated protocol, len is 0 if no protocol was - * negotiated - */ - #[cfg(HAS_APLN)] - if ((*conn).bits).tls_enable_alpn() != 0 { - let mut neg_protocol: *const u8 = 0 as *const u8; - let mut len: u32 = 0; - SSL_get0_alpn_selected((*backend).handle, &mut neg_protocol, &mut len); - if len != 0 { - Curl_infof( - data, - b"ALPN, server accepted to use %.*s\0" as *const u8 as *const libc::c_char, - len, - neg_protocol, - ); - // TODO if的条件编译 - #[cfg(USE_HTTP2)] - let USE_HTTP2_flag = true; - #[cfg(not(USE_HTTP2))] - let USE_HTTP2_flag = false; - if len == 2 as u32 - && USE_HTTP2_flag - && memcmp( - b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, - neg_protocol as *const libc::c_void, - len as u64, - ) == 0 - { - (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; - } else if len == 8 as u32 - && memcmp( - b"http/1.1\0" as *const u8 as *const libc::c_char - as *const libc::c_void, - neg_protocol as *const libc::c_void, - 8 as u64, - ) == 0 - { - (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; - } - } else { - Curl_infof( - data, - b"ALPN, server did not agree to a protocol\0" as *const u8 - as *const libc::c_char, - ); - } - Curl_multiuse_state( - data, - if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as i32 { - 2 as i32 - } else { - -(1 as i32) - }, - ); - } - } - return CURLE_OK; - }; -} - -#[cfg(USE_OPENSSL)] -extern "C" fn asn1_object_dump( - mut a: *mut ASN1_OBJECT, - mut buf: *mut libc::c_char, - mut len: size_t, -) -> i32 { - let mut i: i32 = 0; - let mut ilen: i32 = 0; - ilen = len as i32; - if ilen < 0 as i32 { - return 1 as i32; /* buffer too big */ - } - i = unsafe { i2t_ASN1_OBJECT(buf, ilen, a) }; - if i >= ilen { - return 1 as i32; /* buffer too small */ - } - return 0 as i32; -} -// TODO-3474-参数列表有条件编译 -#[cfg(all(USE_OPENSSL, HAVE_OPAQUE_RSA_DSA_DH))] -extern "C" fn pubkey_show( - mut data: *mut Curl_easy, - mut mem: *mut BIO, - mut num: i32, - mut type_0: *const libc::c_char, - mut name: *const libc::c_char, - mut bn: *const BIGNUM, -) { - let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; - let mut namebuf: [libc::c_char; 32] = [0; 32]; - unsafe { - curl_msnprintf( - namebuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 32]>() as u64, - b"%s(%s)\0" as *const u8 as *const libc::c_char, - type_0, - name, - ); - } - if !bn.is_null() { - unsafe { - BN_print(mem, bn); - } - } - let mut info_len: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len(data, num, namebuf.as_mut_ptr(), ptr, info_len as size_t); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; -} - -#[cfg(USE_OPENSSL)] -extern "C" fn X509V3_ext( - mut data: *mut Curl_easy, - mut certnum: i32, - mut exts: *const stack_st_X509_EXTENSION, -) { - let mut i: i32 = 0; - if sk_X509_EXTENSION_num(exts) <= 0 as i32 { - /* no extensions, bail out */ - return; - } - i = 0 as i32; - while i < sk_X509_EXTENSION_num(exts) { - let mut obj: *mut ASN1_OBJECT = 0 as *mut ASN1_OBJECT; - let mut ext: *mut X509_EXTENSION = sk_X509_EXTENSION_value(exts, i); - let mut biomem: *mut BUF_MEM = 0 as *mut BUF_MEM; - let mut namebuf: [libc::c_char; 128] = [0; 128]; - let mut bio_out: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; - if bio_out.is_null() { - return; - } - obj = unsafe { X509_EXTENSION_get_object(ext) }; - asn1_object_dump( - obj, - namebuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as u64, - ); - if unsafe { X509V3_EXT_print(bio_out, ext, 0 as u64, 0 as i32) } == 0 { - unsafe { ASN1_STRING_print(bio_out, X509_EXTENSION_get_data(ext) as *mut ASN1_STRING) }; - } - unsafe { - BIO_ctrl( - bio_out, - 115 as i32, - 0 as i64, - &mut biomem as *mut *mut BUF_MEM as *mut libc::c_char as *mut libc::c_void, - ); - Curl_ssl_push_certinfo_len( - data, - certnum, - namebuf.as_mut_ptr(), - (*biomem).data, - (*biomem).length, - ); - BIO_free(bio_out); - } - i += 1; - } -} - -#[cfg(USE_OPENSSL)] -extern "C" fn get_cert_chain( - mut data: *mut Curl_easy, - mut connssl: *mut ssl_connect_data, -) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut sk: *mut stack_st_X509 = 0 as *mut stack_st_X509; - let mut i: i32 = 0; - let mut numcerts: numcert_t = 0; - let mut mem: *mut BIO = 0 as *mut BIO; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - sk = unsafe { SSL_get_peer_cert_chain((*backend).handle) }; - if sk.is_null() { - return CURLE_OUT_OF_MEMORY; - } - numcerts = sk_X509_num(sk); - result = Curl_ssl_init_certinfo(data, numcerts); - if result as u64 != 0 { - return result; - } - mem = unsafe { BIO_new(BIO_s_mem()) }; - i = 0 as i32; - while i < numcerts { - let mut num: *mut ASN1_INTEGER = 0 as *mut ASN1_INTEGER; - let mut x: *mut X509 = sk_X509_value(sk, i); - let mut pubkey: *mut EVP_PKEY = 0 as *mut EVP_PKEY; - let mut j: i32 = 0; - let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; - let mut psig: *const ASN1_BIT_STRING = 0 as *const ASN1_BIT_STRING; - unsafe { - X509_NAME_print_ex( - mem, - X509_get_subject_name(x), - 0 as i32, - (1 as i32 - | 2 as i32 - | 4 as i32 - | 0x10 as i32 - | 0x100 as i32 - | 0x200 as i32 - | 8 as i32 - | (2 as i32) << 16 as i32 - | (1 as i32) << 23 as i32 - | 0 as i32) as u64, - ); - let mut info_len: i64 = BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ); - - Curl_ssl_push_certinfo_len( - data, - i, - b"Subject\0" as *const u8 as *const libc::c_char, - ptr, - info_len as size_t, - ); - } - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - unsafe { - X509_NAME_print_ex( - mem, - X509_get_issuer_name(x), - 0 as i32, - (1 as i32 - | 2 as i32 - | 4 as i32 - | 0x10 as i32 - | 0x100 as i32 - | 0x200 as i32 - | 8 as i32 - | (2 as i32) << 16 as i32 - | (1 as i32) << 23 as i32 - | 0 as i32) as u64, - ); - } - let mut info_len_0: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Issuer\0" as *const u8 as *const libc::c_char, - ptr, - info_len_0 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - unsafe { - BIO_printf( - mem, - b"%lx\0" as *const u8 as *const libc::c_char, - X509_get_version(x), - ); - } - let mut info_len_1: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Version\0" as *const u8 as *const libc::c_char, - ptr, - info_len_1 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - num = unsafe { X509_get_serialNumber(x) }; - if unsafe { (*num).type_0 } == 2 as i32 | 0x100 as i32 { - unsafe { - BIO_puts(mem, b"-\0" as *const u8 as *const libc::c_char); - } - } - j = 0 as i32; - while j < unsafe { (*num).length } { - unsafe { - BIO_printf( - mem, - b"%02x\0" as *const u8 as *const libc::c_char, - *((*num).data).offset(j as isize) as i32, - ); - } - j += 1; - } - let mut info_len_2: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Serial Number\0" as *const u8 as *const libc::c_char, - ptr, - info_len_2 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - - if cfg!(all(HAVE_X509_GET0_SIGNATURE, HAVE_X509_GET0_EXTENSIONS)) { - let mut sigalg: *const X509_ALGOR = 0 as *const X509_ALGOR; - let mut xpubkey: *mut X509_PUBKEY = 0 as *mut X509_PUBKEY; - let mut pubkeyoid: *mut ASN1_OBJECT = 0 as *mut ASN1_OBJECT; - unsafe { - X509_get0_signature(&mut psig, &mut sigalg, x); - } - if !sigalg.is_null() { - unsafe { - i2a_ASN1_OBJECT(mem, (*sigalg).algorithm); - } - let mut info_len_3: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Signature Algorithm\0" as *const u8 as *const libc::c_char, - ptr, - info_len_3 as size_t, - ); - 1 as i32 - != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - } - xpubkey = unsafe { X509_get_X509_PUBKEY(x) }; - if !xpubkey.is_null() { - unsafe { - X509_PUBKEY_get0_param( - &mut pubkeyoid, - 0 as *mut *const u8, - 0 as *mut i32, - 0 as *mut *mut X509_ALGOR, - xpubkey, - ); - if !pubkeyoid.is_null() { - i2a_ASN1_OBJECT(mem, pubkeyoid); - let mut info_len_4: i64 = BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ); - Curl_ssl_push_certinfo_len( - data, - i, - b"Public Key Algorithm\0" as *const u8 as *const libc::c_char, - ptr, - info_len_4 as size_t, - ); - 1 as i32 - != BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32; - } - } - } - unsafe { - X509V3_ext(data, i, X509_get0_extensions(x)); - } - } else { - // before OpenSSL 1.0.2 - } - unsafe { - ASN1_TIME_print(mem, X509_get0_notBefore(x)); - } - let mut info_len_5: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Start date\0" as *const u8 as *const libc::c_char, - ptr, - info_len_5 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - unsafe { - ASN1_TIME_print(mem, X509_get0_notAfter(x)); - } - let mut info_len_6: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Expire date\0" as *const u8 as *const libc::c_char, - ptr, - info_len_6 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - - pubkey = unsafe { X509_get_pubkey(x) }; - if pubkey.is_null() { - unsafe { - Curl_infof( - data, - b" Unable to load public key\0" as *const u8 as *const libc::c_char, - ); - } - } else { - let mut pktype: i32 = 0; - match () { - #[cfg(HAVE_OPAQUE_EVP_PKEY)] - _ => { - pktype = unsafe { EVP_PKEY_id(pubkey) }; - } - #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - _ => {} - } - // #[cfg(HAVE_OPAQUE_EVP_PKEY)] - // pktype = EVP_PKEY_id(pubkey); - // TODO - 3652 - // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - match pktype { - 6 => { - #[cfg(HAVE_OPAQUE_EVP_PKEY)] - let mut rsa: *mut RSA = unsafe { EVP_PKEY_get0_RSA(pubkey) }; - // TODO - 3652 - // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] - if true { - let mut n: *const BIGNUM = 0 as *const BIGNUM; - let mut e: *const BIGNUM = 0 as *const BIGNUM; - unsafe { - RSA_get0_key(rsa, &mut n, &mut e, 0 as *mut *const BIGNUM); - } - - BIO_printf( - mem, - b"%d\0" as *const u8 as *const libc::c_char, - BN_num_bits(n), - ); - - let mut info_len_7: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ) - }; - unsafe { - Curl_ssl_push_certinfo_len( - data, - i, - b"RSA Public Key\0" as *const u8 as *const libc::c_char, - ptr, - info_len_7 as size_t, - ); - } - 1 as i32 - != unsafe { - BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 - }; - unsafe { - pubkey_show( - data, - mem, - i, - b"rsa\0" as *const u8 as *const libc::c_char, - b"n\0" as *const u8 as *const libc::c_char, - n, - ); - pubkey_show( - data, - mem, - i, - b"rsa\0" as *const u8 as *const libc::c_char, - b"e\0" as *const u8 as *const libc::c_char, - e, - ); - } - } - #[cfg(not(HAVE_OPAQUE_RSA_DSA_DH))] - if true { - // TODO - 3678 - } - } - 116 => { - if cfg!(not(OPENSSL_NO_DSA)) { - #[cfg(HAVE_OPAQUE_EVP_PKEY)] - let mut dsa: *mut DSA = unsafe { EVP_PKEY_get0_DSA(pubkey) }; - // TODO - 3691 - // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] - if true { - let mut p: *const BIGNUM = 0 as *const BIGNUM; - let mut q: *const BIGNUM = 0 as *const BIGNUM; - let mut g: *const BIGNUM = 0 as *const BIGNUM; - let mut pub_key: *const BIGNUM = 0 as *const BIGNUM; - unsafe { - DSA_get0_pqg(dsa, &mut p, &mut q, &mut g); - DSA_get0_key(dsa, &mut pub_key, 0 as *mut *const BIGNUM); - pubkey_show( - data, - mem, - i, - b"dsa\0" as *const u8 as *const libc::c_char, - b"p\0" as *const u8 as *const libc::c_char, - p, - ); - pubkey_show( - data, - mem, - i, - b"dsa\0" as *const u8 as *const libc::c_char, - b"q\0" as *const u8 as *const libc::c_char, - q, - ); - pubkey_show( - data, - mem, - i, - b"dsa\0" as *const u8 as *const libc::c_char, - b"g\0" as *const u8 as *const libc::c_char, - g, - ); - pubkey_show( - data, - mem, - i, - b"dsa\0" as *const u8 as *const libc::c_char, - b"pub_key\0" as *const u8 as *const libc::c_char, - pub_key, - ); - } - } - #[cfg(not(HAVE_OPAQUE_RSA_DSA_DH))] - if true { - // cfg!(not(HAVE_OPAQUE_RSA_DSA_DH)) - } - } - } - 28 => { - #[cfg(HAVE_OPAQUE_EVP_PKEY)] - let mut dh: *mut DH = unsafe { EVP_PKEY_get0_DH(pubkey) }; - // TODO - // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] - if true { - let mut p_0: *const BIGNUM = 0 as *const BIGNUM; - let mut q_0: *const BIGNUM = 0 as *const BIGNUM; - let mut g_0: *const BIGNUM = 0 as *const BIGNUM; - let mut pub_key_0: *const BIGNUM = 0 as *const BIGNUM; - unsafe { - DH_get0_pqg(dh, &mut p_0, &mut q_0, &mut g_0); - DH_get0_key(dh, &mut pub_key_0, 0 as *mut *const BIGNUM); - pubkey_show( - data, - mem, - i, - b"dh\0" as *const u8 as *const libc::c_char, - b"p\0" as *const u8 as *const libc::c_char, - p_0, - ); - pubkey_show( - data, - mem, - i, - b"dh\0" as *const u8 as *const libc::c_char, - b"q\0" as *const u8 as *const libc::c_char, - q_0, - ); - pubkey_show( - data, - mem, - i, - b"dh\0" as *const u8 as *const libc::c_char, - b"g\0" as *const u8 as *const libc::c_char, - g_0, - ); - pubkey_show( - data, - mem, - i, - b"dh\0" as *const u8 as *const libc::c_char, - b"pub_key\0" as *const u8 as *const libc::c_char, - pub_key_0, - ); - } - } - // TODO - #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - if true { - // TODO - 3471 - } - } - _ => {} - } - unsafe { - EVP_PKEY_free(pubkey); - } - } - if !psig.is_null() { - j = 0 as i32; - while j < unsafe { (*psig).length } { - unsafe { - BIO_printf( - mem, - b"%02x:\0" as *const u8 as *const libc::c_char, - *((*psig).data).offset(j as isize) as i32, - ); - } - j += 1; - } - let mut info_len_8: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Signature\0" as *const u8 as *const libc::c_char, - ptr, - info_len_8 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - } - unsafe { - PEM_write_bio_X509(mem, x); - } - let mut info_len_9: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Cert\0" as *const u8 as *const libc::c_char, - ptr, - info_len_9 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - i += 1; - } - unsafe { - BIO_free(mem); - } - return CURLE_OK; -} - -/* - * Heavily modified from: - * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL - */ -#[cfg(USE_OPENSSL)] -extern "C" fn pkp_pin_peer_pubkey( - mut data: *mut Curl_easy, - mut cert: *mut X509, - mut pinnedpubkey: *const libc::c_char, -) -> CURLcode { - /* Scratch */ - let mut len1: i32 = 0 as i32; - let mut len2: i32 = 0 as i32; - let mut buff1: *mut u8 = 0 as *mut u8; - let mut temp: *mut u8 = 0 as *mut u8; - /* Result is returned to caller */ - let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - /* if a path wasn't specified, don't pin */ - if pinnedpubkey.is_null() { - return CURLE_OK; - } - if cert.is_null() { - return result; - } - /* Begin Gyrations to get the subjectPublicKeyInfo */ - /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */ - len1 = unsafe { i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), 0 as *mut *mut u8) }; - if !(len1 < 1 as i32) { - match () { - #[cfg(not(CURLDEBUG))] - _ => { - temp = unsafe { - Curl_cmalloc.expect("non-null function pointer")(len1 as size_t) as *mut u8 - }; - } - #[cfg(CURLDEBUG)] - _ => { - temp = unsafe { - curl_dbg_malloc( - len1 as size_t, - 3798 as i32, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - ) - } as *mut u8; - } - } - buff1 = temp; - if !buff1.is_null() { - len2 = unsafe { i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &mut temp) }; - /* - * These checks are verifying we got back the same values as when we - * sized the buffer. It's pretty weak since they should always be the - * same. But it gives us something to test. - */ - if !(len1 != len2 - || temp.is_null() - || unsafe { temp.offset_from(buff1) } as i64 != len1 as i64) - { - /* End Gyrations */ - - /* The one good exit point */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1 as size_t); - } - } - } - if !buff1.is_null() { - #[cfg(not(CURLDEBUG))] - unsafe { - Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void); - } - - #[cfg(CURLDEBUG)] - unsafe { - curl_dbg_free( - buff1 as *mut libc::c_void, - 3820 as i32, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - ); - } - } - return result; -} - -/* - * Get the server cert, verify it and show it, etc., only call failf() if the - * 'strict' argument is TRUE as otherwise all this is for informational - * purposes only! - * - * We check certificates to authenticate the server; otherwise we risk - * man-in-the-middle attack. - */ -#[cfg(USE_OPENSSL)] -extern "C" fn servercert( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut connssl: *mut ssl_connect_data, - mut strict: bool, -) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut rc: i32 = 0; - let mut lerr: i64 = 0; - let mut issuer: *mut X509 = 0 as *mut X509; - let mut fp: *mut BIO = 0 as *mut BIO; - let mut error_buffer: [libc::c_char; 256] = unsafe { - *::std::mem::transmute::< - &[u8; 256], - &mut [libc::c_char; 256], - >( - b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + if !pubkeyoid.is_null() { + i2a_ASN1_OBJECT(mem, pubkeyoid); + let mut info_len_4: i64 = BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ); + Curl_ssl_push_certinfo_len( + data, + i, + b"Public Key Algorithm\0" as *const u8 as *const libc::c_char, + ptr, + info_len_4 as size_t, + ); + 1 as i32 + != BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32; + } + } + } + unsafe { + X509V3_ext(data, i, X509_get0_extensions(x)); + } + } else { + // before OpenSSL 1.0.2 + } + unsafe { + ASN1_TIME_print(mem, X509_get0_notBefore(x)); + } + let mut info_len_5: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Start date\0" as *const u8 as *const libc::c_char, + ptr, + info_len_5 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + unsafe { + ASN1_TIME_print(mem, X509_get0_notAfter(x)); + } + let mut info_len_6: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Expire date\0" as *const u8 as *const libc::c_char, + ptr, + info_len_6 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + + pubkey = unsafe { X509_get_pubkey(x) }; + if pubkey.is_null() { + unsafe { + Curl_infof( + data, + b" Unable to load public key\0" as *const u8 as *const libc::c_char, + ); + } + } else { + let mut pktype: i32 = 0; + match () { + #[cfg(HAVE_OPAQUE_EVP_PKEY)] + _ => { + pktype = unsafe { EVP_PKEY_id(pubkey) }; + } + #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + _ => {} + } + // #[cfg(HAVE_OPAQUE_EVP_PKEY)] + // pktype = EVP_PKEY_id(pubkey); + // TODO - 3652 + // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + match pktype { + 6 => { + #[cfg(HAVE_OPAQUE_EVP_PKEY)] + let mut rsa: *mut RSA = unsafe { EVP_PKEY_get0_RSA(pubkey) }; + // TODO - 3652 + // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] + if true { + let mut n: *const BIGNUM = 0 as *const BIGNUM; + let mut e: *const BIGNUM = 0 as *const BIGNUM; + unsafe { + RSA_get0_key(rsa, &mut n, &mut e, 0 as *mut *const BIGNUM); + } + + BIO_printf( + mem, + b"%d\0" as *const u8 as *const libc::c_char, + BN_num_bits(n), + ); + + let mut info_len_7: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ) + }; + unsafe { + Curl_ssl_push_certinfo_len( + data, + i, + b"RSA Public Key\0" as *const u8 as *const libc::c_char, + ptr, + info_len_7 as size_t, + ); + } + 1 as i32 + != unsafe { + BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 + }; + unsafe { + pubkey_show( + data, + mem, + i, + b"rsa\0" as *const u8 as *const libc::c_char, + b"n\0" as *const u8 as *const libc::c_char, + n, + ); + pubkey_show( + data, + mem, + i, + b"rsa\0" as *const u8 as *const libc::c_char, + b"e\0" as *const u8 as *const libc::c_char, + e, + ); + } + } + #[cfg(not(HAVE_OPAQUE_RSA_DSA_DH))] + if true { + // TODO - 3678 + } + } + 116 => { + if cfg!(not(OPENSSL_NO_DSA)) { + #[cfg(HAVE_OPAQUE_EVP_PKEY)] + let mut dsa: *mut DSA = unsafe { EVP_PKEY_get0_DSA(pubkey) }; + // TODO - 3691 + // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] + if true { + let mut p: *const BIGNUM = 0 as *const BIGNUM; + let mut q: *const BIGNUM = 0 as *const BIGNUM; + let mut g: *const BIGNUM = 0 as *const BIGNUM; + let mut pub_key: *const BIGNUM = 0 as *const BIGNUM; + unsafe { + DSA_get0_pqg(dsa, &mut p, &mut q, &mut g); + DSA_get0_key(dsa, &mut pub_key, 0 as *mut *const BIGNUM); + pubkey_show( + data, + mem, + i, + b"dsa\0" as *const u8 as *const libc::c_char, + b"p\0" as *const u8 as *const libc::c_char, + p, + ); + pubkey_show( + data, + mem, + i, + b"dsa\0" as *const u8 as *const libc::c_char, + b"q\0" as *const u8 as *const libc::c_char, + q, + ); + pubkey_show( + data, + mem, + i, + b"dsa\0" as *const u8 as *const libc::c_char, + b"g\0" as *const u8 as *const libc::c_char, + g, + ); + pubkey_show( + data, + mem, + i, + b"dsa\0" as *const u8 as *const libc::c_char, + b"pub_key\0" as *const u8 as *const libc::c_char, + pub_key, + ); + } + } + #[cfg(not(HAVE_OPAQUE_RSA_DSA_DH))] + if true { + // cfg!(not(HAVE_OPAQUE_RSA_DSA_DH)) + } + } + } + 28 => { + #[cfg(HAVE_OPAQUE_EVP_PKEY)] + let mut dh: *mut DH = unsafe { EVP_PKEY_get0_DH(pubkey) }; + // TODO + // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] + if true { + let mut p_0: *const BIGNUM = 0 as *const BIGNUM; + let mut q_0: *const BIGNUM = 0 as *const BIGNUM; + let mut g_0: *const BIGNUM = 0 as *const BIGNUM; + let mut pub_key_0: *const BIGNUM = 0 as *const BIGNUM; + unsafe { + DH_get0_pqg(dh, &mut p_0, &mut q_0, &mut g_0); + DH_get0_key(dh, &mut pub_key_0, 0 as *mut *const BIGNUM); + pubkey_show( + data, + mem, + i, + b"dh\0" as *const u8 as *const libc::c_char, + b"p\0" as *const u8 as *const libc::c_char, + p_0, + ); + pubkey_show( + data, + mem, + i, + b"dh\0" as *const u8 as *const libc::c_char, + b"q\0" as *const u8 as *const libc::c_char, + q_0, + ); + pubkey_show( + data, + mem, + i, + b"dh\0" as *const u8 as *const libc::c_char, + b"g\0" as *const u8 as *const libc::c_char, + g_0, + ); + pubkey_show( + data, + mem, + i, + b"dh\0" as *const u8 as *const libc::c_char, + b"pub_key\0" as *const u8 as *const libc::c_char, + pub_key_0, + ); + } + } + // TODO + #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + if true { + // TODO - 3471 + } + } + _ => {} + } + unsafe { + EVP_PKEY_free(pubkey); + } + } + if !psig.is_null() { + j = 0 as i32; + while j < unsafe { (*psig).length } { + unsafe { + BIO_printf( + mem, + b"%02x:\0" as *const u8 as *const libc::c_char, + *((*psig).data).offset(j as isize) as i32, + ); + } + j += 1; + } + let mut info_len_8: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Signature\0" as *const u8 as *const libc::c_char, + ptr, + info_len_8 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + } + unsafe { + PEM_write_bio_X509(mem, x); + } + let mut info_len_9: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Cert\0" as *const u8 as *const libc::c_char, + ptr, + info_len_9 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + i += 1; + } + unsafe { + BIO_free(mem); + } + return CURLE_OK; + } + + /* + * Heavily modified from: + * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL + */ + #[cfg(USE_OPENSSL)] + extern "C" fn pkp_pin_peer_pubkey( + mut data: *mut Curl_easy, + mut cert: *mut X509, + mut pinnedpubkey: *const libc::c_char, + ) -> CURLcode { + /* Scratch */ + let mut len1: i32 = 0 as i32; + let mut len2: i32 = 0 as i32; + let mut buff1: *mut u8 = 0 as *mut u8; + let mut temp: *mut u8 = 0 as *mut u8; + /* Result is returned to caller */ + let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + /* if a path wasn't specified, don't pin */ + if pinnedpubkey.is_null() { + return CURLE_OK; + } + if cert.is_null() { + return result; + } + /* Begin Gyrations to get the subjectPublicKeyInfo */ + /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */ + len1 = unsafe { i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), 0 as *mut *mut u8) }; + if !(len1 < 1 as i32) { + match () { + #[cfg(not(CURLDEBUG))] + _ => { + temp = unsafe { + Curl_cmalloc.expect("non-null function pointer")(len1 as size_t) as *mut u8 + }; + } + #[cfg(CURLDEBUG)] + _ => { + temp = unsafe { + curl_dbg_malloc( + len1 as size_t, + 3798 as i32, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + ) + } as *mut u8; + } + } + buff1 = temp; + if !buff1.is_null() { + len2 = unsafe { i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &mut temp) }; + /* + * These checks are verifying we got back the same values as when we + * sized the buffer. It's pretty weak since they should always be the + * same. But it gives us something to test. + */ + if !(len1 != len2 + || temp.is_null() + || unsafe { temp.offset_from(buff1) } as i64 != len1 as i64) + { + /* End Gyrations */ + + /* The one good exit point */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1 as size_t); + } + } + } + if !buff1.is_null() { + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void); + } + + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + buff1 as *mut libc::c_void, + 3820 as i32, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + ); + } + } + return result; + } + + /* + * Get the server cert, verify it and show it, etc., only call failf() if the + * 'strict' argument is TRUE as otherwise all this is for informational + * purposes only! + * + * We check certificates to authenticate the server; otherwise we risk + * man-in-the-middle attack. + */ + #[cfg(USE_OPENSSL)] + extern "C" fn servercert( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut connssl: *mut ssl_connect_data, + mut strict: bool, + ) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut rc: i32 = 0; + let mut lerr: i64 = 0; + let mut issuer: *mut X509 = 0 as *mut X509; + let mut fp: *mut BIO = 0 as *mut BIO; + let mut error_buffer: [libc::c_char; 256] = unsafe { + *::std::mem::transmute::< + &[u8; 256], + &mut [libc::c_char; 256], + >( + b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + ) + }; + let mut buffer: [libc::c_char; 2048] = [0; 2048]; + let mut ptr: *const libc::c_char = 0 as *const libc::c_char; + let mut mem: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + if unsafe { ((*data).set.ssl).certinfo() } != 0 { + /* we've been asked to gather certificate info! */ + get_cert_chain(data, connssl); + } + unsafe { + (*backend).server_cert = SSL_get_peer_certificate((*backend).handle); + } + if unsafe { ((*backend).server_cert).is_null() } { + unsafe { + BIO_free(mem); + } + if !strict { + return CURLE_OK; + } + unsafe { + Curl_failf( + data, + b"SSL: couldn't get peer certificate!\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_PEER_FAILED_VERIFICATION; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_IS_PROXY_void = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype } as u32 + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + b"Proxy\0" as *const u8 as *const libc::c_char + } else { + b"Server\0" as *const u8 as *const libc::c_char + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_IS_PROXY_void = if 0 as i32 != 0 { + b"Proxy\0" as *const u8 as *const libc::c_char + } else { + b"Server\0" as *const u8 as *const libc::c_char + }; + unsafe { + Curl_infof( + data, + b"%s certificate:\0" as *const u8 as *const libc::c_char, + SSL_IS_PROXY_void, + ); + } + rc = unsafe { + x509_name_oneline( + X509_get_subject_name((*backend).server_cert), + buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 2048]>() as u64, ) - }; - let mut buffer: [libc::c_char; 2048] = [0; 2048]; - let mut ptr: *const libc::c_char = 0 as *const libc::c_char; - let mut mem: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - if unsafe { ((*data).set.ssl).certinfo() } != 0 { - /* we've been asked to gather certificate info! */ - get_cert_chain(data, connssl); - } - unsafe { - (*backend).server_cert = SSL_get_peer_certificate((*backend).handle); - } - if unsafe { ((*backend).server_cert).is_null() } { - unsafe { - BIO_free(mem); - } - if !strict { - return CURLE_OK; - } - unsafe { - Curl_failf( - data, - b"SSL: couldn't get peer certificate!\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_PEER_FAILED_VERIFICATION; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_IS_PROXY_void = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype } as u32 - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - b"Proxy\0" as *const u8 as *const libc::c_char - } else { - b"Server\0" as *const u8 as *const libc::c_char - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_IS_PROXY_void = if 0 as i32 != 0 { - b"Proxy\0" as *const u8 as *const libc::c_char - } else { - b"Server\0" as *const u8 as *const libc::c_char - }; - unsafe { - Curl_infof( - data, - b"%s certificate:\0" as *const u8 as *const libc::c_char, - SSL_IS_PROXY_void, - ); - } - rc = unsafe { - x509_name_oneline( - X509_get_subject_name((*backend).server_cert), - buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 2048]>() as u64, - ) - }; - unsafe { - Curl_infof( - data, - b" subject: %s\0" as *const u8 as *const libc::c_char, - if rc != 0 { - b"[NONE]\0" as *const u8 as *const libc::c_char - } else { - buffer.as_mut_ptr() as *const libc::c_char - }, - ); - } - // DONE - 3869 - if cfg!(not(CURL_DISABLE_VERBOSE_STRINGS)) { - let mut len: i64 = 0; - unsafe { - ASN1_TIME_print(mem, X509_get0_notBefore((*backend).server_cert)); - } - len = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *const libc::c_char as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ) - }; - unsafe { - Curl_infof( - data, - b" start date: %.*s\0" as *const u8 as *const libc::c_char, - len as i32, - ptr, - ); - BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void); - ASN1_TIME_print(mem, X509_get0_notAfter((*backend).server_cert)); - } - len = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *const libc::c_char as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ) - }; - unsafe { - Curl_infof( - data, - b" expire date: %.*s\0" as *const u8 as *const libc::c_char, - len as i32, - ptr, - ); - BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void); - BIO_free(mem); - } - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifyhost = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype } as u32 - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*conn).proxy_ssl_config).verifyhost() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifyhost() as i32 } - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifyhost = unsafe { ((*conn).ssl_config).verifyhost() != 0 }; - - if SSL_CONN_CONFIG_verifyhost { - result = unsafe { verifyhost(data, conn, (*backend).server_cert) }; - if result as u64 != 0 { - unsafe { - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return result; - } - } - rc = unsafe { - x509_name_oneline( - X509_get_issuer_name((*backend).server_cert), - buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 2048]>() as u64, - ) - }; - if rc != 0 { - if strict { - unsafe { - Curl_failf( - data, - b"SSL: couldn't get X509-issuer name!\0" as *const u8 as *const libc::c_char, - ); - } - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else { - unsafe { - Curl_infof( - data, - b" issuer: %s\0" as *const u8 as *const libc::c_char, - buffer.as_mut_ptr(), - ); - } - /* We could do all sorts of certificate verification stuff here before - deallocating the certificate. */ - - /* e.g. match issuer name with provided issuer certificate */ - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_issuercert = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).proxy_ssl_config.issuercert } - } else { - unsafe { (*conn).ssl_config.issuercert } - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_issuercert = unsafe { (*conn).ssl_config.issuercert }; - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_issuercert_blob = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).proxy_ssl_config.issuercert_blob } - } else { - unsafe { (*conn).ssl_config.issuercert_blob } - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_issuercert_blob = unsafe { (*conn).ssl_config.issuercert_blob }; - if !(SSL_CONN_CONFIG_issuercert).is_null() || !(SSL_CONN_CONFIG_issuercert_blob).is_null() { - if !(SSL_CONN_CONFIG_issuercert_blob).is_null() { - fp = unsafe { - BIO_new_mem_buf( - (*SSL_CONN_CONFIG_issuercert_blob).data, - (*SSL_CONN_CONFIG_issuercert_blob).len as i32, - ) - }; - } else { - fp = unsafe { BIO_new(BIO_s_file()) }; - if fp.is_null() { - unsafe { - Curl_failf( - data, - b"BIO_new return NULL, OpenSSL error %s\0" as *const u8 - as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return CURLE_OUT_OF_MEMORY; - } - if unsafe { - BIO_ctrl( - fp, - 108 as i32, - (0x1 as i32 | 0x2 as i32) as i64, - SSL_CONN_CONFIG_issuercert as *mut libc::c_void, - ) - } as i32 - <= 0 as i32 - { - if strict { - unsafe { - Curl_failf( - data, - b"SSL: Unable to open issuer cert (%s)\0" as *const u8 - as *const libc::c_char, - SSL_CONN_CONFIG_issuercert, - ); - } - } - unsafe { - BIO_free(fp); - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return CURLE_SSL_ISSUER_ERROR; - } - } - issuer = - unsafe { PEM_read_bio_X509(fp, 0 as *mut *mut X509, None, 0 as *mut libc::c_void) }; - if issuer.is_null() { - if strict { - unsafe { - Curl_failf( - data, - b"SSL: Unable to read issuer cert (%s)\0" as *const u8 - as *const libc::c_char, - SSL_CONN_CONFIG_issuercert, - ); - } - } - unsafe { - BIO_free(fp); - X509_free(issuer); - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return CURLE_SSL_ISSUER_ERROR; - } - if unsafe { X509_check_issued(issuer, (*backend).server_cert) } != 0 as i32 { - if strict { - unsafe { - Curl_failf( - data, - b"SSL: Certificate issuer check failed (%s)\0" as *const u8 - as *const libc::c_char, - SSL_CONN_CONFIG_issuercert, - ); - } - } - unsafe { - BIO_free(fp); - X509_free(issuer); - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return CURLE_SSL_ISSUER_ERROR; - } - unsafe { - Curl_infof( - data, - b" SSL certificate issuer check ok (%s)\0" as *const u8 as *const libc::c_char, - SSL_CONN_CONFIG_issuercert, - ); - BIO_free(fp); - X509_free(issuer); - } - } - lerr = unsafe { SSL_get_verify_result((*backend).handle) }; - #[cfg(not(CURL_DISABLE_PROXY))] - if true { - *if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } - { - unsafe { &mut (*data).set.proxy_ssl.certverifyresult } - } else { - unsafe { &mut (*data).set.ssl.certverifyresult } - } = lerr; - } - #[cfg(CURL_DISABLE_PROXY)] - if true { - (*data).set.ssl.certverifyresult = lerr; - } - if lerr != 0 as i64 { - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifypeer = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifypeer() as i32 } - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifypeer = unsafe { ((*conn).ssl_config).verifystatus() } != 0; - if SSL_CONN_CONFIG_verifypeer { - /* We probably never reach this, because SSL_connect() will fail - and we return earlier if verifypeer is set? */ - if strict { - unsafe { - Curl_failf( - data, - b"SSL certificate verify result: %s (%ld)\0" as *const u8 - as *const libc::c_char, - X509_verify_cert_error_string(lerr), - lerr, - ); - } - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else { - unsafe { - Curl_infof( - data, - b" SSL certificate verify result: %s (%ld), continuing anyway.\0" - as *const u8 as *const libc::c_char, - X509_verify_cert_error_string(lerr), - lerr, - ); - } - } - } else { - unsafe { - Curl_infof( - data, - b" SSL certificate verify ok.\0" as *const u8 as *const libc::c_char, - ); - } - } - } - // DONE - 3986 - #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP), not(CURL_DISABLE_PROXY)))] - let SSL_CONN_CONFIG_verifystatus = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*conn).proxy_ssl_config).verifystatus() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifystatus() as i32 } - } != 0; - #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP), CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifystatus = unsafe { ((*conn).ssl_config).verifystatus() } != 0; - #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP)))] - if SSL_CONN_CONFIG_verifystatus { - result = verifystatus(data, connssl); - if result as u64 != 0 { - unsafe { - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return result; - } - } - if !strict { - /* when not strict, we don't bother about the verify cert problems */ - result = CURLE_OK; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_PINNED_PUB_KEY_void = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as usize] } - } else { - unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] } - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_PINNED_PUB_KEY_void = unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] }; - ptr = SSL_PINNED_PUB_KEY_void; - if result as u64 == 0 && !ptr.is_null() { - result = unsafe { pkp_pin_peer_pubkey(data, (*backend).server_cert, ptr) }; - if result as u64 != 0 { - unsafe { - Curl_failf( - data, - b"SSL: public key does not match pinned public key!\0" as *const u8 - as *const libc::c_char, - ); - } - } - } - unsafe { - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - (*connssl).connecting_state = ssl_connect_done; - } - return result; -} - -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_connect_step3( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ssl_connect_3 as u32 == unsafe { (*connssl).connecting_state as u32 } { - } else { - unsafe { - __assert_fail( - b"ssl_connect_3 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 4022 as u32, - (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( - b"CURLcode ossl_connect_step3(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - } - - #[cfg(not(CURL_DISABLE_PROXY))] - let servercert_value_result = servercert( - data, - conn, - connssl, - (if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } - { - unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifypeer() as i32 } - }) != 0 - || (if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } - { - unsafe { ((*conn).proxy_ssl_config).verifyhost() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifyhost() as i32 } - }) != 0, - ); - #[cfg(CURL_DISABLE_PROXY)] - let servercert_value_result = servercert( - data, - conn, - connssl, - unsafe { ((*conn).ssl_config).verifypeer() } as i32 != 0 - || unsafe { ((*conn).ssl_config).verifyhost() } as i32 != 0, - ); - /* - * We check certificates to authenticate the server; otherwise we risk - * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to - * verify the peer, ignore faults and failures from the server cert - * operations. - */ - result = servercert_value_result; - if result as u64 == 0 { - unsafe { - (*connssl).connecting_state = ssl_connect_done; - } - } - return result; -} - -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_connect_common( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut nonblocking: bool, - mut done: *mut bool, -) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } - as *mut ssl_connect_data; - let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; - let mut what: i32 = 0; - /* check if the connection has already been established */ - if ssl_connection_complete as u32 == unsafe { (*connssl).state as u32 } { - unsafe { - *done = 1 as i32 != 0; - } - return CURLE_OK; - } - if ssl_connect_1 as u32 == unsafe { (*connssl).connecting_state as u32 } { - /* Find out how much more time we're allowed */ - let timeout_ms: timediff_t = - unsafe { Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0) }; - if timeout_ms < 0 as i64 { - /* no need to continue if time is already up */ - unsafe { - Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_OPERATION_TIMEDOUT; - } - result = ossl_connect_step1(data, conn, sockindex); - if result as u64 != 0 { - return result; - } - } - unsafe { - while ssl_connect_2 as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 - { - /* check allowed time left */ - let timeout_ms_0: timediff_t = Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0); - if timeout_ms_0 < 0 as i64 { - /* no need to continue if time already is up */ - Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - ); - return CURLE_OPERATION_TIMEDOUT; - } - /* if ssl is expecting something, check if it's available. */ - if (*connssl).connecting_state as u32 == ssl_connect_2_reading as u32 - || (*connssl).connecting_state as u32 == ssl_connect_2_writing as u32 - { - let mut writefd: curl_socket_t = - if ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 { - sockfd - } else { - -(1 as i32) - }; - let mut readfd: curl_socket_t = - if ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 { - sockfd - } else { - -(1 as i32) - }; - what = Curl_socket_check( - readfd, - -(1 as i32), - writefd, - if nonblocking as i32 != 0 { - 0 as i64 - } else { - timeout_ms_0 - }, - ); - if what < 0 as i32 { - /* fatal error */ - Curl_failf( - data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, - *__errno_location(), - ); - return CURLE_SSL_CONNECT_ERROR; - } - if 0 as i32 == what { - if nonblocking { - *done = 0 as i32 != 0; - return CURLE_OK; - } - /* timeout */ - Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - ); - return CURLE_OPERATION_TIMEDOUT; - } - /* socket is readable or writable */ - } - /* Run transaction, and return to the caller if it failed or if this - * connection is done nonblocking and this loop would execute again. This - * permits the owner of a multi handle to abort a connection attempt - * before step2 has completed while ensuring that a client using select() - * or epoll() will always have a valid fdset to wait on. - */ - result = ossl_connect_step2(data, conn, sockindex); - if result as u32 != 0 - || nonblocking as i32 != 0 - && (ssl_connect_2 as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32) - { - return result; - } - } - } /* repeat step2 until all transactions are done. */ - - if ssl_connect_3 as u32 == unsafe { (*connssl).connecting_state as u32 } { - result = ossl_connect_step3(data, conn, sockindex); - if result as u64 != 0 { - return result; - } - } - if ssl_connect_done as u32 == unsafe { (*connssl).connecting_state as u32 } { - unsafe { - (*connssl).state = ssl_connection_complete; - (*conn).recv[sockindex as usize] = Some(ossl_recv as Curl_recv); - (*conn).send[sockindex as usize] = Some(ossl_send as Curl_send); - *done = 1 as i32 != 0; - } - } else { - unsafe { - *done = 0 as i32 != 0; - } - } - /* Reset our connect state machine */ - unsafe { - (*connssl).connecting_state = ssl_connect_1; - } - return CURLE_OK; -} - -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_connect_nonblocking( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut done: *mut bool, -) -> CURLcode { - return ossl_connect_common(data, conn, sockindex, 1 as i32 != 0, done); -} -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_connect( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut done: bool = 0 as i32 != 0; - result = ossl_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done); - if result as u64 != 0 { - return result; - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if done { - } else { - unsafe { - __assert_fail( - b"done\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 4170 as u32, - (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( - b"CURLcode ossl_connect(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - } - return CURLE_OK; -} -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_data_pending(mut conn: *const connectdata, mut connindex: i32) -> bool { - unsafe { - let mut connssl: *const ssl_connect_data = - &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data; - if !((*(*connssl).backend).handle).is_null() - && SSL_pending((*(*connssl).backend).handle) != 0 - { - return 1 as i32 != 0; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let mut proxyssl: *const ssl_connect_data = - &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data; - #[cfg(not(CURL_DISABLE_PROXY))] - if !((*(*proxyssl).backend).handle).is_null() - && SSL_pending((*(*proxyssl).backend).handle) != 0 - { - return 1 as i32 != 0; - } - return 0 as i32 != 0; - } -} -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_send( - mut data: *mut Curl_easy, - mut sockindex: i32, - mut mem: *const libc::c_void, - mut len: size_t, - mut curlcode: *mut CURLcode, -) -> ssize_t { - /* SSL_write() is said to return 'int' while write() and send() returns - 'size_t' */ - let mut err: i32 = 0; - let mut error_buffer: [libc::c_char; 256] = [0; 256]; - let mut sslerror: u64 = 0; - let mut memlen: i32 = 0; - let mut rc: i32 = 0; - let mut conn: *mut connectdata = unsafe { (*data).conn }; - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - unsafe { - ERR_clear_error(); - } - const INT_MAX: size_t = 2147483647 as size_t; - memlen = if len > INT_MAX { - INT_MAX as i32 - } else { - len as i32 - }; - unsafe { - (*(*conn).ssl[0 as usize].backend).logger = data; - } - rc = unsafe { SSL_write((*backend).handle, mem, memlen) }; - if rc <= 0 as i32 { - err = unsafe { SSL_get_error((*backend).handle, rc) }; - match err { - 2 | 3 => { - /* The operation did not complete; the same TLS/SSL I/O function - should be called again later. This is basically an EWOULDBLOCK - equivalent. */ - unsafe { - *curlcode = CURLE_AGAIN; - } - return -(1 as i32) as ssize_t; - } - 5 => { - let mut sockerr: i32 = unsafe { *__errno_location() }; - sslerror = unsafe { ERR_get_error() }; - if sslerror != 0 { - ossl_strerror( - sslerror, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } else if sockerr != 0 { - unsafe { - Curl_strerror( - sockerr, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - } else { - unsafe { - strncpy( - error_buffer.as_mut_ptr(), - SSL_ERROR_to_str(err), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - error_buffer[(::std::mem::size_of::<[libc::c_char; 256]>() as u64) - .wrapping_sub(1 as u64) as usize] = '\0' as i32 as libc::c_char; - } - unsafe { - Curl_failf( - data, - b"OpenSSL SSL_write: %s, errno %d\0" as *const u8 as *const libc::c_char, - error_buffer.as_mut_ptr(), - sockerr, - ); - *curlcode = CURLE_SEND_ERROR; - } - return -(1 as i32) as ssize_t; - } - 1 => { - /* A failure in the SSL library occurred, usually a protocol error. - The OpenSSL error queue contains more information on the error. */ - sslerror = unsafe { ERR_get_error() }; - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let CURL_DISABLE_PROXY_flag_4 = (*conn).proxy_ssl[sockindex as usize].state - as u32 - == ssl_connection_complete as u32; - #[cfg(CURL_DISABLE_PROXY)] - let CURL_DISABLE_PROXY_flag_4 = true; - if (sslerror >> 24 as i64 & 0xff as u64) as i32 == 20 as i32 - && (sslerror & 0xfff as u64) as i32 == 128 as i32 - && (*conn).ssl[sockindex as usize].state as u32 - == ssl_connection_complete as u32 - && CURL_DISABLE_PROXY_flag_4 - { - let mut ver: [libc::c_char; 120] = [0; 120]; - ossl_version( - ver.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 120]>() as u64, - ); - Curl_failf( - data, - b"Error: %s does not support double SSL tunneling.\0" as *const u8 - as *const libc::c_char, - ver.as_mut_ptr(), - ); - } else { - Curl_failf( - data, - b"SSL_write() error: %s\0" as *const u8 as *const libc::c_char, - ossl_strerror( - sslerror, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - } - - *curlcode = CURLE_SEND_ERROR; - } - return -(1 as i32) as ssize_t; - } - _ => {} - } - /* a true error */ - unsafe { - Curl_failf( - data, - b"OpenSSL SSL_write: %s, errno %d\0" as *const u8 as *const libc::c_char, - SSL_ERROR_to_str(err), - *__errno_location(), - ); - *curlcode = CURLE_SEND_ERROR; - } - return -(1 as i32) as ssize_t; - } - unsafe { - *curlcode = CURLE_OK; - } - return rc as ssize_t; -} - -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_recv( - mut data: *mut Curl_easy, - mut num: i32, - mut buf: *mut libc::c_char, - mut buffersize: size_t, - mut curlcode: *mut CURLcode, -) -> ssize_t { - let mut error_buffer: [libc::c_char; 256] = [0; 256]; - let mut sslerror: u64 = 0; - let mut nread: ssize_t = 0; - let mut buffsize: i32 = 0; - let mut conn: *mut connectdata = unsafe { (*data).conn }; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) } as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - unsafe { - ERR_clear_error(); - } - const INT_MAX: size_t = 2147483647 as size_t; - buffsize = if buffersize > INT_MAX { - INT_MAX as i32 - } else { - buffersize as i32 - }; - unsafe { - (*(*conn).ssl[0 as usize].backend).logger = data; - nread = SSL_read((*backend).handle, buf as *mut libc::c_void, buffsize) as ssize_t; - } - if nread <= 0 as i64 { - let mut err: i32 = unsafe { SSL_get_error((*backend).handle, nread as i32) }; - match err { - 0 => {} - 6 => { - if num == 0 as i32 { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - unsafe { - Curl_conncontrol(conn, 1 as i32); - } - - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - unsafe { - Curl_conncontrol( - conn, - 1 as i32, - b"TLS close_notify\0" as *const u8 as *const libc::c_char, - ); - } - } - } - 2 | 3 => { - unsafe { - *curlcode = CURLE_AGAIN; - } - return -(1 as i32) as ssize_t; - } - _ => { - sslerror = unsafe { ERR_get_error() }; - if nread < 0 as i64 || sslerror != 0 { - let mut sockerr: i32 = unsafe { *__errno_location() }; - if sslerror != 0 { - ossl_strerror( - sslerror, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } else if sockerr != 0 && err == 5 as i32 { - unsafe { - Curl_strerror( - sockerr, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - } else { - unsafe { - strncpy( - error_buffer.as_mut_ptr(), - SSL_ERROR_to_str(err), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - error_buffer[(::std::mem::size_of::<[libc::c_char; 256]>() as u64) - .wrapping_sub(1 as u64) - as usize] = '\0' as i32 as libc::c_char; - } - unsafe { - Curl_failf( - data, - b"OpenSSL SSL_read: %s, errno %d\0" as *const u8 as *const libc::c_char, - error_buffer.as_mut_ptr(), - sockerr, - ); - *curlcode = CURLE_RECV_ERROR; - } - return -(1 as i32) as ssize_t; - /* For debug builds be a little stricter and error on any - SSL_ERROR_SYSCALL. For example a server may have closed the connection - abruptly without a close_notify alert. For compatibility with older - peers we don't do this by default. #4624 - - We can use this to gauge how many users may be affected, and - if it goes ok eventually transition to allow in dev and release with - the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ - #[cfg(DEBUGBUILD)] - unsafe { - if err == 5 as i32 { - let mut sockerr_0: i32 = *__errno_location(); - if sockerr_0 != 0 { - Curl_strerror( - sockerr_0, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } else { - curl_msnprintf( - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - b"Connection closed abruptly\0" as *const u8 - as *const libc::c_char, - ); - } - Curl_failf( + }; + unsafe { + Curl_infof( + data, + b" subject: %s\0" as *const u8 as *const libc::c_char, + if rc != 0 { + b"[NONE]\0" as *const u8 as *const libc::c_char + } else { + buffer.as_mut_ptr() as *const libc::c_char + }, + ); + } + // DONE - 3869 + if cfg!(not(CURL_DISABLE_VERBOSE_STRINGS)) { + let mut len: i64 = 0; + unsafe { + ASN1_TIME_print(mem, X509_get0_notBefore((*backend).server_cert)); + } + len = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *const libc::c_char as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ) + }; + unsafe { + Curl_infof( + data, + b" start date: %.*s\0" as *const u8 as *const libc::c_char, + len as i32, + ptr, + ); + BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void); + ASN1_TIME_print(mem, X509_get0_notAfter((*backend).server_cert)); + } + len = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *const libc::c_char as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ) + }; + unsafe { + Curl_infof( + data, + b" expire date: %.*s\0" as *const u8 as *const libc::c_char, + len as i32, + ptr, + ); + BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void); + BIO_free(mem); + } + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifyhost = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype } as u32 + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*conn).proxy_ssl_config).verifyhost() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifyhost() as i32 } + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifyhost = unsafe { ((*conn).ssl_config).verifyhost() != 0 }; + + if SSL_CONN_CONFIG_verifyhost { + result = unsafe { verifyhost(data, conn, (*backend).server_cert) }; + if result as u64 != 0 { + unsafe { + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return result; + } + } + rc = unsafe { + x509_name_oneline( + X509_get_issuer_name((*backend).server_cert), + buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 2048]>() as u64, + ) + }; + if rc != 0 { + if strict { + unsafe { + Curl_failf( + data, + b"SSL: couldn't get X509-issuer name!\0" as *const u8 as *const libc::c_char, + ); + } + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else { + unsafe { + Curl_infof( + data, + b" issuer: %s\0" as *const u8 as *const libc::c_char, + buffer.as_mut_ptr(), + ); + } + /* We could do all sorts of certificate verification stuff here before + deallocating the certificate. */ + + /* e.g. match issuer name with provided issuer certificate */ + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_issuercert = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.issuercert } + } else { + unsafe { (*conn).ssl_config.issuercert } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_issuercert = unsafe { (*conn).ssl_config.issuercert }; + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_issuercert_blob = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.issuercert_blob } + } else { + unsafe { (*conn).ssl_config.issuercert_blob } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_issuercert_blob = unsafe { (*conn).ssl_config.issuercert_blob }; + if !(SSL_CONN_CONFIG_issuercert).is_null() || !(SSL_CONN_CONFIG_issuercert_blob).is_null() { + if !(SSL_CONN_CONFIG_issuercert_blob).is_null() { + fp = unsafe { + BIO_new_mem_buf( + (*SSL_CONN_CONFIG_issuercert_blob).data, + (*SSL_CONN_CONFIG_issuercert_blob).len as i32, + ) + }; + } else { + fp = unsafe { BIO_new(BIO_s_file()) }; + if fp.is_null() { + unsafe { + Curl_failf( data, - b"OpenSSL SSL_read: %s, errno %d (Fatal because this is a curl debug build)\0" - as *const u8 as *const libc::c_char, + b"BIO_new return NULL, OpenSSL error %s\0" as *const u8 + as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return CURLE_OUT_OF_MEMORY; + } + if unsafe { + BIO_ctrl( + fp, + 108 as i32, + (0x1 as i32 | 0x2 as i32) as i64, + SSL_CONN_CONFIG_issuercert as *mut libc::c_void, + ) + } as i32 + <= 0 as i32 + { + if strict { + unsafe { + Curl_failf( + data, + b"SSL: Unable to open issuer cert (%s)\0" as *const u8 + as *const libc::c_char, + SSL_CONN_CONFIG_issuercert, + ); + } + } + unsafe { + BIO_free(fp); + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return CURLE_SSL_ISSUER_ERROR; + } + } + issuer = + unsafe { PEM_read_bio_X509(fp, 0 as *mut *mut X509, None, 0 as *mut libc::c_void) }; + if issuer.is_null() { + if strict { + unsafe { + Curl_failf( + data, + b"SSL: Unable to read issuer cert (%s)\0" as *const u8 + as *const libc::c_char, + SSL_CONN_CONFIG_issuercert, + ); + } + } + unsafe { + BIO_free(fp); + X509_free(issuer); + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return CURLE_SSL_ISSUER_ERROR; + } + if unsafe { X509_check_issued(issuer, (*backend).server_cert) } != 0 as i32 { + if strict { + unsafe { + Curl_failf( + data, + b"SSL: Certificate issuer check failed (%s)\0" as *const u8 + as *const libc::c_char, + SSL_CONN_CONFIG_issuercert, + ); + } + } + unsafe { + BIO_free(fp); + X509_free(issuer); + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return CURLE_SSL_ISSUER_ERROR; + } + unsafe { + Curl_infof( + data, + b" SSL certificate issuer check ok (%s)\0" as *const u8 as *const libc::c_char, + SSL_CONN_CONFIG_issuercert, + ); + BIO_free(fp); + X509_free(issuer); + } + } + lerr = unsafe { SSL_get_verify_result((*backend).handle) }; + #[cfg(not(CURL_DISABLE_PROXY))] + if true { + *if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } + { + unsafe { &mut (*data).set.proxy_ssl.certverifyresult } + } else { + unsafe { &mut (*data).set.ssl.certverifyresult } + } = lerr; + } + #[cfg(CURL_DISABLE_PROXY)] + unsafe { + (*data).set.ssl.certverifyresult = lerr; + } + if lerr != 0 as i64 { + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifypeer = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifypeer() as i32 } + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifypeer = unsafe { ((*conn).ssl_config).verifystatus() } != 0; + if SSL_CONN_CONFIG_verifypeer { + /* We probably never reach this, because SSL_connect() will fail + and we return earlier if verifypeer is set? */ + if strict { + unsafe { + Curl_failf( + data, + b"SSL certificate verify result: %s (%ld)\0" as *const u8 + as *const libc::c_char, + X509_verify_cert_error_string(lerr), + lerr, + ); + } + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else { + unsafe { + Curl_infof( + data, + b" SSL certificate verify result: %s (%ld), continuing anyway.\0" + as *const u8 as *const libc::c_char, + X509_verify_cert_error_string(lerr), + lerr, + ); + } + } + } else { + unsafe { + Curl_infof( + data, + b" SSL certificate verify ok.\0" as *const u8 as *const libc::c_char, + ); + } + } + } + // DONE - 3986 + #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP), not(CURL_DISABLE_PROXY)))] + let SSL_CONN_CONFIG_verifystatus = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*conn).proxy_ssl_config).verifystatus() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifystatus() as i32 } + } != 0; + #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP), CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifystatus = unsafe { ((*conn).ssl_config).verifystatus() } != 0; + #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP)))] + if SSL_CONN_CONFIG_verifystatus { + result = verifystatus(data, connssl); + if result as u64 != 0 { + unsafe { + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return result; + } + } + if !strict { + /* when not strict, we don't bother about the verify cert problems */ + result = CURLE_OK; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_PINNED_PUB_KEY_void = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as usize] } + } else { + unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_PINNED_PUB_KEY_void = unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] }; + ptr = SSL_PINNED_PUB_KEY_void; + if result as u64 == 0 && !ptr.is_null() { + result = unsafe { pkp_pin_peer_pubkey(data, (*backend).server_cert, ptr) }; + if result as u64 != 0 { + unsafe { + Curl_failf( + data, + b"SSL: public key does not match pinned public key!\0" as *const u8 + as *const libc::c_char, + ); + } + } + } + unsafe { + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + (*connssl).connecting_state = ssl_connect_done; + } + return result; + } + + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_connect_step3( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ssl_connect_3 as u32 == unsafe { (*connssl).connecting_state as u32 } { + } else { + unsafe { + __assert_fail( + b"ssl_connect_3 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 4022 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode ossl_connect_step3(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + + #[cfg(not(CURL_DISABLE_PROXY))] + let servercert_value_result = servercert( + data, + conn, + connssl, + (if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } + { + unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifypeer() as i32 } + }) != 0 + || (if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } + { + unsafe { ((*conn).proxy_ssl_config).verifyhost() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifyhost() as i32 } + }) != 0, + ); + #[cfg(CURL_DISABLE_PROXY)] + let servercert_value_result = servercert( + data, + conn, + connssl, + unsafe { ((*conn).ssl_config).verifypeer() } as i32 != 0 + || unsafe { ((*conn).ssl_config).verifyhost() } as i32 != 0, + ); + /* + * We check certificates to authenticate the server; otherwise we risk + * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to + * verify the peer, ignore faults and failures from the server cert + * operations. + */ + result = servercert_value_result; + if result as u64 == 0 { + unsafe { + (*connssl).connecting_state = ssl_connect_done; + } + } + return result; + } + + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_connect_common( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut nonblocking: bool, + mut done: *mut bool, + ) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } + as *mut ssl_connect_data; + let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; + let mut what: i32 = 0; + /* check if the connection has already been established */ + if ssl_connection_complete as u32 == unsafe { (*connssl).state as u32 } { + unsafe { + *done = 1 as i32 != 0; + } + return CURLE_OK; + } + if ssl_connect_1 as u32 == unsafe { (*connssl).connecting_state as u32 } { + /* Find out how much more time we're allowed */ + let timeout_ms: timediff_t = + unsafe { Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0) }; + if timeout_ms < 0 as i64 { + /* no need to continue if time is already up */ + unsafe { + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_OPERATION_TIMEDOUT; + } + result = ossl_connect_step1(data, conn, sockindex); + if result as u64 != 0 { + return result; + } + } + unsafe { + while ssl_connect_2 as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 + { + /* check allowed time left */ + let timeout_ms_0: timediff_t = Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0); + if timeout_ms_0 < 0 as i64 { + /* no need to continue if time already is up */ + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OPERATION_TIMEDOUT; + } + /* if ssl is expecting something, check if it's available. */ + if (*connssl).connecting_state as u32 == ssl_connect_2_reading as u32 + || (*connssl).connecting_state as u32 == ssl_connect_2_writing as u32 + { + let mut writefd: curl_socket_t = + if ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 { + sockfd + } else { + -(1 as i32) + }; + let mut readfd: curl_socket_t = + if ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 { + sockfd + } else { + -(1 as i32) + }; + what = Curl_socket_check( + readfd, + -(1 as i32), + writefd, + if nonblocking as i32 != 0 { + 0 as i64 + } else { + timeout_ms_0 + }, + ); + if what < 0 as i32 { + /* fatal error */ + Curl_failf( + data, + b"select/poll on SSL socket, errno: %d\0" as *const u8 + as *const libc::c_char, + *__errno_location(), + ); + return CURLE_SSL_CONNECT_ERROR; + } + if 0 as i32 == what { + if nonblocking { + *done = 0 as i32 != 0; + return CURLE_OK; + } + /* timeout */ + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OPERATION_TIMEDOUT; + } + /* socket is readable or writable */ + } + /* Run transaction, and return to the caller if it failed or if this + * connection is done nonblocking and this loop would execute again. This + * permits the owner of a multi handle to abort a connection attempt + * before step2 has completed while ensuring that a client using select() + * or epoll() will always have a valid fdset to wait on. + */ + result = ossl_connect_step2(data, conn, sockindex); + if result as u32 != 0 + || nonblocking as i32 != 0 + && (ssl_connect_2 as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32) + { + return result; + } + } + } /* repeat step2 until all transactions are done. */ + + if ssl_connect_3 as u32 == unsafe { (*connssl).connecting_state as u32 } { + result = ossl_connect_step3(data, conn, sockindex); + if result as u64 != 0 { + return result; + } + } + if ssl_connect_done as u32 == unsafe { (*connssl).connecting_state as u32 } { + unsafe { + (*connssl).state = ssl_connection_complete; + (*conn).recv[sockindex as usize] = Some(ossl_recv as Curl_recv); + (*conn).send[sockindex as usize] = Some(ossl_send as Curl_send); + *done = 1 as i32 != 0; + } + } else { + unsafe { + *done = 0 as i32 != 0; + } + } + /* Reset our connect state machine */ + unsafe { + (*connssl).connecting_state = ssl_connect_1; + } + return CURLE_OK; + } + + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_connect_nonblocking( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut done: *mut bool, + ) -> CURLcode { + return ossl_connect_common(data, conn, sockindex, 1 as i32 != 0, done); + } + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_connect( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut done: bool = 0 as i32 != 0; + result = ossl_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done); + if result as u64 != 0 { + return result; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if done { + } else { + unsafe { + __assert_fail( + b"done\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 4170 as u32, + (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( + b"CURLcode ossl_connect(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + return CURLE_OK; + } + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_data_pending(mut conn: *const connectdata, mut connindex: i32) -> bool { + unsafe { + let mut connssl: *const ssl_connect_data = + &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data; + if !((*(*connssl).backend).handle).is_null() + && SSL_pending((*(*connssl).backend).handle) != 0 + { + return 1 as i32 != 0; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let mut proxyssl: *const ssl_connect_data = + &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data; + #[cfg(not(CURL_DISABLE_PROXY))] + if !((*(*proxyssl).backend).handle).is_null() + && SSL_pending((*(*proxyssl).backend).handle) != 0 + { + return 1 as i32 != 0; + } + return 0 as i32 != 0; + } + } + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_send( + mut data: *mut Curl_easy, + mut sockindex: i32, + mut mem: *const libc::c_void, + mut len: size_t, + mut curlcode: *mut CURLcode, + ) -> ssize_t { + /* SSL_write() is said to return 'int' while write() and send() returns + 'size_t' */ + let mut err: i32 = 0; + let mut error_buffer: [libc::c_char; 256] = [0; 256]; + let mut sslerror: u64 = 0; + let mut memlen: i32 = 0; + let mut rc: i32 = 0; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + ERR_clear_error(); + } + const INT_MAX: size_t = 2147483647 as size_t; + memlen = if len > INT_MAX { + INT_MAX as i32 + } else { + len as i32 + }; + unsafe { + (*(*conn).ssl[0 as usize].backend).logger = data; + } + rc = unsafe { SSL_write((*backend).handle, mem, memlen) }; + if rc <= 0 as i32 { + err = unsafe { SSL_get_error((*backend).handle, rc) }; + match err { + 2 | 3 => { + /* The operation did not complete; the same TLS/SSL I/O function + should be called again later. This is basically an EWOULDBLOCK + equivalent. */ + unsafe { + *curlcode = CURLE_AGAIN; + } + return -(1 as i32) as ssize_t; + } + 5 => { + let mut sockerr: i32 = unsafe { *__errno_location() }; + sslerror = unsafe { ERR_get_error() }; + if sslerror != 0 { + ossl_strerror( + sslerror, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } else if sockerr != 0 { + unsafe { + Curl_strerror( + sockerr, error_buffer.as_mut_ptr(), - sockerr_0, + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, ); - *curlcode = CURLE_RECV_ERROR; - return -(1 as i32) as ssize_t; - } - } - } - } - } - } - return nread; -} -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_version(mut buffer: *mut libc::c_char, mut size: size_t) -> size_t { - // TODO 这里有一个很长的条件编译 - // if cfg!(LIBRESSL_VERSION_NUMBER){ - // if cfg!(LIBRESSL_VERSION_NUMBER_LT_0X2070100FL){ - // /* - // return msnprintf(buffer, size, "%s/%lx.%lx.%lx", - // OSSL_PACKAGE, - // (LIBRESSL_VERSION_NUMBER>>28)&0xf, - // (LIBRESSL_VERSION_NUMBER>>20)&0xff, - // (LIBRESSL_VERSION_NUMBER>>12)&0xff); - // */ - // } - // else{ - // /* - // char *p; - // int count; - // const char *ver = OpenSSL_version(OPENSSL_VERSION); - // const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ - // if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) { - // ver += sizeof(expected) - 1; - // } - // count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); - // for(p = buffer; *p; ++p) { - // if(ISSPACE(*p)) - // *p = '_'; - // } - // return count; - // */ - // } - // } - // else if cfg!(OPENSSL_IS_BORINGSSL){ - // // return msnprintf(buffer, size, OSSL_PACKAGE); - - // } - // else if cfg!(all(HAVE_OPENSSL_VERSION, OPENSSL_VERSION_STRING)){ - // /* - // return msnprintf(buffer, size, "%s/%s", - // OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); - // */ - // } - //else{ - /* not LibreSSL, BoringSSL and not using OpenSSL_version */ - let mut sub: [libc::c_char; 3] = [0; 3]; - let mut ssleay_value: u64 = 0; - sub[2 as i32 as usize] = '\0' as libc::c_char; - sub[1 as i32 as usize] = '\0' as libc::c_char; - ssleay_value = unsafe { OpenSSL_version_num() }; - if ssleay_value < 0x906000 as u64 { - ssleay_value = 0x1010106f as u64; - sub[0 as usize] = '\0' as libc::c_char; - } else if ssleay_value & 0xff0 as i32 as u64 != 0 { - let mut minor_ver: i32 = (ssleay_value >> 4 as i32 & 0xff as u64) as i32; - if minor_ver > 26 as i32 { - /* handle extended version introduced for 0.9.8za */ - sub[1 as usize] = - ((minor_ver - 1 as i32) % 26 as i32 + 'a' as i32 + 1 as i32) as libc::c_char; - sub[0 as usize] = 'z' as libc::c_char; - } else { - sub[0 as usize] = (minor_ver + 'a' as i32 - 1 as i32) as libc::c_char; - } - } else { - sub[0 as usize] = '\0' as libc::c_char; - } - #[cfg(not(OPENSSL_FIPS))] - return unsafe { - curl_msnprintf( - buffer, - size, - b"%s/%lx.%lx.%lx%s\0" as *const u8 as *const libc::c_char, - b"OpenSSL\0" as *const u8 as *const libc::c_char, - ssleay_value >> 28 as i32 & 0xf as u64, - ssleay_value >> 20 as i32 & 0xff as u64, - ssleay_value >> 12 as i32 & 0xff as u64, - sub.as_mut_ptr(), - ) as size_t - }; - #[cfg(OPENSSL_FIPS)] - return unsafe { - curl_msnprintf( - buffer, - size, - b"%s/%lx.%lx.%lx%s\0" as *const u8 as *const libc::c_char, - b"-fips\0" as *const u8 as *const libc::c_char, - b"OpenSSL\0" as *const u8 as *const libc::c_char, - ssleay_value >> 28 as i32 & 0xf as u64, - ssleay_value >> 20 as i32 & 0xff as u64, - ssleay_value >> 12 as i32 & 0xff as u64, - sub.as_mut_ptr(), - ) as size_t - }; - //} -} -/* can be called with data == NULL */ -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_random( - mut data: *mut Curl_easy, - mut entropy: *mut u8, - mut length: size_t, -) -> CURLcode { - let mut rc: i32 = 0; - if !data.is_null() { - if ossl_seed(data) as u64 != 0 { - /* Initiate the seed if not already done */ - return CURLE_FAILED_INIT; /* couldn't seed for some reason */ - } - } else if !rand_enough() { - return CURLE_FAILED_INIT; - } - /* RAND_bytes() returns 1 on success, 0 otherwise. */ - rc = unsafe { RAND_bytes(entropy, curlx_uztosi(length)) }; - return (if rc == 1 as i32 { - CURLE_OK as i32 - } else { - CURLE_FAILED_INIT as i32 - }) as CURLcode; -} - -#[cfg(not(OPENSSL_NO_SHA256))] -extern "C" fn ossl_sha256sum( - mut tmp: *const u8, - mut tmplen: size_t, - mut sha256sum: *mut u8, - mut unused: size_t, -) -> CURLcode { - let mut mdctx: *mut EVP_MD_CTX = 0 as *mut EVP_MD_CTX; - let mut len: u32 = 0 as u32; - mdctx = unsafe { EVP_MD_CTX_new() }; - if mdctx.is_null() { - return CURLE_OUT_OF_MEMORY; - } - unsafe { - EVP_DigestInit(mdctx, EVP_sha256()); - EVP_DigestUpdate(mdctx, tmp as *const libc::c_void, tmplen); - EVP_DigestFinal_ex(mdctx, sha256sum, &mut len); - EVP_MD_CTX_free(mdctx); - } - return CURLE_OK; -} -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_cert_status_request() -> bool { - // TODO - 4475 - if cfg!(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP))) { - return 1 as i32 != 0; - } else { - return 0 as i32 != 0; - } -} -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_get_internals( - mut connssl: *mut ssl_connect_data, - mut info: CURLINFO, -) -> *mut libc::c_void { - unsafe { - let mut backend: *mut ssl_backend_data = (*connssl).backend; - return if info as u32 == CURLINFO_TLS_SESSION as u32 { - (*backend).ctx as *mut libc::c_void - } else { - (*backend).handle as *mut libc::c_void - }; - } -} -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_associate_connection( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) { - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - if unsafe { ((*backend).handle).is_null() } { - /* If we don't have SSL context, do nothing. */ - return; - } - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*data).set.proxy_ssl.primary).sessionid() as i32 - } else { - ((*data).set.ssl.primary).sessionid() as i32 - } != 0; - - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = ((*data).set.ssl.primary).sessionid() != 0; - - if SSL_SET_OPTION_primary_sessionid { - let mut data_idx: i32 = ossl_get_ssl_data_index(); - let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); - let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); - let mut proxy_idx: i32 = ossl_get_proxy_index(); - if data_idx >= 0 as i32 - && connectdata_idx >= 0 as i32 - && sockindex_idx >= 0 as i32 - && proxy_idx >= 0 as i32 - { - /* Store the data needed for the "new session" callback. - * The sockindex is stored as a pointer to an array element. */ - - SSL_set_ex_data((*backend).handle, data_idx, data as *mut libc::c_void); - SSL_set_ex_data( - (*backend).handle, - connectdata_idx, - conn as *mut libc::c_void, - ); - SSL_set_ex_data( - (*backend).handle, - sockindex_idx, - ((*conn).sock).as_mut_ptr().offset(sockindex as isize) as *mut libc::c_void, - ); - #[cfg(not(CURL_DISABLE_PROXY))] - SSL_set_ex_data( - (*backend).handle, - proxy_idx, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - 1 as *mut libc::c_void - } else { - 0 as *mut libc::c_void - }, - ); - // TODO - 4516 - #[cfg(CURL_DISABLE_PROXY)] - SSL_set_ex_data((*backend).handle, proxy_idx, 0 as *mut libc::c_void); - } - } - } -} - -/* - * Starting with TLS 1.3, the ossl_new_session_cb callback gets called after - * the handshake. If the transfer that sets up the callback gets killed before - * this callback arrives, we must make sure to properly clear the data to - * avoid UAF problems. A future optimization could be to instead store another - * transfer that might still be using the same connection. - */ -#[cfg(USE_OPENSSL)] -extern "C" fn ossl_disassociate_connection(mut data: *mut Curl_easy, mut sockindex: i32) { - let mut conn: *mut connectdata = unsafe { (*data).conn }; - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - /* If we don't have SSL context, do nothing. */ - if unsafe { ((*backend).handle).is_null() } { - return; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } - } else { - unsafe { ((*data).set.ssl.primary).sessionid() as i32 } - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() } != 0; - if SSL_SET_OPTION_primary_sessionid { - let mut data_idx: i32 = ossl_get_ssl_data_index(); - let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); - let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); - let mut proxy_idx: i32 = ossl_get_proxy_index(); - if data_idx >= 0 as i32 - && connectdata_idx >= 0 as i32 - && sockindex_idx >= 0 as i32 - && proxy_idx >= 0 as i32 - { - /* Disable references to data in "new session" callback to avoid - * accessing a stale pointer. */ - unsafe { - SSL_set_ex_data((*backend).handle, data_idx, 0 as *mut libc::c_void); - SSL_set_ex_data((*backend).handle, connectdata_idx, 0 as *mut libc::c_void); - SSL_set_ex_data((*backend).handle, sockindex_idx, 0 as *mut libc::c_void); - SSL_set_ex_data((*backend).handle, proxy_idx, 0 as *mut libc::c_void); - } - } - } -} - -#[no_mangle] -pub static mut Curl_ssl_openssl: Curl_ssl = Curl_ssl { - info: { - curl_ssl_backend { - id: CURLSSLBACKEND_OPENSSL, - name: b"openssl\0" as *const u8 as *const libc::c_char, - } - }, - supports: ((1 as i32) << 0 as i32 - | (1 as i32) << 6 as i32 - | (1 as i32) << 1 as i32 - | (1 as i32) << 2 as i32 - | (1 as i32) << 3 as i32 - | (1 as i32) << 5 as i32 - | (1 as i32) << 4 as i32) as u32, - sizeof_ssl_backend_data: ::std::mem::size_of::() as u64, - init: Some(ossl_init as unsafe extern "C" fn() -> i32), - cleanup: Some(ossl_cleanup as unsafe extern "C" fn() -> ()), - version: Some(ossl_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t), - check_cxn: Some(ossl_check_cxn as unsafe extern "C" fn(*mut connectdata) -> i32), - shut_down: Some( - ossl_shutdown as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> i32, - ), - data_pending: Some(ossl_data_pending as unsafe extern "C" fn(*const connectdata, i32) -> bool), - random: Some(ossl_random as unsafe extern "C" fn(*mut Curl_easy, *mut u8, size_t) -> CURLcode), - cert_status_request: Some(ossl_cert_status_request as unsafe extern "C" fn() -> bool), - connect_blocking: Some( - ossl_connect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> CURLcode, - ), - connect_nonblocking: Some( - ossl_connect_nonblocking - as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32, *mut bool) -> CURLcode, - ), - getsock: Some( - Curl_ssl_getsock as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> i32, - ), - get_internals: Some( - ossl_get_internals - as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, - ), - close_one: Some( - ossl_close as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), - ), - close_all: Some(ossl_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), - session_free: Some(ossl_session_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), - set_engine: Some( - ossl_set_engine as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, - ), - set_engine_default: Some( - ossl_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, - ), - engines_list: Some( - ossl_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, - ), - false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), - sha256sum: Some( - ossl_sha256sum as unsafe extern "C" fn(*const u8, size_t, *mut u8, size_t) -> CURLcode, - ), - associate_connection: Some( - ossl_associate_connection - as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), - ), - disassociate_connection: Some( - ossl_disassociate_connection as unsafe extern "C" fn(*mut Curl_easy, i32) -> (), - ), -}; + } + } else { + unsafe { + strncpy( + error_buffer.as_mut_ptr(), + SSL_ERROR_to_str(err), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + error_buffer[(::std::mem::size_of::<[libc::c_char; 256]>() as u64) + .wrapping_sub(1 as u64) as usize] = '\0' as i32 as libc::c_char; + } + unsafe { + Curl_failf( + data, + b"OpenSSL SSL_write: %s, errno %d\0" as *const u8 as *const libc::c_char, + error_buffer.as_mut_ptr(), + sockerr, + ); + *curlcode = CURLE_SEND_ERROR; + } + return -(1 as i32) as ssize_t; + } + 1 => { + /* A failure in the SSL library occurred, usually a protocol error. + The OpenSSL error queue contains more information on the error. */ + sslerror = unsafe { ERR_get_error() }; + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let CURL_DISABLE_PROXY_flag_4 = (*conn).proxy_ssl[sockindex as usize].state + as u32 + == ssl_connection_complete as u32; + #[cfg(CURL_DISABLE_PROXY)] + let CURL_DISABLE_PROXY_flag_4 = true; + if (sslerror >> 24 as i64 & 0xff as u64) as i32 == 20 as i32 + && (sslerror & 0xfff as u64) as i32 == 128 as i32 + && (*conn).ssl[sockindex as usize].state as u32 + == ssl_connection_complete as u32 + && CURL_DISABLE_PROXY_flag_4 + { + let mut ver: [libc::c_char; 120] = [0; 120]; + ossl_version( + ver.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 120]>() as u64, + ); + Curl_failf( + data, + b"Error: %s does not support double SSL tunneling.\0" as *const u8 + as *const libc::c_char, + ver.as_mut_ptr(), + ); + } else { + Curl_failf( + data, + b"SSL_write() error: %s\0" as *const u8 as *const libc::c_char, + ossl_strerror( + sslerror, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + + *curlcode = CURLE_SEND_ERROR; + } + return -(1 as i32) as ssize_t; + } + _ => {} + } + /* a true error */ + unsafe { + Curl_failf( + data, + b"OpenSSL SSL_write: %s, errno %d\0" as *const u8 as *const libc::c_char, + SSL_ERROR_to_str(err), + *__errno_location(), + ); + *curlcode = CURLE_SEND_ERROR; + } + return -(1 as i32) as ssize_t; + } + unsafe { + *curlcode = CURLE_OK; + } + return rc as ssize_t; + } + + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_recv( + mut data: *mut Curl_easy, + mut num: i32, + mut buf: *mut libc::c_char, + mut buffersize: size_t, + mut curlcode: *mut CURLcode, + ) -> ssize_t { + let mut error_buffer: [libc::c_char; 256] = [0; 256]; + let mut sslerror: u64 = 0; + let mut nread: ssize_t = 0; + let mut buffsize: i32 = 0; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) } as *mut ssl_connect_data; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + ERR_clear_error(); + } + const INT_MAX: size_t = 2147483647 as size_t; + buffsize = if buffersize > INT_MAX { + INT_MAX as i32 + } else { + buffersize as i32 + }; + unsafe { + (*(*conn).ssl[0 as usize].backend).logger = data; + nread = SSL_read((*backend).handle, buf as *mut libc::c_void, buffsize) as ssize_t; + } + if nread <= 0 as i64 { + let mut err: i32 = unsafe { SSL_get_error((*backend).handle, nread as i32) }; + match err { + 0 => {} + 6 => { + if num == 0 as i32 { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + unsafe { + Curl_conncontrol(conn, 1 as i32); + } + + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + unsafe { + Curl_conncontrol( + conn, + 1 as i32, + b"TLS close_notify\0" as *const u8 as *const libc::c_char, + ); + } + } + } + 2 | 3 => { + unsafe { + *curlcode = CURLE_AGAIN; + } + return -(1 as i32) as ssize_t; + } + _ => { + sslerror = unsafe { ERR_get_error() }; + if nread < 0 as i64 || sslerror != 0 { + let mut sockerr: i32 = unsafe { *__errno_location() }; + if sslerror != 0 { + ossl_strerror( + sslerror, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } else if sockerr != 0 && err == 5 as i32 { + unsafe { + Curl_strerror( + sockerr, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + } else { + unsafe { + strncpy( + error_buffer.as_mut_ptr(), + SSL_ERROR_to_str(err), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + error_buffer[(::std::mem::size_of::<[libc::c_char; 256]>() as u64) + .wrapping_sub(1 as u64) + as usize] = '\0' as i32 as libc::c_char; + } + unsafe { + Curl_failf( + data, + b"OpenSSL SSL_read: %s, errno %d\0" as *const u8 as *const libc::c_char, + error_buffer.as_mut_ptr(), + sockerr, + ); + *curlcode = CURLE_RECV_ERROR; + } + return -(1 as i32) as ssize_t; + /* For debug builds be a little stricter and error on any + SSL_ERROR_SYSCALL. For example a server may have closed the connection + abruptly without a close_notify alert. For compatibility with older + peers we don't do this by default. #4624 + + We can use this to gauge how many users may be affected, and + if it goes ok eventually transition to allow in dev and release with + the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ + #[cfg(DEBUGBUILD)] + unsafe { + if err == 5 as i32 { + let mut sockerr_0: i32 = *__errno_location(); + if sockerr_0 != 0 { + Curl_strerror( + sockerr_0, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } else { + curl_msnprintf( + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + b"Connection closed abruptly\0" as *const u8 + as *const libc::c_char, + ); + } + Curl_failf( + data, + b"OpenSSL SSL_read: %s, errno %d (Fatal because this is a curl debug build)\0" + as *const u8 as *const libc::c_char, + error_buffer.as_mut_ptr(), + sockerr_0, + ); + *curlcode = CURLE_RECV_ERROR; + return -(1 as i32) as ssize_t; + } + } + } + } + } + } + return nread; + } + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_version(mut buffer: *mut libc::c_char, mut size: size_t) -> size_t { + // TODO 这里有一个很长的条件编译 + // if cfg!(LIBRESSL_VERSION_NUMBER){ + // if cfg!(LIBRESSL_VERSION_NUMBER_LT_0X2070100FL){ + // /* + // return msnprintf(buffer, size, "%s/%lx.%lx.%lx", + // OSSL_PACKAGE, + // (LIBRESSL_VERSION_NUMBER>>28)&0xf, + // (LIBRESSL_VERSION_NUMBER>>20)&0xff, + // (LIBRESSL_VERSION_NUMBER>>12)&0xff); + // */ + // } + // else{ + // /* + // char *p; + // int count; + // const char *ver = OpenSSL_version(OPENSSL_VERSION); + // const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ + // if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) { + // ver += sizeof(expected) - 1; + // } + // count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); + // for(p = buffer; *p; ++p) { + // if(ISSPACE(*p)) + // *p = '_'; + // } + // return count; + // */ + // } + // } + // else if cfg!(OPENSSL_IS_BORINGSSL){ + // // return msnprintf(buffer, size, OSSL_PACKAGE); + + // } + // else if cfg!(all(HAVE_OPENSSL_VERSION, OPENSSL_VERSION_STRING)){ + // /* + // return msnprintf(buffer, size, "%s/%s", + // OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); + // */ + // } + //else{ + /* not LibreSSL, BoringSSL and not using OpenSSL_version */ + let mut sub: [libc::c_char; 3] = [0; 3]; + let mut ssleay_value: u64 = 0; + sub[2 as i32 as usize] = '\0' as libc::c_char; + sub[1 as i32 as usize] = '\0' as libc::c_char; + ssleay_value = unsafe { OpenSSL_version_num() }; + if ssleay_value < 0x906000 as u64 { + ssleay_value = 0x1010106f as u64; + sub[0 as usize] = '\0' as libc::c_char; + } else if ssleay_value & 0xff0 as i32 as u64 != 0 { + let mut minor_ver: i32 = (ssleay_value >> 4 as i32 & 0xff as u64) as i32; + if minor_ver > 26 as i32 { + /* handle extended version introduced for 0.9.8za */ + sub[1 as usize] = + ((minor_ver - 1 as i32) % 26 as i32 + 'a' as i32 + 1 as i32) as libc::c_char; + sub[0 as usize] = 'z' as libc::c_char; + } else { + sub[0 as usize] = (minor_ver + 'a' as i32 - 1 as i32) as libc::c_char; + } + } else { + sub[0 as usize] = '\0' as libc::c_char; + } + #[cfg(not(OPENSSL_FIPS))] + return unsafe { + curl_msnprintf( + buffer, + size, + b"%s/%lx.%lx.%lx%s\0" as *const u8 as *const libc::c_char, + b"OpenSSL\0" as *const u8 as *const libc::c_char, + ssleay_value >> 28 as i32 & 0xf as u64, + ssleay_value >> 20 as i32 & 0xff as u64, + ssleay_value >> 12 as i32 & 0xff as u64, + sub.as_mut_ptr(), + ) as size_t + }; + #[cfg(OPENSSL_FIPS)] + return unsafe { + curl_msnprintf( + buffer, + size, + b"%s/%lx.%lx.%lx%s\0" as *const u8 as *const libc::c_char, + b"-fips\0" as *const u8 as *const libc::c_char, + b"OpenSSL\0" as *const u8 as *const libc::c_char, + ssleay_value >> 28 as i32 & 0xf as u64, + ssleay_value >> 20 as i32 & 0xff as u64, + ssleay_value >> 12 as i32 & 0xff as u64, + sub.as_mut_ptr(), + ) as size_t + }; + //} + } + /* can be called with data == NULL */ + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_random( + mut data: *mut Curl_easy, + mut entropy: *mut u8, + mut length: size_t, + ) -> CURLcode { + let mut rc: i32 = 0; + if !data.is_null() { + if ossl_seed(data) as u64 != 0 { + /* Initiate the seed if not already done */ + return CURLE_FAILED_INIT; /* couldn't seed for some reason */ + } + } else if !rand_enough() { + return CURLE_FAILED_INIT; + } + /* RAND_bytes() returns 1 on success, 0 otherwise. */ + rc = unsafe { RAND_bytes(entropy, curlx_uztosi(length)) }; + return (if rc == 1 as i32 { + CURLE_OK as i32 + } else { + CURLE_FAILED_INIT as i32 + }) as CURLcode; + } + + #[cfg(not(OPENSSL_NO_SHA256))] + extern "C" fn ossl_sha256sum( + mut tmp: *const u8, + mut tmplen: size_t, + mut sha256sum: *mut u8, + mut unused: size_t, + ) -> CURLcode { + let mut mdctx: *mut EVP_MD_CTX = 0 as *mut EVP_MD_CTX; + let mut len: u32 = 0 as u32; + mdctx = unsafe { EVP_MD_CTX_new() }; + if mdctx.is_null() { + return CURLE_OUT_OF_MEMORY; + } + unsafe { + EVP_DigestInit(mdctx, EVP_sha256()); + EVP_DigestUpdate(mdctx, tmp as *const libc::c_void, tmplen); + EVP_DigestFinal_ex(mdctx, sha256sum, &mut len); + EVP_MD_CTX_free(mdctx); + } + return CURLE_OK; + } + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_cert_status_request() -> bool { + // TODO - 4475 + if cfg!(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP))) { + return 1 as i32 != 0; + } else { + return 0 as i32 != 0; + } + } + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_get_internals( + mut connssl: *mut ssl_connect_data, + mut info: CURLINFO, + ) -> *mut libc::c_void { + unsafe { + let mut backend: *mut ssl_backend_data = (*connssl).backend; + return if info as u32 == CURLINFO_TLS_SESSION as u32 { + (*backend).ctx as *mut libc::c_void + } else { + (*backend).handle as *mut libc::c_void + }; + } + } + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_associate_connection( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) { + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + if unsafe { ((*backend).handle).is_null() } { + /* If we don't have SSL context, do nothing. */ + return; + } + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*data).set.proxy_ssl.primary).sessionid() as i32 + } else { + ((*data).set.ssl.primary).sessionid() as i32 + } != 0; + + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = ((*data).set.ssl.primary).sessionid() != 0; + + if SSL_SET_OPTION_primary_sessionid { + let mut data_idx: i32 = ossl_get_ssl_data_index(); + let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); + let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); + let mut proxy_idx: i32 = ossl_get_proxy_index(); + if data_idx >= 0 as i32 + && connectdata_idx >= 0 as i32 + && sockindex_idx >= 0 as i32 + && proxy_idx >= 0 as i32 + { + /* Store the data needed for the "new session" callback. + * The sockindex is stored as a pointer to an array element. */ + + SSL_set_ex_data((*backend).handle, data_idx, data as *mut libc::c_void); + SSL_set_ex_data( + (*backend).handle, + connectdata_idx, + conn as *mut libc::c_void, + ); + SSL_set_ex_data( + (*backend).handle, + sockindex_idx, + ((*conn).sock).as_mut_ptr().offset(sockindex as isize) as *mut libc::c_void, + ); + #[cfg(not(CURL_DISABLE_PROXY))] + SSL_set_ex_data( + (*backend).handle, + proxy_idx, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + 1 as *mut libc::c_void + } else { + 0 as *mut libc::c_void + }, + ); + // TODO - 4516 + #[cfg(CURL_DISABLE_PROXY)] + SSL_set_ex_data((*backend).handle, proxy_idx, 0 as *mut libc::c_void); + } + } + } + } + + /* + * Starting with TLS 1.3, the ossl_new_session_cb callback gets called after + * the handshake. If the transfer that sets up the callback gets killed before + * this callback arrives, we must make sure to properly clear the data to + * avoid UAF problems. A future optimization could be to instead store another + * transfer that might still be using the same connection. + */ + #[cfg(USE_OPENSSL)] + extern "C" fn ossl_disassociate_connection(mut data: *mut Curl_easy, mut sockindex: i32) { + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + /* If we don't have SSL context, do nothing. */ + if unsafe { ((*backend).handle).is_null() } { + return; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } + } else { + unsafe { ((*data).set.ssl.primary).sessionid() as i32 } + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() } != 0; + if SSL_SET_OPTION_primary_sessionid { + let mut data_idx: i32 = ossl_get_ssl_data_index(); + let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); + let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); + let mut proxy_idx: i32 = ossl_get_proxy_index(); + if data_idx >= 0 as i32 + && connectdata_idx >= 0 as i32 + && sockindex_idx >= 0 as i32 + && proxy_idx >= 0 as i32 + { + /* Disable references to data in "new session" callback to avoid + * accessing a stale pointer. */ + unsafe { + SSL_set_ex_data((*backend).handle, data_idx, 0 as *mut libc::c_void); + SSL_set_ex_data((*backend).handle, connectdata_idx, 0 as *mut libc::c_void); + SSL_set_ex_data((*backend).handle, sockindex_idx, 0 as *mut libc::c_void); + SSL_set_ex_data((*backend).handle, proxy_idx, 0 as *mut libc::c_void); + } + } + } + } + + #[no_mangle] + pub static mut Curl_ssl_openssl: Curl_ssl = Curl_ssl { + info: { + curl_ssl_backend { + id: CURLSSLBACKEND_OPENSSL, + name: b"openssl\0" as *const u8 as *const libc::c_char, + } + }, + supports: ((1 as i32) << 0 as i32 + | (1 as i32) << 6 as i32 + | (1 as i32) << 1 as i32 + | (1 as i32) << 2 as i32 + | (1 as i32) << 3 as i32 + | (1 as i32) << 5 as i32 + | (1 as i32) << 4 as i32) as u32, + sizeof_ssl_backend_data: ::std::mem::size_of::() as u64, + init: Some(ossl_init as unsafe extern "C" fn() -> i32), + cleanup: Some(ossl_cleanup as unsafe extern "C" fn() -> ()), + version: Some(ossl_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t), + check_cxn: Some(ossl_check_cxn as unsafe extern "C" fn(*mut connectdata) -> i32), + shut_down: Some( + ossl_shutdown as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> i32, + ), + data_pending: Some(ossl_data_pending as unsafe extern "C" fn(*const connectdata, i32) -> bool), + random: Some(ossl_random as unsafe extern "C" fn(*mut Curl_easy, *mut u8, size_t) -> CURLcode), + cert_status_request: Some(ossl_cert_status_request as unsafe extern "C" fn() -> bool), + connect_blocking: Some( + ossl_connect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> CURLcode, + ), + connect_nonblocking: Some( + ossl_connect_nonblocking + as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32, *mut bool) -> CURLcode, + ), + getsock: Some( + Curl_ssl_getsock as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> i32, + ), + get_internals: Some( + ossl_get_internals + as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, + ), + close_one: Some( + ossl_close as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), + ), + close_all: Some(ossl_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), + session_free: Some(ossl_session_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), + set_engine: Some( + ossl_set_engine as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, + ), + set_engine_default: Some( + ossl_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, + ), + engines_list: Some( + ossl_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, + ), + false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), + sha256sum: Some( + ossl_sha256sum as unsafe extern "C" fn(*const u8, size_t, *mut u8, size_t) -> CURLcode, + ), + associate_connection: Some( + ossl_associate_connection + as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), + ), + disassociate_connection: Some( + ossl_disassociate_connection as unsafe extern "C" fn(*mut Curl_easy, i32) -> (), + ), + }; + \ No newline at end of file diff --git a/rust/rust_project/src/vtls/vtls.rs b/rust/rust_project/src/vtls/vtls.rs old mode 100755 new mode 100644 index 21dbd2c..2bcfc08 --- a/rust/rust_project/src/vtls/vtls.rs +++ b/rust/rust_project/src/vtls/vtls.rs @@ -824,18 +824,18 @@ pub extern "C" fn Curl_ssl_getsessionid( } else { unsafe { __assert_fail( - b"((CURLPROXY_HTTPS == conn->http_proxy.proxytype && ssl_connection_complete != conn->proxy_ssl[conn->sock[1] == -1 ? 0 : 1].state) ? data->set.proxy_ssl.primary.sessionid : data->set.ssl.primary.sessionid)\0" - as *const u8 as *const libc::c_char, - b"vtls/vtls.c\0" as *const u8 as *const libc::c_char, - 424 as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 107], - &[libc::c_char; 107], - >( - b"_Bool Curl_ssl_getsessionid(struct Curl_easy *, struct connectdata *, const _Bool, void **, size_t *, int)\0", - )) - .as_ptr(), - ); + b"((CURLPROXY_HTTPS == conn->http_proxy.proxytype && ssl_connection_complete != conn->proxy_ssl[conn->sock[1] == -1 ? 0 : 1].state) ? data->set.proxy_ssl.primary.sessionid : data->set.ssl.primary.sessionid)\0" + as *const u8 as *const libc::c_char, + b"vtls/vtls.c\0" as *const u8 as *const libc::c_char, + 424 as libc::c_uint, + (*::std::mem::transmute::< + &[u8; 107], + &[libc::c_char; 107], + >( + b"_Bool Curl_ssl_getsessionid(struct Curl_easy *, struct connectdata *, const _Bool, void **, size_t *, int)\0", + )) + .as_ptr(), + ); } } #[cfg(not(CURL_DISABLE_PROXY))] @@ -1049,18 +1049,18 @@ pub extern "C" fn Curl_ssl_addsessionid( } else { unsafe { __assert_fail( - b"((CURLPROXY_HTTPS == conn->http_proxy.proxytype && ssl_connection_complete != conn->proxy_ssl[conn->sock[1] == -1 ? 0 : 1].state) ? data->set.proxy_ssl.primary.sessionid : data->set.ssl.primary.sessionid)\0" - as *const u8 as *const libc::c_char, - b"vtls/vtls.c\0" as *const u8 as *const libc::c_char, - 544 as i32 as libc::c_uint, - (*::std::mem::transmute::< - &[u8; 107], - &[libc::c_char; 107], - >( - b"CURLcode Curl_ssl_addsessionid(struct Curl_easy *, struct connectdata *, const _Bool, void *, size_t, int)\0", - )) - .as_ptr(), - ); + b"((CURLPROXY_HTTPS == conn->http_proxy.proxytype && ssl_connection_complete != conn->proxy_ssl[conn->sock[1] == -1 ? 0 : 1].state) ? data->set.proxy_ssl.primary.sessionid : data->set.ssl.primary.sessionid)\0" + as *const u8 as *const libc::c_char, + b"vtls/vtls.c\0" as *const u8 as *const libc::c_char, + 544 as i32 as libc::c_uint, + (*::std::mem::transmute::< + &[u8; 107], + &[libc::c_char; 107], + >( + b"CURLcode Curl_ssl_addsessionid(struct Curl_easy *, struct connectdata *, const _Bool, void *, size_t, int)\0", + )) + .as_ptr(), + ); } } match () { diff --git a/rust/rust_project/src/vtls/wolfssl.rs b/rust/rust_project/src/vtls/wolfssl.rs old mode 100755 new mode 100644 index dec560f..f70be8a --- a/rust/rust_project/src/vtls/wolfssl.rs +++ b/rust/rust_project/src/vtls/wolfssl.rs @@ -1136,14 +1136,14 @@ extern "C" fn wolfssl_connect_step3( } else { unsafe { __assert_fail( - b"ssl_connect_3 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, - b"vtls/wolfssl.c\0" as *const u8 as *const libc::c_char, - 730 as libc::c_int as libc::c_uint, - (*::std::mem::transmute::<&[u8; 78], &[libc::c_char; 78]>( - b"CURLcode wolfssl_connect_step3(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); + b"ssl_connect_3 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, + b"vtls/wolfssl.c\0" as *const u8 as *const libc::c_char, + 730 as libc::c_int as libc::c_uint, + (*::std::mem::transmute::<&[u8; 78], &[libc::c_char; 78]>( + b"CURLcode wolfssl_connect_step3(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); } } #[cfg(not(CURL_DISABLE_PROXY))] -- Gitee From e954bf746af482330aed3ff144c02fc222a1ebbb Mon Sep 17 00:00:00 2001 From: pNext <843609378@qq.com> Date: Fri, 30 Dec 2022 11:49:18 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96.rs=EF=BC=8C?= =?UTF-8?q?=E5=9C=A8.c=E4=B8=AD=E8=A1=A5=E5=85=85=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/macros_to_rust.c | 9 + rust/rust_project/src/ftp.rs | 1152 +-- rust/rust_project/src/http.rs | 9318 ++++++++--------- rust/rust_project/src/http_digest.rs | 42 +- rust/rust_project/src/http_ntlm.rs | 144 +- rust/rust_project/src/http_proxy.rs | 3232 +++--- rust/rust_project/src/vtls/gtls.rs | 325 +- rust/rust_project/src/vtls/openssl.rs | 12795 ++++++++++++------------ rust/rust_project/src/vtls/rustls.rs | 228 +- 9 files changed, 13732 insertions(+), 13513 deletions(-) diff --git a/lib/macros_to_rust.c b/lib/macros_to_rust.c index 428710e..68857f6 100644 --- a/lib/macros_to_rust.c +++ b/lib/macros_to_rust.c @@ -1524,4 +1524,13 @@ int get_THREADING_SUPPORT() #else return 0; #endif +} + +int get_USE_QUICHE() +{ +#ifdef USE_QUICHE + return 1; +#else + return 0; +#endif } \ No newline at end of file diff --git a/rust/rust_project/src/ftp.rs b/rust/rust_project/src/ftp.rs index 00eb693..b57484d 100644 --- a/rust/rust_project/src/ftp.rs +++ b/rust/rust_project/src/ftp.rs @@ -164,15 +164,16 @@ pub static mut Curl_handler_ftps: Curl_handler = unsafe { } }; extern "C" fn close_secondarysocket(mut data: *mut Curl_easy, mut conn: *mut connectdata) { - - if unsafe{-(1 as i32) != (*conn).sock[1 as usize] }{ - unsafe{ + if unsafe { -(1 as i32) != (*conn).sock[1 as usize] } { + unsafe { Curl_closesocket(data, conn, (*conn).sock[1 as usize]); (*conn).sock[1 as usize] = -(1 as i32); - } } - unsafe{(*conn).bits.tcpconnect[1 as usize] = 0 as i32 != 0;} - unsafe{ + } + unsafe { + (*conn).bits.tcpconnect[1 as usize] = 0 as i32 != 0; + } + unsafe { match () { #[cfg(not(CURL_DISABLE_PROXY))] _ => { @@ -182,7 +183,6 @@ extern "C" fn close_secondarysocket(mut data: *mut Curl_easy, mut conn: *mut con _ => {} } } - } /* @@ -196,11 +196,10 @@ extern "C" fn close_secondarysocket(mut data: *mut Curl_easy, mut conn: *mut con * following define named CURL_FTP_HTTPSTYLE_HEAD. */ extern "C" fn freedirs(mut ftpc: *mut ftp_conn) { - - if unsafe{!((*ftpc).dirs).is_null()} { - let mut i: i32 = 0; - i = 0 as i32; - unsafe{ + if unsafe { !((*ftpc).dirs).is_null() } { + let mut i: i32 = 0; + i = 0 as i32; + unsafe { while i < (*ftpc).dirdepth { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( @@ -216,37 +215,54 @@ extern "C" fn freedirs(mut ftpc: *mut ftp_conn) { i += 1; } } - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")((*ftpc).dirs as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")((*ftpc).dirs as *mut libc::c_void); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( (*ftpc).dirs as *mut libc::c_void, 251 as i32, b"ftp.c\0" as *const u8 as *const libc::c_char, - );} - unsafe{(*ftpc).dirs = 0 as *mut *mut libc::c_char; - (*ftpc).dirdepth = 0 as i32;} + ); } - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")((*ftpc).file as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( + unsafe { + (*ftpc).dirs = 0 as *mut *mut libc::c_char; + (*ftpc).dirdepth = 0 as i32; + } + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")((*ftpc).file as *mut libc::c_void); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( (*ftpc).file as *mut libc::c_void, 255 as i32, b"ftp.c\0" as *const u8 as *const libc::c_char, - );} - unsafe{(*ftpc).file = 0 as *mut libc::c_char;} - #[cfg(not(CURLDEBUG))] - unsafe{Curl_cfree.expect("non-null function pointer")((*ftpc).newhost as *mut libc::c_void);} - #[cfg(CURLDEBUG)] - unsafe{curl_dbg_free( + ); + } + unsafe { + (*ftpc).file = 0 as *mut libc::c_char; + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")((*ftpc).newhost as *mut libc::c_void); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( (*ftpc).newhost as *mut libc::c_void, 258 as i32, b"ftp.c\0" as *const u8 as *const libc::c_char, - );} - /* no longer of any use */ - unsafe{(*ftpc).newhost = 0 as *mut libc::c_char;} - + ); + } + /* no longer of any use */ + unsafe { + (*ftpc).newhost = 0 as *mut libc::c_char; + } } /*********************************************************************** @@ -258,33 +274,36 @@ extern "C" fn freedirs(mut ftpc: *mut ftp_conn) { * */ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut sock: curl_socket_t =unsafe{ (*conn).sock[1 as usize]}; - let mut s: curl_socket_t = -(1 as i32); - #[cfg(ENABLE_IPV6)] - let mut add: Curl_sockaddr_storage =unsafe{ Curl_sockaddr_storage { + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut sock: curl_socket_t = unsafe { (*conn).sock[1 as usize] }; + let mut s: curl_socket_t = -(1 as i32); + #[cfg(ENABLE_IPV6)] + let mut add: Curl_sockaddr_storage = unsafe { + Curl_sockaddr_storage { buffer: C2RustUnnamed_9 { sa: sockaddr { sa_family: 0, sa_data: [0; 14], }, }, - }}; - #[cfg(not(ENABLE_IPV6))] - let mut add: sockaddr_in = unsafe{ sockaddr_in { + } + }; + #[cfg(not(ENABLE_IPV6))] + let mut add: sockaddr_in = unsafe { + sockaddr_in { sin_family: 0, sin_port: 0, sin_addr: in_addr { s_addr: 0 }, sin_zero: [0; 8], - }}; - #[cfg(ENABLE_IPV6)] - let mut size: curl_socklen_t = - ::std::mem::size_of::() as curl_socklen_t; - #[cfg(not(ENABLE_IPV6))] - let mut size: curl_socklen_t = - ::std::mem::size_of::() as u64 as curl_socklen_t; - #[cfg(ENABLE_IPV6)] - unsafe{ if 0 as i32 + } + }; + #[cfg(ENABLE_IPV6)] + let mut size: curl_socklen_t = ::std::mem::size_of::() as curl_socklen_t; + #[cfg(not(ENABLE_IPV6))] + let mut size: curl_socklen_t = ::std::mem::size_of::() as u64 as curl_socklen_t; + #[cfg(ENABLE_IPV6)] + unsafe { + if 0 as i32 == getsockname( sock, &mut add as *mut Curl_sockaddr_storage as *mut sockaddr, @@ -313,9 +332,11 @@ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { ); } } - }} - #[cfg(not(ENABLE_IPV6))] - unsafe{ if 0 as i32 + } + } + #[cfg(not(ENABLE_IPV6))] + unsafe { + if 0 as i32 == getsockname( sock, &mut add as *mut sockaddr_in as *mut sockaddr, @@ -330,7 +351,8 @@ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { ); } } - unsafe{ Curl_closesocket(data, conn, sock); /* close the first socket */ + unsafe { + Curl_closesocket(data, conn, sock); /* close the first socket */ if -(1 as i32) == s { Curl_failf( data, @@ -362,8 +384,7 @@ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { } } } - return CURLE_OK; - + return CURLE_OK; } /* @@ -376,33 +397,33 @@ extern "C" fn AcceptServerConnect(mut data: *mut Curl_easy) -> CURLcode { * */ extern "C" fn ftp_timeleft_accept(mut data: *mut Curl_easy) -> timediff_t { - let mut timeout_ms: timediff_t = 60000 as timediff_t; - let mut other: timediff_t = 0; - let mut now: curltime = curltime { - tv_sec: 0, - tv_usec: 0, - }; - if unsafe{(*data).set.accepttimeout > 0 as i64} { - unsafe{ - timeout_ms = (*data).set.accepttimeout;} - } - now = unsafe{Curl_now()}; - /* check if the generic timeout possibly is set shorter */ - other = unsafe{Curl_timeleft(data, &mut now, 0 as i32 != 0)}; - if other != 0 && other < timeout_ms { - /* note that this also works fine for when other happens to be negative - due to it already having elapsed */ - timeout_ms = other; - } else { - /* subtract elapsed time */ - timeout_ms -= unsafe{Curl_timediff(now, (*data).progress.t_acceptdata)}; - if timeout_ms == 0 { - /* avoid returning 0 as that means no timeout! */ - return -(1 as i32) as timediff_t; - } + let mut timeout_ms: timediff_t = 60000 as timediff_t; + let mut other: timediff_t = 0; + let mut now: curltime = curltime { + tv_sec: 0, + tv_usec: 0, + }; + if unsafe { (*data).set.accepttimeout > 0 as i64 } { + unsafe { + timeout_ms = (*data).set.accepttimeout; } - return timeout_ms; - + } + now = unsafe { Curl_now() }; + /* check if the generic timeout possibly is set shorter */ + other = unsafe { Curl_timeleft(data, &mut now, 0 as i32 != 0) }; + if other != 0 && other < timeout_ms { + /* note that this also works fine for when other happens to be negative + due to it already having elapsed */ + timeout_ms = other; + } else { + /* subtract elapsed time */ + timeout_ms -= unsafe { Curl_timediff(now, (*data).progress.t_acceptdata) }; + if timeout_ms == 0 { + /* avoid returning 0 as that means no timeout! */ + return -(1 as i32) as timediff_t; + } + } + return timeout_ms; } /*********************************************************************** * @@ -414,48 +435,58 @@ extern "C" fn ftp_timeleft_accept(mut data: *mut Curl_easy) -> timediff_t { * */ extern "C" fn ReceivedServerConnect(mut data: *mut Curl_easy, mut received: *mut bool) -> CURLcode { - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ctrl_sock: curl_socket_t =unsafe{ (*conn).sock[0 as usize]}; - let mut data_sock: curl_socket_t = unsafe{(*conn).sock[1 as usize]}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; - let mut result: i32 = 0; - let mut timeout_ms: timediff_t = 0; - let mut nread: ssize_t = 0; - let mut ftpcode: i32 = 0; - unsafe{*received = 0 as i32 != 0;} - timeout_ms = ftp_timeleft_accept(data); - unsafe{Curl_infof( + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ctrl_sock: curl_socket_t = unsafe { (*conn).sock[0 as usize] }; + let mut data_sock: curl_socket_t = unsafe { (*conn).sock[1 as usize] }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut pp: *mut pingpong = unsafe { &mut (*ftpc).pp }; + let mut result: i32 = 0; + let mut timeout_ms: timediff_t = 0; + let mut nread: ssize_t = 0; + let mut ftpcode: i32 = 0; + unsafe { + *received = 0 as i32 != 0; + } + timeout_ms = ftp_timeleft_accept(data); + unsafe { + Curl_infof( data, b"Checking for server connect\0" as *const u8 as *const libc::c_char, - );} - if timeout_ms < 0 as i64 { - /* if a timeout was already reached, bail out */ - unsafe{Curl_failf( + ); + } + if timeout_ms < 0 as i64 { + /* if a timeout was already reached, bail out */ + unsafe { + Curl_failf( data, b"Accept timeout occurred while waiting server connect\0" as *const u8 as *const libc::c_char, - );} - return CURLE_FTP_ACCEPT_TIMEOUT; + ); } - /* First check whether there is a cached response from server */ + return CURLE_FTP_ACCEPT_TIMEOUT; + } + /* First check whether there is a cached response from server */ - if unsafe{(*pp).cache_size != 0 + if unsafe { + (*pp).cache_size != 0 && !((*pp).cache).is_null() - && *((*pp).cache).offset(0 as isize) as i32 > '3' as i32} - { - /* Data connection could not be established, let's return */ - unsafe{Curl_infof( + && *((*pp).cache).offset(0 as isize) as i32 > '3' as i32 + } { + /* Data connection could not be established, let's return */ + unsafe { + Curl_infof( data, b"There is negative response in cache while serv connect\0" as *const u8 as *const libc::c_char, - );} - Curl_GetFTPResponse(data, &mut nread, &mut ftpcode); - return CURLE_FTP_ACCEPT_FAILED; + ); } - result = unsafe{Curl_socket_check(ctrl_sock, data_sock, -(1 as i32), 0 as i32 as timediff_t)}; - /* see if the connecion request is already here */ - unsafe{ + Curl_GetFTPResponse(data, &mut nread, &mut ftpcode); + return CURLE_FTP_ACCEPT_FAILED; + } + result = + unsafe { Curl_socket_check(ctrl_sock, data_sock, -(1 as i32), 0 as i32 as timediff_t) }; + /* see if the connecion request is already here */ + unsafe { match result { -1 => { /* error *//* let's die here */ @@ -488,9 +519,9 @@ extern "C" fn ReceivedServerConnect(mut data: *mut Curl_easy, mut received: *mut return CURLE_WEIRD_SERVER_REPLY; } } /* switch() */ - }} - return CURLE_OK; - + } + } + return CURLE_OK; } /*********************************************************************** @@ -502,35 +533,37 @@ extern "C" fn ReceivedServerConnect(mut data: *mut Curl_easy, mut received: *mut * */ extern "C" fn InitiateTransfer(mut data: *mut Curl_easy) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - if unsafe{ ((*conn).bits).ftp_use_data_ssl() != 0} { - /* since we only have a plaintext TCP connection here, we must now - * do the TLS stuff */ - unsafe{Curl_infof( + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + if unsafe { ((*conn).bits).ftp_use_data_ssl() != 0 } { + /* since we only have a plaintext TCP connection here, we must now + * do the TLS stuff */ + unsafe { + Curl_infof( data, b"Doing the SSL/TLS handshake on the data stream\0" as *const u8 as *const libc::c_char, - );} - // match () { - // #[cfg(USE_SSL)] - // _ => { - // result = Curl_ssl_connect(data, conn, 1 as i32); - // } - // #[cfg(not(USE_SSL))] - // _ => { - // result = CURLE_NOT_BUILT_IN; - // } - // } - result = unsafe{Curl_ssl_connect(data, conn, 1 as i32)}; - if result as u64 != 0 { - return result; - } + ); + } + // match () { + // #[cfg(USE_SSL)] + // _ => { + // result = Curl_ssl_connect(data, conn, 1 as i32); + // } + // #[cfg(not(USE_SSL))] + // _ => { + // result = CURLE_NOT_BUILT_IN; + // } + // } + result = unsafe { Curl_ssl_connect(data, conn, 1 as i32) }; + if result as u64 != 0 { + return result; } - /* When we know we're uploading a specified file, we can get the file - size prior to the actual upload. */ - if unsafe{(*conn).proto.ftpc.state_saved as u32 == FTP_STOR as u32} { - unsafe{ + } + /* When we know we're uploading a specified file, we can get the file + size prior to the actual upload. */ + if unsafe { (*conn).proto.ftpc.state_saved as u32 == FTP_STOR as u32 } { + unsafe { Curl_pgrsSetUploadSize(data, (*data).state.infilesize); /* set the SO_SNDBUF for the secondary socket for those who need it */ Curl_setup_transfer( @@ -539,26 +572,29 @@ extern "C" fn InitiateTransfer(mut data: *mut Curl_easy) -> CURLcode { -(1 as i32) as curl_off_t, 0 as i32 != 0, 1 as i32, - );} - } else { - /* FTP download: */ - unsafe{ + ); + } + } else { + /* FTP download: */ + unsafe { Curl_setup_transfer( data, 1 as i32, (*conn).proto.ftpc.retr_size_saved, 0 as i32 != 0, -(1 as i32), - );} + ); } - unsafe{(*conn).proto.ftpc.pp.pending_resp = 1 as i32 != 0;} /* expect server response */ - #[cfg(not(DEBUGBUILD))] - _state(data, FTP_STOP); - - #[cfg(DEBUGBUILD)] - _state(data, FTP_STOP, 470 as i32); - return CURLE_OK; - + } + unsafe { + (*conn).proto.ftpc.pp.pending_resp = 1 as i32 != 0; + } /* expect server response */ + #[cfg(not(DEBUGBUILD))] + _state(data, FTP_STOP); + + #[cfg(DEBUGBUILD)] + _state(data, FTP_STOP, 470 as i32); + return CURLE_OK; } /*********************************************************************** * @@ -570,43 +606,48 @@ extern "C" fn InitiateTransfer(mut data: *mut Curl_easy) -> CURLcode { * */ extern "C" fn AllowServerConnect(mut data: *mut Curl_easy, mut connected: *mut bool) -> CURLcode { - let mut timeout_ms: timediff_t = 0; - let mut result: CURLcode = CURLE_OK; - unsafe{*connected = 0 as i32 != 0}; - unsafe{Curl_infof( + let mut timeout_ms: timediff_t = 0; + let mut result: CURLcode = CURLE_OK; + unsafe { *connected = 0 as i32 != 0 }; + unsafe { + Curl_infof( data, b"Preparing for accepting server on data port\0" as *const u8 as *const libc::c_char, ); /* Save the time we start accepting server connect */ - Curl_pgrsTime(data, TIMER_STARTACCEPT);} - timeout_ms = ftp_timeleft_accept(data); - if timeout_ms < 0 as i64 { - /* if a timeout was already reached, bail out */ - unsafe{Curl_failf( + Curl_pgrsTime(data, TIMER_STARTACCEPT); + } + timeout_ms = ftp_timeleft_accept(data); + if timeout_ms < 0 as i64 { + /* if a timeout was already reached, bail out */ + unsafe { + Curl_failf( data, b"Accept timeout occurred while waiting server connect\0" as *const u8 as *const libc::c_char, - );} - return CURLE_FTP_ACCEPT_TIMEOUT; + ); } - /* see if the connection request is already here */ - result = ReceivedServerConnect(data, connected); + return CURLE_FTP_ACCEPT_TIMEOUT; + } + /* see if the connection request is already here */ + result = ReceivedServerConnect(data, connected); + if result as u64 != 0 { + return result; + } + /* Add timeout to multi handle and break out of the loop */ + + if unsafe { *connected } { + result = AcceptServerConnect(data); if result as u64 != 0 { return result; } - /* Add timeout to multi handle and break out of the loop */ - - if unsafe{*connected} { - result = AcceptServerConnect(data); - if result as u64 != 0 { - return result; - } - result = InitiateTransfer(data); - if result as u64 != 0 { - return result; - } - } else if unsafe{*connected as i32 == 0 as i32} { - unsafe{Curl_expire( + result = InitiateTransfer(data); + if result as u64 != 0 { + return result; + } + } else if unsafe { *connected as i32 == 0 as i32 } { + unsafe { + Curl_expire( data, if (*data).set.accepttimeout > 0 as i64 { (*data).set.accepttimeout @@ -614,10 +655,10 @@ extern "C" fn AllowServerConnect(mut data: *mut Curl_easy, mut connected: *mut b 60000 as i64 }, EXPIRE_100_TIMEOUT, - );} + ); } - return result; - + } + return result; } extern "C" fn ftp_endofresp( mut data: *mut Curl_easy, @@ -646,14 +687,13 @@ extern "C" fn ftp_readresp( mut ftpcode: *mut i32, /* return the ftp-code if done */ mut size: *mut size_t, /* size of the response */ ) -> CURLcode { - - let mut code: i32 = 0; - let mut result: CURLcode = unsafe{Curl_pp_readresp(data, sockfd, pp, &mut code, size)}; - if cfg!(HAVE_GSSAPI) { - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let buf: *mut libc::c_char =unsafe{ (*data).state.buffer}; - /* handle the security-oriented responses 6xx ***/ - unsafe{ + let mut code: i32 = 0; + let mut result: CURLcode = unsafe { Curl_pp_readresp(data, sockfd, pp, &mut code, size) }; + if cfg!(HAVE_GSSAPI) { + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let buf: *mut libc::c_char = unsafe { (*data).state.buffer }; + /* handle the security-oriented responses 6xx ***/ + unsafe { match code { 631 => { code = Curl_sec_read_msg(data, conn, buf, PROT_SAFE); @@ -666,34 +706,39 @@ extern "C" fn ftp_readresp( } _ => {} /* normal ftp stuff we pass through! */ } - } - } - /* store the latest code for later retrieval */ - unsafe{(*data).info.httpcode = code;} - if !ftpcode.is_null() { - unsafe{*ftpcode = code;} } - if 421 as i32 == code { - /* 421 means "Service not available, closing control connection." and FTP - * servers use it to signal that idle session timeout has been exceeded. - * If we ignored the response, it could end up hanging in some cases. - * - * This response code can come at any point so having it treated - * generically is a good idea. - */ - unsafe{Curl_infof( + } + /* store the latest code for later retrieval */ + unsafe { + (*data).info.httpcode = code; + } + if !ftpcode.is_null() { + unsafe { + *ftpcode = code; + } + } + if 421 as i32 == code { + /* 421 means "Service not available, closing control connection." and FTP + * servers use it to signal that idle session timeout has been exceeded. + * If we ignored the response, it could end up hanging in some cases. + * + * This response code can come at any point so having it treated + * generically is a good idea. + */ + unsafe { + Curl_infof( data, b"We got a 421 - timeout!\0" as *const u8 as *const libc::c_char, - );} - #[cfg(not(DEBUGBUILD))] - _state(data, FTP_STOP); - - #[cfg(DEBUGBUILD)] - _state(data, FTP_STOP, 596 as i32); - return CURLE_OPERATION_TIMEDOUT; + ); } - return result; - + #[cfg(not(DEBUGBUILD))] + _state(data, FTP_STOP); + + #[cfg(DEBUGBUILD)] + _state(data, FTP_STOP, 596 as i32); + return CURLE_OPERATION_TIMEDOUT; + } + return result; } /* --- parse FTP server responses --- */ @@ -708,66 +753,72 @@ pub extern "C" fn Curl_GetFTPResponse( mut nreadp: *mut ssize_t, /* return number of bytes read */ mut ftpcode: *mut i32, /* return the ftp-code */ ) -> CURLcode { - /* - * We cannot read just one byte per read() and then go back to select() as - * the OpenSSL read() doesn't grok that properly. - * - * Alas, read as much as possible, split up into lines, use the ending - * line in a response or continue reading. */ - - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut sockfd: curl_socket_t = unsafe{(*conn).sock[0 as usize]}; - let mut result: CURLcode = CURLE_OK; - let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; - let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; - let mut nread: size_t = 0; - let mut cache_skip: i32 = 0 as i32; - let mut value_to_be_ignored: i32 = 0 as i32; - if !ftpcode.is_null() { - unsafe{*ftpcode = 0 as i32;} /* 0 for errors */ - } else { - /* make the pointer point to something for the rest of this function */ - ftpcode = &mut value_to_be_ignored; - } - unsafe{*nreadp = 0 as ssize_t;} - let mut current_block_20: u64; - while unsafe{*ftpcode == 0 && result as u64 == 0} { - /* check and reset timeout value every lap */ - let mut timeout: timediff_t = unsafe{Curl_pp_state_timeout(data, pp, 0 as i32 != 0)}; - let mut interval_ms: timediff_t = 0; - if timeout <= 0 as i64 { - unsafe{Curl_failf( + /* + * We cannot read just one byte per read() and then go back to select() as + * the OpenSSL read() doesn't grok that properly. + * + * Alas, read as much as possible, split up into lines, use the ending + * line in a response or continue reading. */ + + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut sockfd: curl_socket_t = unsafe { (*conn).sock[0 as usize] }; + let mut result: CURLcode = CURLE_OK; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut pp: *mut pingpong = unsafe { &mut (*ftpc).pp }; + let mut nread: size_t = 0; + let mut cache_skip: i32 = 0 as i32; + let mut value_to_be_ignored: i32 = 0 as i32; + if !ftpcode.is_null() { + unsafe { + *ftpcode = 0 as i32; + } /* 0 for errors */ + } else { + /* make the pointer point to something for the rest of this function */ + ftpcode = &mut value_to_be_ignored; + } + unsafe { + *nreadp = 0 as ssize_t; + } + let mut current_block_20: u64; + while unsafe { *ftpcode == 0 && result as u64 == 0 } { + /* check and reset timeout value every lap */ + let mut timeout: timediff_t = unsafe { Curl_pp_state_timeout(data, pp, 0 as i32 != 0) }; + let mut interval_ms: timediff_t = 0; + if timeout <= 0 as i64 { + unsafe { + Curl_failf( data, b"FTP response timeout\0" as *const u8 as *const libc::c_char, - );} - return CURLE_OPERATION_TIMEDOUT; /* already too little time */ - } - interval_ms = 1000 as timediff_t; /* use 1 second timeout intervals */ - if timeout < interval_ms { - interval_ms = timeout; + ); } + return CURLE_OPERATION_TIMEDOUT; /* already too little time */ + } + interval_ms = 1000 as timediff_t; /* use 1 second timeout intervals */ + if timeout < interval_ms { + interval_ms = timeout; + } + /* + * Since this function is blocking, we need to wait here for input on the + * connection and only then we call the response reading function. We do + * timeout at least every second to make the timeout check run. + * + * A caution here is that the ftp_readresp() function has a cache that may + * contain pieces of a response from the previous invoke and we need to + * make sure we don't just wait for input while there is unhandled data in + * that cache. But also, if the cache is there, we call ftp_readresp() and + * the cache wasn't good enough to continue we must not just busy-loop + * around this function. + * + */ + if unsafe { !(!((*pp).cache).is_null() && cache_skip < 2 as i32) } { /* - * Since this function is blocking, we need to wait here for input on the - * connection and only then we call the response reading function. We do - * timeout at least every second to make the timeout check run. - * - * A caution here is that the ftp_readresp() function has a cache that may - * contain pieces of a response from the previous invoke and we need to - * make sure we don't just wait for input while there is unhandled data in - * that cache. But also, if the cache is there, we call ftp_readresp() and - * the cache wasn't good enough to continue we must not just busy-loop - * around this function. - * + * There's a cache left since before. We then skipping the wait for + * socket action, unless this is the same cache like the previous round + * as then the cache was deemed not enough to act on and we then need to + * wait for more data anyway. */ - if unsafe{!(!((*pp).cache).is_null() && cache_skip < 2 as i32)} { - /* - * There's a cache left since before. We then skipping the wait for - * socket action, unless this is the same cache like the previous round - * as then the cache was deemed not enough to act on and we then need to - * wait for more data anyway. - */ - if unsafe{!Curl_conn_data_pending(conn, 0 as i32)} { - unsafe{ + if unsafe { !Curl_conn_data_pending(conn, 0 as i32) } { + unsafe { match Curl_socket_check(sockfd, -(1 as i32), -(1 as i32), interval_ms) { -1 => { /* select() error, stop reading */ @@ -817,23 +868,26 @@ pub extern "C" fn Curl_GetFTPResponse( } } } - } - result = ftp_readresp(data, sockfd, pp, ftpcode, &mut nread); - if result as u64 != 0 { - break; - } - if unsafe{nread == 0 && !((*pp).cache).is_null()} { - cache_skip += 1; /* bump cache skip counter as on repeated skips we must wait for more - data */ - } else { - cache_skip = 0 as i32; - } - unsafe{*nreadp = (*nreadp as u64).wrapping_add(nread) as ssize_t;} } - unsafe{(*pp).pending_resp = 0 as i32 != 0;} /* when we got data or there is no cache left, we reset the cache skip - counter */ - return result; - + result = ftp_readresp(data, sockfd, pp, ftpcode, &mut nread); + if result as u64 != 0 { + break; + } + if unsafe { nread == 0 && !((*pp).cache).is_null() } { + cache_skip += 1; /* bump cache skip counter as on repeated skips we must wait for more + data */ + } else { + cache_skip = 0 as i32; + } + unsafe { + *nreadp = (*nreadp as u64).wrapping_add(nread) as ssize_t; + } + } + unsafe { + (*pp).pending_resp = 0 as i32 != 0; + } /* when we got data or there is no cache left, we reset the cache skip + counter */ + return result; } /* for debug purposes */ static mut ftp_state_names: [*const libc::c_char; 35] = [ @@ -903,7 +957,8 @@ extern "C" fn _state(mut data: *mut Curl_easy, mut newstate: ftpstate, mut linen } /* For the FTP "protocol connect" and "doing" phases only */ extern "C" fn ftp_state_user(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - let mut result: CURLcode =unsafe{ Curl_pp_sendf( + let mut result: CURLcode = unsafe { + Curl_pp_sendf( data, &mut (*conn).proto.ftpc.pp as *mut pingpong, b"USER %s\0" as *const u8 as *const libc::c_char, @@ -912,36 +967,39 @@ extern "C" fn ftp_state_user(mut data: *mut Curl_easy, mut conn: *mut connectdat } else { b"\0" as *const u8 as *const libc::c_char }, - )}; - if result as u64 == 0 { - #[cfg(not(DEBUGBUILD))] - _state(data, FTP_USER); + ) + }; + if result as u64 == 0 { + #[cfg(not(DEBUGBUILD))] + _state(data, FTP_USER); - #[cfg(DEBUGBUILD)] - _state(data, FTP_USER, 787 as i32); - // let ref mut fresh6 = (*data).state; - unsafe{((*data).state).set_ftp_trying_alternative(0 as bit);} + #[cfg(DEBUGBUILD)] + _state(data, FTP_USER, 787 as i32); + // let ref mut fresh6 = (*data).state; + unsafe { + ((*data).state).set_ftp_trying_alternative(0 as bit); } - return result; - + } + return result; } /* For the FTP "DO_MORE" phase only */ extern "C" fn ftp_state_pwd(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - let mut result: CURLcode =unsafe{ Curl_pp_sendf( + let mut result: CURLcode = unsafe { + Curl_pp_sendf( data, &mut (*conn).proto.ftpc.pp as *mut pingpong, b"%s\0" as *const u8 as *const libc::c_char, b"PWD\0" as *const u8 as *const libc::c_char, - )}; - if result as u64 == 0 { - #[cfg(not(DEBUGBUILD))] - _state(data, FTP_PWD); + ) + }; + if result as u64 == 0 { + #[cfg(not(DEBUGBUILD))] + _state(data, FTP_PWD); - #[cfg(DEBUGBUILD)] - _state(data, FTP_PWD, 798 as i32); - } - return result; - + #[cfg(DEBUGBUILD)] + _state(data, FTP_PWD, 798 as i32); + } + return result; } /* For the FTP "protocol connect" and "doing" phases only */ extern "C" fn ftp_getsock( @@ -959,28 +1017,31 @@ extern "C" fn ftp_domore_getsock( mut conn: *mut connectdata, mut socks: *mut curl_socket_t, ) -> i32 { - - /* When in DO_MORE state, we could be either waiting for us to connect to a - * remote site, or we could wait for that site to connect to us. Or just - * handle ordinary commands. - */ - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - if unsafe{(*conn).cnnct.state as u32 >= CONNECT_SOCKS_INIT as u32 - && ((*conn).cnnct.state as u32) < CONNECT_DONE as u32} - { - /* if stopped and still in this state, then we're also waiting for a - connect on the secondary connection */ - #[cfg(not(CURL_DISABLE_PROXY))] - unsafe{return Curl_SOCKS_getsock(conn, socks, 1 as i32);} - #[cfg(CURL_DISABLE_PROXY)] - return 0 as i32; - } - if unsafe{FTP_STOP as u32 == (*ftpc).state as u32} { - let mut bits: i32 = (1 as i32) << 0 as i32; - let mut any: bool = 0 as i32 != 0; - /* PORT is used to tell the server to connect to us, and during that we - don't do happy eyeballs, but we do if we connect to the server */ - unsafe{*socks.offset(0 as i32 as isize) = (*conn).sock[0 as usize]; + /* When in DO_MORE state, we could be either waiting for us to connect to a + * remote site, or we could wait for that site to connect to us. Or just + * handle ordinary commands. + */ + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + if unsafe { + (*conn).cnnct.state as u32 >= CONNECT_SOCKS_INIT as u32 + && ((*conn).cnnct.state as u32) < CONNECT_DONE as u32 + } { + /* if stopped and still in this state, then we're also waiting for a + connect on the secondary connection */ + #[cfg(not(CURL_DISABLE_PROXY))] + unsafe { + return Curl_SOCKS_getsock(conn, socks, 1 as i32); + } + #[cfg(CURL_DISABLE_PROXY)] + return 0 as i32; + } + if unsafe { FTP_STOP as u32 == (*ftpc).state as u32 } { + let mut bits: i32 = (1 as i32) << 0 as i32; + let mut any: bool = 0 as i32 != 0; + /* PORT is used to tell the server to connect to us, and during that we + don't do happy eyeballs, but we do if we connect to the server */ + unsafe { + *socks.offset(0 as i32 as isize) = (*conn).sock[0 as usize]; if ((*data).set).ftp_use_port() == 0 { let mut s: i32 = 0; let mut i: i32 = 0; @@ -1001,10 +1062,10 @@ extern "C" fn ftp_domore_getsock( *socks.offset(1 as isize) = (*conn).sock[1 as usize]; bits |= (1 as i32) << 16 as i32 + 1 as i32 | (1 as i32) << 1 as i32; } - return bits;} + return bits; } - return unsafe{Curl_pp_getsock(data, &mut (*conn).proto.ftpc.pp, socks)}; - + } + return unsafe { Curl_pp_getsock(data, &mut (*conn).proto.ftpc.pp, socks) }; } /* This is called after the FTP_QUOTE state is passed. @@ -1014,10 +1075,9 @@ extern "C" fn ftp_domore_getsock( missing ones, if that option is enabled. */ extern "C" fn ftp_state_cwd(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + unsafe { if (*ftpc).cwddone { /* already done and fine */ result = ftp_state_mdtm(data); @@ -1860,10 +1920,10 @@ extern "C" fn ftp_state_prepare_transfer(mut data: *mut Curl_easy) -> CURLcode { } } extern "C" fn ftp_state_rest(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + unsafe { if (*ftp).transfer as u32 != PPTRANSFER_BODY as u32 && !((*ftpc).file).is_null() { /* if a "head"-like request is being made (on a file) */ @@ -1889,11 +1949,10 @@ extern "C" fn ftp_state_rest(mut data: *mut Curl_easy, mut conn: *mut connectdat } } extern "C" fn ftp_state_size(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; - let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + unsafe { if (*ftp).transfer as u32 == PPTRANSFER_INFO as u32 && !((*ftpc).file).is_null() { /* if a "head"-like request is being made (on a file) */ @@ -1918,26 +1977,25 @@ extern "C" fn ftp_state_size(mut data: *mut Curl_easy, mut conn: *mut connectdat } } extern "C" fn ftp_state_list(mut data: *mut Curl_easy) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - /* If this output is to be machine-parsed, the NLST command might be better - to use, since the LIST command output is not specified or standard in any - way. It has turned out that the NLST list output is not the same on all - servers either... */ - - /* - if FTPFILE_NOCWD was specified, we should add the path - as argument for the LIST / NLST / or custom command. - Whether the server will support this, is uncertain. - - The other ftp_filemethods will CWD into dir/dir/ first and - then just do LIST (in that case: nothing to do here) - */ - let mut lstArg: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cmd: *mut libc::c_char = 0 as *mut libc::c_char; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + /* If this output is to be machine-parsed, the NLST command might be better + to use, since the LIST command output is not specified or standard in any + way. It has turned out that the NLST list output is not the same on all + servers either... */ + + /* + if FTPFILE_NOCWD was specified, we should add the path + as argument for the LIST / NLST / or custom command. + Whether the server will support this, is uncertain. + + The other ftp_filemethods will CWD into dir/dir/ first and + then just do LIST (in that case: nothing to do here) + */ + let mut lstArg: *mut libc::c_char = 0 as *mut libc::c_char; + let mut cmd: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { if (*data).set.ftp_filemethod as u32 == FTPFILE_NOCWD as u32 && !((*ftp).path).is_null() { let mut slashPos: *const libc::c_char = 0 as *const libc::c_char; let mut rawPath: *mut libc::c_char = 0 as *mut libc::c_char; @@ -2044,15 +2102,14 @@ extern "C" fn ftp_state_stor_prequote(mut data: *mut Curl_easy) -> CURLcode { } } extern "C" fn ftp_state_type(mut data: *mut Curl_easy) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - /* If we have selected NOBODY and HEADER, it means that we only want file - information. Which in FTP can't be much more than the file size and - date. */ - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + /* If we have selected NOBODY and HEADER, it means that we only want file + information. Which in FTP can't be much more than the file size and + date. */ + unsafe { if ((*data).set).opt_no_body() as i32 != 0 && !((*ftpc).file).is_null() && ftp_need_type(conn, ((*data).state).prefer_ascii() != 0) != 0 @@ -2078,12 +2135,11 @@ extern "C" fn ftp_state_type(mut data: *mut Curl_easy) -> CURLcode { /* This is called after the CWD commands have been done in the beginning of the DO phase */ extern "C" fn ftp_state_mdtm(mut data: *mut Curl_easy) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - /* Requested time of file or time-depended transfer? */ - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + /* Requested time of file or time-depended transfer? */ + unsafe { if (((*data).set).get_filetime() as i32 != 0 || (*data).set.timecondition as u32 != 0) && !((*ftpc).file).is_null() { @@ -2110,13 +2166,12 @@ extern "C" fn ftp_state_mdtm(mut data: *mut Curl_easy) -> CURLcode { } /* This is called after the TYPE and possible quote commands have been sent */ extern "C" fn ftp_state_ul_setup(mut data: *mut Curl_easy, mut sizechecked: bool) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - let mut append: bool =unsafe{ ((*data).set).remote_append() != 0}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut append: bool = unsafe { ((*data).set).remote_append() != 0 }; + unsafe { if (*data).state.resume_from != 0 && !sizechecked || (*data).state.resume_from > 0 as i64 && sizechecked as i32 != 0 { @@ -2255,14 +2310,13 @@ extern "C" fn ftp_state_quote( mut init: bool, mut instate: ftpstate, ) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; - let mut quote: bool = 0 as i32 != 0; - let mut item: *mut curl_slist = 0 as *mut curl_slist; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut quote: bool = 0 as i32 != 0; + let mut item: *mut curl_slist = 0 as *mut curl_slist; + unsafe { match instate as u32 { 13 | 14 => { item = (*data).set.prequote; @@ -2449,16 +2503,15 @@ extern "C" fn control_address(mut conn: *mut connectdata) -> *mut libc::c_char { } } extern "C" fn ftp_state_pasv_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> CURLcode { - - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - let mut result: CURLcode = CURLE_OK; - let mut addr: *mut Curl_dns_entry = 0 as *mut Curl_dns_entry; - let mut rc: resolve_t = CURLRESOLV_RESOLVED; - let mut connectport: u16 = 0; /* the local port connect() should use! */ - let mut str: *mut libc::c_char =unsafe{ - &mut *((*data).state.buffer).offset(4 as isize) as *mut libc::c_char}; /* start on the first letter */ - unsafe{ + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut result: CURLcode = CURLE_OK; + let mut addr: *mut Curl_dns_entry = 0 as *mut Curl_dns_entry; + let mut rc: resolve_t = CURLRESOLV_RESOLVED; + let mut connectport: u16 = 0; /* the local port connect() should use! */ + let mut str: *mut libc::c_char = + unsafe { &mut *((*data).state.buffer).offset(4 as isize) as *mut libc::c_char }; /* start on the first letter */ + unsafe { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")((*ftpc).newhost as *mut libc::c_void); /* if we come here again, make sure the former name is cleared */ @@ -2878,12 +2931,11 @@ extern "C" fn ftp_state_pasv_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> } } extern "C" fn ftp_state_port_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> CURLcode { - - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; - let mut fcmd: ftpport = unsafe{(*ftpc).count1 as ftpport}; - let mut result: CURLcode = CURLE_OK; - unsafe{ + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut fcmd: ftpport = unsafe { (*ftpc).count1 as ftpport }; + let mut result: CURLcode = CURLE_OK; + unsafe { /* The FTP spec tells a positive response should have code 200. Be more permissive here to tolerate deviant servers. */ if ftpcode / 100 as i32 != 2 as i32 { @@ -2923,12 +2975,11 @@ extern "C" fn ftp_state_port_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> } } extern "C" fn ftp_state_mdtm_resp(mut data: *mut Curl_easy, mut ftpcode: i32) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP =unsafe{(*data).req.p.ftp}; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + unsafe { match ftpcode { 213 => { /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the @@ -3098,10 +3149,9 @@ extern "C" fn ftp_state_type_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + unsafe { if ftpcode / 100 as i32 != 2 as i32 { /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a successful 'TYPE I'. While that is not as RFC959 says, it is still a @@ -3133,12 +3183,11 @@ extern "C" fn ftp_state_type_resp( } } extern "C" fn ftp_state_retr(mut data: *mut Curl_easy, mut filesize: curl_off_t) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + unsafe { if (*data).set.max_filesize != 0 && filesize > (*data).set.max_filesize { Curl_failf( data, @@ -3250,11 +3299,10 @@ extern "C" fn ftp_state_size_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut filesize: curl_off_t = -(1 as i32) as curl_off_t; - let mut buf: *mut libc::c_char =unsafe{ (*data).state.buffer}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut filesize: curl_off_t = -(1 as i32) as curl_off_t; + let mut buf: *mut libc::c_char = unsafe { (*data).state.buffer }; + unsafe { /* get the size from the ascii string: */ if ftpcode == 213 as i32 { /* To allow servers to prepend "rubbish" in the response string, we scan @@ -3327,10 +3375,9 @@ extern "C" fn ftp_state_rest_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + unsafe { match instate as u32 { 27 => { if ftpcode != 350 as i32 { @@ -3383,10 +3430,9 @@ extern "C" fn ftp_state_stor_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = unsafe{(*data).conn}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + unsafe { if ftpcode >= 400 as i32 { Curl_failf( data, @@ -3434,11 +3480,10 @@ extern "C" fn ftp_state_get_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + unsafe { if ftpcode == 150 as i32 || ftpcode == 125 as i32 { /* A; @@ -3580,10 +3625,9 @@ extern "C" fn ftp_state_get_resp( } /* after USER, PASS and ACCT */ extern "C" fn ftp_state_loggedin(mut data: *mut Curl_easy) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + unsafe { if ((*conn).bits).ftp_use_control_ssl() != 0 { /* PBSZ = PROTECTION BUFFER SIZE. @@ -3624,12 +3668,11 @@ extern "C" fn ftp_state_user_resp( mut ftpcode: i32, mut instate: ftpstate, ) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = unsafe{(*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; /* no use for this yet */ - /* some need password anyway, and others just return 2xx ignored */ - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; /* no use for this yet */ + /* some need password anyway, and others just return 2xx ignored */ + unsafe { if ftpcode == 331 as i32 && (*ftpc).state as u32 == FTP_USER as u32 { /* 331 Password required for ... (the server requires to send the user's password too) */ @@ -4392,15 +4435,14 @@ unsafe extern "C" fn ftp_statemachine( /* called repeatedly until done from multi.c */ extern "C" fn ftp_multi_statemach(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { - - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; - let mut result: CURLcode =unsafe{ - Curl_pp_statemach(data, &mut (*ftpc).pp, 0 as i32 != 0, 0 as i32 != 0)}; - /* Check for the state outside of the Curl_socket_check() return code checks - since at times we are in fact already in this state when this function - gets called. */ - unsafe{ + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut result: CURLcode = + unsafe { Curl_pp_statemach(data, &mut (*ftpc).pp, 0 as i32 != 0, 0 as i32 != 0) }; + /* Check for the state outside of the Curl_socket_check() return code checks + since at times we are in fact already in this state when this function + gets called. */ + unsafe { *done = if (*ftpc).state as u32 == FTP_STOP as u32 { 1 as i32 } else { @@ -4414,10 +4456,10 @@ extern "C" fn ftp_block_statemach( mut data: *mut Curl_easy, mut conn: *mut connectdata, ) -> CURLcode { - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; - let mut result: CURLcode = CURLE_OK; - unsafe{ + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut pp: *mut pingpong = unsafe { &mut (*ftpc).pp }; + let mut result: CURLcode = CURLE_OK; + unsafe { // 解决clippy错误 loop { if (*ftpc).state as u32 == FTP_STOP as u32 { @@ -4444,11 +4486,11 @@ extern "C" fn ftp_block_statemach( extern "C" fn ftp_connect(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { /* see description above */ - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut pp: *mut pingpong = unsafe { &mut (*ftpc).pp }; + unsafe { *done = 0 as i32 != 0; /* default to not done yet */ #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] Curl_conncontrol(conn, 0 as i32); @@ -4521,17 +4563,16 @@ extern "C" fn ftp_done( mut status: CURLcode, mut premature: bool, ) -> CURLcode { - - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; - let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; - let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; - let mut nread: ssize_t = 0; - let mut ftpcode: i32 = 0; - let mut result: CURLcode = CURLE_OK; - let mut rawPath: *mut libc::c_char = 0 as *mut libc::c_char; - let mut pathLen: size_t = 0 as size_t; - unsafe{ + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut pp: *mut pingpong = unsafe { &mut (*ftpc).pp }; + let mut nread: ssize_t = 0; + let mut ftpcode: i32 = 0; + let mut result: CURLcode = CURLE_OK; + let mut rawPath: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pathLen: size_t = 0 as size_t; + unsafe { if ftp.is_null() { return CURLE_OK; } @@ -4904,12 +4945,11 @@ extern "C" fn ftp_sendquote( mut conn: *mut connectdata, mut quote: *mut curl_slist, ) -> CURLcode { - - let mut item: *mut curl_slist = 0 as *mut curl_slist; - let mut ftpc: *mut ftp_conn = unsafe{&mut (*conn).proto.ftpc}; - let mut pp: *mut pingpong = unsafe{&mut (*ftpc).pp}; - item = quote; - unsafe{ + let mut item: *mut curl_slist = 0 as *mut curl_slist; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut pp: *mut pingpong = unsafe { &mut (*ftpc).pp }; + item = quote; + unsafe { while !item.is_null() { if !((*item).data).is_null() { let mut nread: ssize_t = 0; @@ -4983,15 +5023,14 @@ extern "C" fn ftp_nb_type( mut ascii: bool, mut newstate: ftpstate, ) -> CURLcode { - - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - let mut result: CURLcode = CURLE_OK; - let mut want: libc::c_char = (if ascii as i32 != 0 { - 'A' as i32 - } else { - 'I' as i32 - }) as libc::c_char; - unsafe{ + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut result: CURLcode = CURLE_OK; + let mut want: libc::c_char = (if ascii as i32 != 0 { + 'A' as i32 + } else { + 'I' as i32 + }) as libc::c_char; + unsafe { if (*ftpc).transfertype as i32 == want as i32 { #[cfg(not(DEBUGBUILD))] _state(data, newstate); @@ -5034,9 +5073,8 @@ extern "C" fn ftp_pasv_verbose( mut newhost: *mut libc::c_char, /* ascii version */ mut port: i32, ) { - - let mut buf: [libc::c_char; 256] = [0; 256]; - unsafe{ + let mut buf: [libc::c_char; 256] = [0; 256]; + unsafe { Curl_printable_address( ai, buf.as_mut_ptr(), @@ -5063,14 +5101,13 @@ extern "C" fn ftp_pasv_verbose( * EPSV). */ extern "C" fn ftp_do_more(mut data: *mut Curl_easy, mut completep: *mut i32) -> CURLcode { - - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - let mut result: CURLcode = CURLE_OK; - let mut connected: bool = 0 as i32 != 0; - let mut complete: bool = 0 as i32 != 0; - let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; - unsafe{ + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut result: CURLcode = CURLE_OK; + let mut connected: bool = 0 as i32 != 0; + let mut complete: bool = 0 as i32 != 0; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + unsafe { /* the ftp struct is inited in ftp_connect() */ /* if the second connection isn't done yet, wait for it */ if !(*conn).bits.tcpconnect[1 as i32 as usize] { @@ -5307,14 +5344,13 @@ extern "C" fn wc_data_dtor(mut ptr: *mut libc::c_void) { } extern "C" fn init_wc_data(mut data: *mut Curl_easy) -> CURLcode { - - let mut last_slash: *mut libc::c_char = 0 as *mut libc::c_char; - let mut ftp: *mut FTP = unsafe{(*data).req.p.ftp}; - let mut path: *mut libc::c_char =unsafe{ (*ftp).path}; - let mut wildcard: *mut WildcardData =unsafe{ &mut (*data).wildcard}; - let mut result: CURLcode = CURLE_OK; - let mut ftpwc: *mut ftp_wc = 0 as *mut ftp_wc; - unsafe{ + let mut last_slash: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut path: *mut libc::c_char = unsafe { (*ftp).path }; + let mut wildcard: *mut WildcardData = unsafe { &mut (*data).wildcard }; + let mut result: CURLcode = CURLE_OK; + let mut ftpwc: *mut ftp_wc = 0 as *mut ftp_wc; + unsafe { last_slash = strrchr((*ftp).path, '/' as i32); if !last_slash.is_null() { last_slash = last_slash.offset(1); @@ -5493,12 +5529,11 @@ extern "C" fn init_wc_data(mut data: *mut Curl_easy) -> CURLcode { } extern "C" fn wc_statemach(mut data: *mut Curl_easy) -> CURLcode { - - let wildcard: *mut WildcardData =unsafe{ &mut (*data).wildcard}; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut result: CURLcode = CURLE_OK; - let mut current_block_53: u64; - unsafe{ + let wildcard: *mut WildcardData = unsafe { &mut (*data).wildcard }; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut result: CURLcode = CURLE_OK; + let mut current_block_53: u64; + unsafe { loop { match (*wildcard).state as u32 { 1 => { @@ -5693,11 +5728,10 @@ extern "C" fn wc_statemach(mut data: *mut Curl_easy) -> CURLcode { * The input argument is already checked for validity. */ extern "C" fn ftp_do(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + unsafe { *done = 0 as i32 != 0; /* default to false */ (*ftpc).wait_data_conn = 0 as i32 != 0; /* default to no such wait */ if ((*data).state).wildcardmatch() != 0 { @@ -6329,17 +6363,16 @@ extern "C" fn ftp_disconnect( mut conn: *mut connectdata, mut dead_connection: bool, ) -> CURLcode { - - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - let mut pp: *mut pingpong =unsafe{ &mut (*ftpc).pp}; - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. - - ftp_quit() will check the state of ftp->ctl_valid. If it's ok it - will try to send the QUIT command, otherwise it will just return. - */ - unsafe{ + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut pp: *mut pingpong = unsafe { &mut (*ftpc).pp }; + /* We cannot send quit unconditionally. If this connection is stale or + bad in any way, sending quit and waiting around here will make the + disconnect wait in vain and cause more problems than we need to. + + ftp_quit() will check the state of ftp->ctl_valid. If it's ok it + will try to send the QUIT command, otherwise it will just return. + */ + unsafe { if dead_connection { (*ftpc).ctl_valid = 0 as i32 != 0; } @@ -6400,17 +6433,16 @@ extern "C" fn ftp_disconnect( * */ extern "C" fn ftp_parse_url_path(mut data: *mut Curl_easy) -> CURLcode { - - /* the ftp struct is already inited in ftp_connect() */ - let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - let mut slashPos: *const libc::c_char = 0 as *const libc::c_char; - let mut fileName: *const libc::c_char = 0 as *const libc::c_char; - let mut result: CURLcode = CURLE_OK; - let mut rawPath: *mut libc::c_char = 0 as *mut libc::c_char; /* url-decoded "raw" path */ - let mut pathLen: size_t = 0 as size_t; - unsafe{ + /* the ftp struct is already inited in ftp_connect() */ + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + let mut slashPos: *const libc::c_char = 0 as *const libc::c_char; + let mut fileName: *const libc::c_char = 0 as *const libc::c_char; + let mut result: CURLcode = CURLE_OK; + let mut rawPath: *mut libc::c_char = 0 as *mut libc::c_char; /* url-decoded "raw" path */ + let mut pathLen: size_t = 0 as size_t; + unsafe { (*ftpc).ctl_valid = 0 as i32 != 0; (*ftpc).cwdfail = 0 as i32 != 0; /* url-decode ftp path before further evaluation */ @@ -6723,11 +6755,10 @@ extern "C" fn ftp_parse_url_path(mut data: *mut Curl_easy) -> CURLcode { } /* call this when the DO phase has completed */ extern "C" fn ftp_dophase_done(mut data: *mut Curl_easy, mut connected: bool) -> CURLcode { - - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftp: *mut FTP =unsafe{ (*data).req.p.ftp}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - unsafe{ + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftp: *mut FTP = unsafe { (*data).req.p.ftp }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + unsafe { if connected { let mut completed: i32 = 0; let mut result: CURLcode = ftp_do_more(data, &mut completed); @@ -6791,12 +6822,11 @@ extern "C" fn ftp_regular_transfer( mut data: *mut Curl_easy, mut dophase_done: *mut bool, ) -> CURLcode { - - let mut result: CURLcode = CURLE_OK; - let mut connected: bool = 0 as i32 != 0; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut ftpc: *mut ftp_conn =unsafe{ &mut (*conn).proto.ftpc}; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut connected: bool = 0 as i32 != 0; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut ftpc: *mut ftp_conn = unsafe { &mut (*conn).proto.ftpc }; + unsafe { (*data).req.size = -(1 as i32) as curl_off_t; /* make sure this is unknown at this point */ Curl_pgrsSetUploadCounter(data, 0 as curl_off_t); Curl_pgrsSetDownloadCounter(data, 0 as curl_off_t); diff --git a/rust/rust_project/src/http.rs b/rust/rust_project/src/http.rs index 2258caa..2ef2eed 100644 --- a/rust/rust_project/src/http.rs +++ b/rust/rust_project/src/http.rs @@ -170,71 +170,75 @@ pub static mut Curl_handler_https: Curl_handler = Curl_handler { flags: PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | PROTOPT_USERPWDCTRL, }; -extern "C" fn http_setup_conn( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, -) -> CURLcode { +extern "C" fn http_setup_conn(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { /* allocate the HTTP-specific struct for the Curl_easy, only to survive during this request */ let mut http: *mut HTTP = 0 as *mut HTTP; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - unsafe {if ((*data).req.p.http).is_null() { - } else { - __assert_fail( - b"data->req.p.http == ((void*)0)\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 179 as u32, - (*::std::mem::transmute::<&[u8; 67], &[libc::c_char; 67]>( - b"CURLcode http_setup_conn(struct Curl_easy *, struct connectdata *)\0", - )) - .as_ptr(), - ); - }} + unsafe { + if ((*data).req.p.http).is_null() { + } else { + __assert_fail( + b"data->req.p.http == ((void*)0)\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 179 as u32, + (*::std::mem::transmute::<&[u8; 67], &[libc::c_char; 67]>( + b"CURLcode http_setup_conn(struct Curl_easy *, struct connectdata *)\0", + )) + .as_ptr(), + ); + } + } #[cfg(not(CURLDEBUG))] - let mut new_http: *mut HTTP =unsafe { Curl_ccalloc.expect("non-null function pointer")( - 1 as size_t, - ::std::mem::size_of::() as u64, - ) as *mut HTTP}; + let mut new_http: *mut HTTP = unsafe { + Curl_ccalloc.expect("non-null function pointer")( + 1 as size_t, + ::std::mem::size_of::() as u64, + ) as *mut HTTP + }; #[cfg(CURLDEBUG)] - let mut new_http: *mut HTTP = unsafe {curl_dbg_calloc( - 1 as size_t, - ::std::mem::size_of::() as u64, - 181, - b"http.c\0" as *const u8 as *const libc::c_char, - ) as *mut HTTP}; + let mut new_http: *mut HTTP = unsafe { + curl_dbg_calloc( + 1 as size_t, + ::std::mem::size_of::() as u64, + 181, + b"http.c\0" as *const u8 as *const libc::c_char, + ) as *mut HTTP + }; http = new_http; if http.is_null() { return CURLE_OUT_OF_MEMORY; } unsafe { - #[cfg(any( - all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), - not(CURL_DISABLE_SMTP), - not(CURL_DISABLE_IMAP) - ))] - Curl_mime_initpart(&mut (*http).form, data); - (*data).req.p.http = http; - if (*data).state.httpwant as i32 == CURL_HTTP_VERSION_3 as i32 { - /* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does - the QUIC dance. */ - if (*(*conn).handler).flags & PROTOPT_SSL != 0 { - (*conn).transport = TRNSPRT_QUIC; + #[cfg(any( + all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), + not(CURL_DISABLE_SMTP), + not(CURL_DISABLE_IMAP) + ))] + Curl_mime_initpart(&mut (*http).form, data); + (*data).req.p.http = http; + if (*data).state.httpwant as i32 == CURL_HTTP_VERSION_3 as i32 { + /* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does + the QUIC dance. */ + if (*(*conn).handler).flags & PROTOPT_SSL != 0 { + (*conn).transport = TRNSPRT_QUIC; + } else { + Curl_failf( + data, + b"HTTP/3 requested for non-HTTPS URL\0" as *const u8 as *const libc::c_char, + ); + return CURLE_URL_MALFORMAT; + } } else { - Curl_failf( - data, - b"HTTP/3 requested for non-HTTPS URL\0" as *const u8 as *const libc::c_char, - ); - return CURLE_URL_MALFORMAT; - } - } else { - /* if not already multi-using, setup connection details */ - if (*conn).easyq.size == 0 { - Curl_http2_setup_conn(conn); + /* if not already multi-using, setup connection details */ + if (*conn).easyq.size == 0 { + Curl_http2_setup_conn(conn); + } + Curl_http2_setup_req(data); } - Curl_http2_setup_req(data); - }} + } return CURLE_OK; } @@ -255,23 +259,23 @@ pub extern "C" fn Curl_checkProxyheaders( mut thisheader: *const libc::c_char, ) -> *mut libc::c_char { let mut head: *mut curl_slist = 0 as *mut curl_slist; - let mut thislen: size_t =unsafe { strlen(thisheader)}; + let mut thislen: size_t = unsafe { strlen(thisheader) }; unsafe { - head = if ((*conn).bits).proxy() as i32 != 0 && ((*data).set).sep_headers() as i32 != 0 { - (*data).set.proxyheaders - } else { - (*data).set.headers - }; + head = if ((*conn).bits).proxy() as i32 != 0 && ((*data).set).sep_headers() as i32 != 0 { + (*data).set.proxyheaders + } else { + (*data).set.headers + }; - while !head.is_null() { - if Curl_strncasecompare((*head).data, thisheader, thislen) != 0 - && (*((*head).data).offset(thislen as isize) as i32 == ':' as i32 - || *((*head).data).offset(thislen as isize) as i32 == ';' as i32) - { - return (*head).data; + while !head.is_null() { + if Curl_strncasecompare((*head).data, thisheader, thislen) != 0 + && (*((*head).data).offset(thislen as isize) as i32 == ':' as i32 + || *((*head).data).offset(thislen as isize) as i32 == ';' as i32) + { + return (*head).data; + } + head = (*head).next; } - head = (*head).next; - } } return 0 as *mut libc::c_char; } @@ -285,7 +289,8 @@ pub extern "C" fn Curl_checkProxyheaders( mut thisheader: *const libc::c_char, ) -> *mut libc::c_char { unsafe { - return 0 as *mut libc::c_char;} + return 0 as *mut libc::c_char; + } } /* @@ -295,70 +300,73 @@ pub extern "C" fn Curl_checkProxyheaders( * consists entirely of whitespace. */ #[no_mangle] -pub extern "C" fn Curl_copy_header_value( - mut header: *const libc::c_char, -) -> *mut libc::c_char { +pub extern "C" fn Curl_copy_header_value(mut header: *const libc::c_char) -> *mut libc::c_char { let mut start: *const libc::c_char = 0 as *const libc::c_char; let mut end: *const libc::c_char = 0 as *const libc::c_char; let mut value: *mut libc::c_char = 0 as *mut libc::c_char; let mut len: size_t = 0; /* Find the end of the header name */ - while unsafe {*header as i32 != 0 && *header as i32 != ':' as i32} { - header = unsafe {header.offset(1)}; + while unsafe { *header as i32 != 0 && *header as i32 != ':' as i32 } { + header = unsafe { header.offset(1) }; } - if unsafe {*header != 0} { + if unsafe { *header != 0 } { /* Skip over colon */ - header = unsafe {header.offset(1)}; + header = unsafe { header.offset(1) }; } /* Find the first non-space letter */ start = header; - while unsafe {*start as i32 != 0 && Curl_isspace(*start as u8 as i32) != 0} { - start = unsafe {start.offset(1)}; + while unsafe { *start as i32 != 0 && Curl_isspace(*start as u8 as i32) != 0 } { + start = unsafe { start.offset(1) }; } /* data is in the host encoding so use '\r' and '\n' instead of 0x0d and 0x0a */ - end = unsafe {strchr(start, '\r' as i32)}; + end = unsafe { strchr(start, '\r' as i32) }; if end.is_null() { - end = unsafe {strchr(start, '\n' as i32)}; + end = unsafe { strchr(start, '\n' as i32) }; } if end.is_null() { - end = unsafe {strchr(start, '\0' as i32)}; + end = unsafe { strchr(start, '\0' as i32) }; } if end.is_null() { return 0 as *mut libc::c_char; } /* skip all trailing space letters */ - while unsafe {end > start && Curl_isspace(*end as u8 as i32) != 0} { - end =unsafe { end.offset(-1)}; + while unsafe { end > start && Curl_isspace(*end as u8 as i32) != 0 } { + end = unsafe { end.offset(-1) }; } /* get length of the type */ - len = unsafe {(end.offset_from(start) as i64 + 1 as i64) as size_t}; + len = unsafe { (end.offset_from(start) as i64 + 1 as i64) as size_t }; #[cfg(not(CURLDEBUG))] - let mut new_value: *mut libc::c_char =unsafe { + let mut new_value: *mut libc::c_char = unsafe { Curl_cmalloc.expect("non-null function pointer")(len.wrapping_add(1 as i32 as u64)) - as *mut libc::c_char}; + as *mut libc::c_char + }; #[cfg(CURLDEBUG)] - let mut new_value: *mut libc::c_char =unsafe { curl_dbg_malloc( - len.wrapping_add(1 as u64), - 282, - b"http.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char}; + let mut new_value: *mut libc::c_char = unsafe { + curl_dbg_malloc( + len.wrapping_add(1 as u64), + 282, + b"http.c\0" as *const u8 as *const libc::c_char, + ) as *mut libc::c_char + }; value = new_value; if value.is_null() { return 0 as *mut libc::c_char; } - unsafe {memcpy( - value as *mut libc::c_void, - start as *const libc::c_void, - len, - ); - *value.offset(len as isize) = 0 as libc::c_char; /* null-terminate */} + unsafe { + memcpy( + value as *mut libc::c_void, + start as *const libc::c_void, + len, + ); + *value.offset(len as isize) = 0 as libc::c_char; /* null-terminate */ + } return value; } @@ -378,84 +386,85 @@ extern "C" fn http_output_basic(mut data: *mut Curl_easy, mut proxy: bool) -> CU let mut result: CURLcode = CURLE_OK; let mut out: *mut libc::c_char = 0 as *mut libc::c_char; unsafe { - /* credentials are unique per transfer for HTTP, do not use the ones for the - connection */ - if proxy { - match () { - #[cfg(not(CURL_DISABLE_PROXY))] - _ => { - userp = &mut (*data).state.aptr.proxyuserpwd; - user = (*data).state.aptr.proxyuser; - pwd = (*data).state.aptr.proxypasswd; - } - #[cfg(CURL_DISABLE_PROXY)] - _ => { - return CURLE_NOT_BUILT_IN; + /* credentials are unique per transfer for HTTP, do not use the ones for the + connection */ + if proxy { + match () { + #[cfg(not(CURL_DISABLE_PROXY))] + _ => { + userp = &mut (*data).state.aptr.proxyuserpwd; + user = (*data).state.aptr.proxyuser; + pwd = (*data).state.aptr.proxypasswd; + } + #[cfg(CURL_DISABLE_PROXY)] + _ => { + return CURLE_NOT_BUILT_IN; + } } + } else { + userp = &mut (*data).state.aptr.userpwd; + user = (*data).state.aptr.user; + pwd = (*data).state.aptr.passwd; } - } else { - userp = &mut (*data).state.aptr.userpwd; - user = (*data).state.aptr.user; - pwd = (*data).state.aptr.passwd; - } - out = curl_maprintf( - b"%s:%s\0" as *const u8 as *const libc::c_char, - user, - if !pwd.is_null() { - pwd - } else { - b"\0" as *const u8 as *const libc::c_char - }, - ); - if out.is_null() { - return CURLE_OUT_OF_MEMORY; - } + out = curl_maprintf( + b"%s:%s\0" as *const u8 as *const libc::c_char, + user, + if !pwd.is_null() { + pwd + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + if out.is_null() { + return CURLE_OUT_OF_MEMORY; + } - result = Curl_base64_encode(data, out, strlen(out), &mut authorization, &mut size); - if !(result as u64 != 0) { - if authorization.is_null() { - result = CURLE_REMOTE_ACCESS_DENIED; - } else { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(*userp as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - *userp as *mut libc::c_void, - 339 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - *userp = curl_maprintf( - b"%sAuthorization: Basic %s\r\n\0" as *const u8 as *const libc::c_char, - if proxy as i32 != 0 { - b"Proxy-\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - authorization, - ); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(authorization as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - authorization as *mut libc::c_void, - 343 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - if (*userp).is_null() { - result = CURLE_OUT_OF_MEMORY; + result = Curl_base64_encode(data, out, strlen(out), &mut authorization, &mut size); + if !(result as u64 != 0) { + if authorization.is_null() { + result = CURLE_REMOTE_ACCESS_DENIED; + } else { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(*userp as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + *userp as *mut libc::c_void, + 339 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + *userp = curl_maprintf( + b"%sAuthorization: Basic %s\r\n\0" as *const u8 as *const libc::c_char, + if proxy as i32 != 0 { + b"Proxy-\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + authorization, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(authorization as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + authorization as *mut libc::c_void, + 343 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + if (*userp).is_null() { + result = CURLE_OUT_OF_MEMORY; + } } } + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(out as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + out as *mut libc::c_void, + 350 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + return result; } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(out as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - out as *mut libc::c_void, - 350 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - return result;} } /* @@ -469,23 +478,23 @@ extern "C" fn http_output_bearer(mut data: *mut Curl_easy) -> CURLcode { let mut userp: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; let mut result: CURLcode = CURLE_OK; unsafe { - userp = &mut (*data).state.aptr.userpwd; - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(*userp as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - *userp as *mut libc::c_void, - 366, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - *userp = curl_maprintf( - b"Authorization: Bearer %s\r\n\0" as *const u8 as *const libc::c_char, - (*data).set.str_0[STRING_BEARER as i32 as usize], - ); - - if (*userp).is_null() { - result = CURLE_OUT_OF_MEMORY; - } + userp = &mut (*data).state.aptr.userpwd; + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(*userp as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + *userp as *mut libc::c_void, + 366, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + *userp = curl_maprintf( + b"Authorization: Bearer %s\r\n\0" as *const u8 as *const libc::c_char, + (*data).set.str_0[STRING_BEARER as i32 as usize], + ); + + if (*userp).is_null() { + result = CURLE_OUT_OF_MEMORY; + } } return result; } @@ -498,31 +507,31 @@ extern "C" fn http_output_bearer(mut data: *mut Curl_easy) -> CURLcode { extern "C" fn pickoneauth(mut pick: *mut auth, mut mask: u64) -> bool { let mut picked: bool = false; /* only deal with authentication we want */ - let mut avail: u64 =unsafe { (*pick).avail & (*pick).want & mask}; + let mut avail: u64 = unsafe { (*pick).avail & (*pick).want & mask }; picked = true; /* The order of these checks is highly relevant, as this will be the order of preference in case of the existence of multiple accepted types. */ unsafe { - if avail & CURLAUTH_NEGOTIATE != 0 { - (*pick).picked = CURLAUTH_NEGOTIATE; - } else if avail & CURLAUTH_BEARER != 0 { - (*pick).picked = CURLAUTH_BEARER; - } else if avail & CURLAUTH_DIGEST != 0 { - (*pick).picked = CURLAUTH_DIGEST; - } else if avail & CURLAUTH_NTLM != 0 { - (*pick).picked = CURLAUTH_NTLM; - } else if avail & CURLAUTH_NTLM_WB != 0 { - (*pick).picked = CURLAUTH_NTLM_WB; - } else if avail & CURLAUTH_BASIC != 0 { - (*pick).picked = CURLAUTH_BASIC; - } else if avail & CURLAUTH_AWS_SIGV4 != 0 { - (*pick).picked = CURLAUTH_AWS_SIGV4; - } else { - (*pick).picked = CURLAUTH_PICKNONE; /* we select to use nothing */ - picked = false; - } - (*pick).avail = CURLAUTH_NONE; /* clear it here */ + if avail & CURLAUTH_NEGOTIATE != 0 { + (*pick).picked = CURLAUTH_NEGOTIATE; + } else if avail & CURLAUTH_BEARER != 0 { + (*pick).picked = CURLAUTH_BEARER; + } else if avail & CURLAUTH_DIGEST != 0 { + (*pick).picked = CURLAUTH_DIGEST; + } else if avail & CURLAUTH_NTLM != 0 { + (*pick).picked = CURLAUTH_NTLM; + } else if avail & CURLAUTH_NTLM_WB != 0 { + (*pick).picked = CURLAUTH_NTLM_WB; + } else if avail & CURLAUTH_BASIC != 0 { + (*pick).picked = CURLAUTH_BASIC; + } else if avail & CURLAUTH_AWS_SIGV4 != 0 { + (*pick).picked = CURLAUTH_AWS_SIGV4; + } else { + (*pick).picked = CURLAUTH_PICKNONE; /* we select to use nothing */ + picked = false; + } + (*pick).avail = CURLAUTH_NONE; /* clear it here */ } return picked; } @@ -550,154 +559,153 @@ extern "C" fn pickoneauth(mut pick: *mut auth, mut mask: u64) -> bool { * } * } */ -extern "C" fn http_perhapsrewind( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, -) -> CURLcode { - let mut http: *mut HTTP =unsafe { (*data).req.p.http}; +extern "C" fn http_perhapsrewind(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { + let mut http: *mut HTTP = unsafe { (*data).req.p.http }; let mut bytessent: curl_off_t = 0; let mut expectsend: curl_off_t = -1 as curl_off_t; /* default is unknown */ unsafe { - if http.is_null() { - /* If this is still NULL, we have not reach very far and we can safely - skip this rewinding stuff */ - return CURLE_OK; - } + if http.is_null() { + /* If this is still NULL, we have not reach very far and we can safely + skip this rewinding stuff */ + return CURLE_OK; + } - match (*data).state.httpreq as u32 { - // 0 | 5 => return CURLE_OK, - HTTPREQ_GET | HTTPREQ_HEAD => return CURLE_OK, - _ => {} - } + match (*data).state.httpreq as u32 { + // 0 | 5 => return CURLE_OK, + HTTPREQ_GET | HTTPREQ_HEAD => return CURLE_OK, + _ => {} + } - bytessent = (*data).req.writebytecount; + bytessent = (*data).req.writebytecount; - // todo 解决clippy错误,代码通过测试后就可以删掉注释 - if ((*conn).bits).authneg() != 0 || ((*conn).bits).protoconnstart() == 0 { - /* This is a state where we are known to be negotiating and we don't send - any data then. */ - expectsend = 0 as curl_off_t; - // } else if ((*conn).bits).protoconnstart() == 0 { - /* HTTP CONNECT in progress: there is no body */ - // expectsend = 0 as curl_off_t; - } else { - match (*data).state.httpreq as u32 { - /* figure out how much data we are expected to send */ - HTTPREQ_POST | HTTPREQ_PUT => { - if (*data).state.infilesize != -1 as i64 { - expectsend = (*data).state.infilesize; + // todo 解决clippy错误,代码通过测试后就可以删掉注释 + if ((*conn).bits).authneg() != 0 || ((*conn).bits).protoconnstart() == 0 { + /* This is a state where we are known to be negotiating and we don't send + any data then. */ + expectsend = 0 as curl_off_t; + // } else if ((*conn).bits).protoconnstart() == 0 { + /* HTTP CONNECT in progress: there is no body */ + // expectsend = 0 as curl_off_t; + } else { + match (*data).state.httpreq as u32 { + /* figure out how much data we are expected to send */ + HTTPREQ_POST | HTTPREQ_PUT => { + if (*data).state.infilesize != -1 as i64 { + expectsend = (*data).state.infilesize; + } } + HTTPREQ_POST_FORM | HTTPREQ_POST_MIME => { + expectsend = (*http).postsize; + } + _ => {} } - HTTPREQ_POST_FORM | HTTPREQ_POST_MIME => { - expectsend = (*http).postsize; - } - _ => {} } - } - (*conn).bits.set_rewindaftersend(0 as bit); /* default */ + (*conn).bits.set_rewindaftersend(0 as bit); /* default */ - if expectsend == -1 as i64 || expectsend > bytessent { - match () { - #[cfg(USE_NTLM)] - /* There is still data left to send */ - _ => { - if (*data).state.authproxy.picked == CURLAUTH_NTLM - || (*data).state.authhost.picked == CURLAUTH_NTLM - || (*data).state.authproxy.picked == CURLAUTH_NTLM_WB - || (*data).state.authhost.picked == CURLAUTH_NTLM_WB - { - if expectsend - bytessent < 2000 as i64 - || (*conn).http_ntlm_state as u32 != NTLMSTATE_NONE as i32 as u32 - || (*conn).proxy_ntlm_state as u32 != NTLMSTATE_NONE as i32 as u32 + if expectsend == -1 as i64 || expectsend > bytessent { + match () { + #[cfg(USE_NTLM)] + /* There is still data left to send */ + _ => { + if (*data).state.authproxy.picked == CURLAUTH_NTLM + || (*data).state.authhost.picked == CURLAUTH_NTLM + || (*data).state.authproxy.picked == CURLAUTH_NTLM_WB + || (*data).state.authhost.picked == CURLAUTH_NTLM_WB { - /* The NTLM-negotiation has started *OR* there is just a little (<2K) - data left to send, keep on sending. */ + if expectsend - bytessent < 2000 as i64 + || (*conn).http_ntlm_state as u32 != NTLMSTATE_NONE as i32 as u32 + || (*conn).proxy_ntlm_state as u32 != NTLMSTATE_NONE as i32 as u32 + { + /* The NTLM-negotiation has started *OR* there is just a little (<2K) + data left to send, keep on sending. */ - /* rewind data when completely done sending! */ - if ((*conn).bits).authneg() == 0 && (*conn).writesockfd != -1 { - (*conn).bits.set_rewindaftersend(1 as bit); - Curl_infof( - data, - b"Rewind stream after send\0" as *const u8 as *const libc::c_char, - ); - } + /* rewind data when completely done sending! */ + if ((*conn).bits).authneg() == 0 && (*conn).writesockfd != -1 { + (*conn).bits.set_rewindaftersend(1 as bit); + Curl_infof( + data, + b"Rewind stream after send\0" as *const u8 + as *const libc::c_char, + ); + } - return CURLE_OK; - } + return CURLE_OK; + } - if ((*conn).bits).close() != 0 { - /* this is already marked to get closed */ - return CURLE_OK; + if ((*conn).bits).close() != 0 { + /* this is already marked to get closed */ + return CURLE_OK; + } + Curl_infof( + data, + b"NTLM send, close instead of sending %ld bytes\0" as *const u8 + as *const libc::c_char, + expectsend - bytessent, + ); } - Curl_infof( - data, - b"NTLM send, close instead of sending %ld bytes\0" as *const u8 - as *const libc::c_char, - expectsend - bytessent, - ); } + #[cfg(not(USE_NTLM))] + _ => {} } - #[cfg(not(USE_NTLM))] - _ => {} - } - // TODO 待测试 - match () { - #[cfg(USE_SPNEGO)] - /* There is still data left to send */ - _ => { - if (*data).state.authproxy.picked == CURLAUTH_NEGOTIATE - || (*data).state.authhost.picked == CURLAUTH_NEGOTIATE - { - if expectsend - bytessent < 2000 as i64 - || (*conn).http_negotiate_state as u32 != GSS_AUTHNONE as i32 as u32 - || (*conn).proxy_negotiate_state as u32 != GSS_AUTHNONE as i32 as u32 + // TODO 待测试 + match () { + #[cfg(USE_SPNEGO)] + /* There is still data left to send */ + _ => { + if (*data).state.authproxy.picked == CURLAUTH_NEGOTIATE + || (*data).state.authhost.picked == CURLAUTH_NEGOTIATE { - /* The NEGOTIATE-negotiation has started *OR* - there is just a little (<2K) data left to send, keep on sending. */ + if expectsend - bytessent < 2000 as i64 + || (*conn).http_negotiate_state as u32 != GSS_AUTHNONE as i32 as u32 + || (*conn).proxy_negotiate_state as u32 != GSS_AUTHNONE as i32 as u32 + { + /* The NEGOTIATE-negotiation has started *OR* + there is just a little (<2K) data left to send, keep on sending. */ - /* rewind data when completely done sending! */ - if ((*conn).bits).authneg() == 0 && (*conn).writesockfd != -1 { - (*conn).bits.set_rewindaftersend(1 as bit); - Curl_infof( - data, - b"Rewind stream after send\0" as *const u8 as *const libc::c_char, - ); + /* rewind data when completely done sending! */ + if ((*conn).bits).authneg() == 0 && (*conn).writesockfd != -1 { + (*conn).bits.set_rewindaftersend(1 as bit); + Curl_infof( + data, + b"Rewind stream after send\0" as *const u8 + as *const libc::c_char, + ); + } + return CURLE_OK; } - return CURLE_OK; - } - if ((*conn).bits).close() != 0 { - return CURLE_OK; + if ((*conn).bits).close() != 0 { + return CURLE_OK; + } + Curl_infof( + data, + b"NEGOTIATE send, close instead of sending %ld bytes\0" as *const u8 + as *const libc::c_char, + expectsend - bytessent, + ); } - Curl_infof( - data, - b"NEGOTIATE send, close instead of sending %ld bytes\0" as *const u8 - as *const libc::c_char, - expectsend - bytessent, - ); } + #[cfg(not(USE_SPNEGO))] + _ => {} } - #[cfg(not(USE_SPNEGO))] - _ => {} - } - /* This is not NEGOTIATE/NTLM or many bytes left to send: close */ - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 2); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 2, - b"Mid-auth HTTP and much data left to send\0" as *const u8 as *const libc::c_char, - ); - (*data).req.size = 0 as curl_off_t; /* don't download any more than 0 bytes */ - /* There still is data left to send, but this connection is marked for - closure so we can safely do the rewind right now */ - } - if bytessent != 0 { - /* we rewind now at once since if we already sent something */ - return Curl_readrewind(data); - } + /* This is not NEGOTIATE/NTLM or many bytes left to send: close */ + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 2); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 2, + b"Mid-auth HTTP and much data left to send\0" as *const u8 as *const libc::c_char, + ); + (*data).req.size = 0 as curl_off_t; /* don't download any more than 0 bytes */ + /* There still is data left to send, but this connection is marked for + closure so we can safely do the rewind right now */ + } + if bytessent != 0 { + /* we rewind now at once since if we already sent something */ + return Curl_readrewind(data); + } } return CURLE_OK; } @@ -710,149 +718,149 @@ extern "C" fn http_perhapsrewind( */ #[no_mangle] pub extern "C" fn Curl_http_auth_act(mut data: *mut Curl_easy) -> CURLcode { - let mut conn: *mut connectdata =unsafe { (*data).conn}; + let mut conn: *mut connectdata = unsafe { (*data).conn }; let mut pickhost: bool = false; let mut pickproxy: bool = false; let mut result: CURLcode = CURLE_OK; let mut authmask: u64 = !(0 as u64); unsafe { - if ((*data).set.str_0[STRING_BEARER as i32 as usize]).is_null() { - authmask &= !CURLAUTH_BEARER; - } - - if 100 <= (*data).req.httpcode && 199 >= (*data).req.httpcode { - /* this is a transient response code, ignore */ - return CURLE_OK; - } - - if ((*data).state).authproblem() != 0 { - return (if ((*data).set).http_fail_on_error() as i32 != 0 { - CURLE_HTTP_RETURNED_ERROR as i32 - } else { - CURLE_OK as i32 - }) as CURLcode; - } - - if (((*conn).bits).user_passwd() as i32 != 0 - || !((*data).set.str_0[STRING_BEARER as i32 as usize]).is_null()) - && ((*data).req.httpcode == 401 - || ((*conn).bits).authneg() as i32 != 0 && (*data).req.httpcode < 300) - { - pickhost = pickoneauth(&mut (*data).state.authhost, authmask); - if !pickhost { - (*data).state.set_authproblem(1 as bit); + if ((*data).set.str_0[STRING_BEARER as i32 as usize]).is_null() { + authmask &= !CURLAUTH_BEARER; } - if (*data).state.authhost.picked == CURLAUTH_NTLM && (*conn).httpversion as i32 > 11 { - Curl_infof( - data, - b"Forcing HTTP/1.1 for NTLM\0" as *const u8 as *const libc::c_char, - ); - - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 1); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 1, - b"Force HTTP/1.1 connection\0" as *const u8 as *const libc::c_char, - ); - (*data).state.httpwant = CURL_HTTP_VERSION_1_1 as i32 as u8; + if 100 <= (*data).req.httpcode && 199 >= (*data).req.httpcode { + /* this is a transient response code, ignore */ + return CURLE_OK; } - } - #[cfg(not(CURL_DISABLE_PROXY))] - if ((*conn).bits).proxy_user_passwd() as i32 != 0 - && ((*data).req.httpcode == 407 - || ((*conn).bits).authneg() as i32 != 0 && (*data).req.httpcode < 300) - { - pickproxy = pickoneauth(&mut (*data).state.authproxy, authmask & !((1 as u64) << 6)); - if !pickproxy { - (*data).state.set_authproblem(1 as bit); + if ((*data).state).authproblem() != 0 { + return (if ((*data).set).http_fail_on_error() as i32 != 0 { + CURLE_HTTP_RETURNED_ERROR as i32 + } else { + CURLE_OK as i32 + }) as CURLcode; } - } - if pickhost as i32 != 0 || pickproxy as i32 != 0 { - if (*data).state.httpreq as u32 != HTTPREQ_GET as u32 - && (*data).state.httpreq as u32 != HTTPREQ_HEAD as u32 - && ((*conn).bits).rewindaftersend() == 0 + + if (((*conn).bits).user_passwd() as i32 != 0 + || !((*data).set.str_0[STRING_BEARER as i32 as usize]).is_null()) + && ((*data).req.httpcode == 401 + || ((*conn).bits).authneg() as i32 != 0 && (*data).req.httpcode < 300) { - result = http_perhapsrewind(data, conn); - if result as u64 != 0 { - return result; - } - } - match () { - #[cfg(not(CURLDEBUG))] - _ => { - /* In case this is GSS auth, the newurl field is already allocated so - we must make sure to free it before allocating a new one. As figured - out in bug #2284386 */ - Curl_cfree.expect("non-null function pointer")( - (*data).req.newurl as *mut libc::c_void, - ); - (*data).req.newurl = 0 as *mut libc::c_char; - /* clone URL */ - (*data).req.newurl = - Curl_cstrdup.expect("non-null function pointer")((*data).state.url); + pickhost = pickoneauth(&mut (*data).state.authhost, authmask); + if !pickhost { + (*data).state.set_authproblem(1 as bit); } - #[cfg(CURLDEBUG)] - _ => { - /* In case this is GSS auth, the newurl field is already allocated so - we must make sure to free it before allocating a new one. As figured - out in bug #2284386 */ - curl_dbg_free( - (*data).req.newurl as *mut libc::c_void, - 626, - b"http.c\0" as *const u8 as *const libc::c_char, + + if (*data).state.authhost.picked == CURLAUTH_NTLM && (*conn).httpversion as i32 > 11 { + Curl_infof( + data, + b"Forcing HTTP/1.1 for NTLM\0" as *const u8 as *const libc::c_char, ); - (*data).req.newurl = 0 as *mut libc::c_char; - /* clone URL */ - (*data).req.newurl = curl_dbg_strdup( - (*data).state.url, - 627, - b"http.c\0" as *const u8 as *const libc::c_char, + + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 1); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 1, + b"Force HTTP/1.1 connection\0" as *const u8 as *const libc::c_char, ); + (*data).state.httpwant = CURL_HTTP_VERSION_1_1 as i32 as u8; } } - if ((*data).req.newurl).is_null() { - return CURLE_OUT_OF_MEMORY; - } - } else if (*data).req.httpcode < 300 - && ((*data).state.authhost).done() == 0 - && ((*conn).bits).authneg() as i32 != 0 - { - /* no (known) authentication available, - authentication is not "done" yet and - no authentication seems to be required and - we didn't try HEAD or GET */ - if (*data).state.httpreq as u32 != HTTPREQ_GET as u32 - && (*data).state.httpreq as u32 != HTTPREQ_HEAD as u32 + + #[cfg(not(CURL_DISABLE_PROXY))] + if ((*conn).bits).proxy_user_passwd() as i32 != 0 + && ((*data).req.httpcode == 407 + || ((*conn).bits).authneg() as i32 != 0 && (*data).req.httpcode < 300) { - #[cfg(not(CURLDEBUG))] - let new_url: *mut libc::c_char = - Curl_cstrdup.expect("non-null function pointer")((*data).state.url); - #[cfg(CURLDEBUG)] - let new_url: *mut libc::c_char = curl_dbg_strdup( - (*data).state.url, - 640, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - (*data).req.newurl = new_url; /* clone URL */ + pickproxy = pickoneauth(&mut (*data).state.authproxy, authmask & !((1 as u64) << 6)); + if !pickproxy { + (*data).state.set_authproblem(1 as bit); + } + } + if pickhost as i32 != 0 || pickproxy as i32 != 0 { + if (*data).state.httpreq as u32 != HTTPREQ_GET as u32 + && (*data).state.httpreq as u32 != HTTPREQ_HEAD as u32 + && ((*conn).bits).rewindaftersend() == 0 + { + result = http_perhapsrewind(data, conn); + if result as u64 != 0 { + return result; + } + } + match () { + #[cfg(not(CURLDEBUG))] + _ => { + /* In case this is GSS auth, the newurl field is already allocated so + we must make sure to free it before allocating a new one. As figured + out in bug #2284386 */ + Curl_cfree.expect("non-null function pointer")( + (*data).req.newurl as *mut libc::c_void, + ); + (*data).req.newurl = 0 as *mut libc::c_char; + /* clone URL */ + (*data).req.newurl = + Curl_cstrdup.expect("non-null function pointer")((*data).state.url); + } + #[cfg(CURLDEBUG)] + _ => { + /* In case this is GSS auth, the newurl field is already allocated so + we must make sure to free it before allocating a new one. As figured + out in bug #2284386 */ + curl_dbg_free( + (*data).req.newurl as *mut libc::c_void, + 626, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).req.newurl = 0 as *mut libc::c_char; + /* clone URL */ + (*data).req.newurl = curl_dbg_strdup( + (*data).state.url, + 627, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + } + } if ((*data).req.newurl).is_null() { return CURLE_OUT_OF_MEMORY; } - (*data).state.authhost.set_done(1 as bit); + } else if (*data).req.httpcode < 300 + && ((*data).state.authhost).done() == 0 + && ((*conn).bits).authneg() as i32 != 0 + { + /* no (known) authentication available, + authentication is not "done" yet and + no authentication seems to be required and + we didn't try HEAD or GET */ + if (*data).state.httpreq as u32 != HTTPREQ_GET as u32 + && (*data).state.httpreq as u32 != HTTPREQ_HEAD as u32 + { + #[cfg(not(CURLDEBUG))] + let new_url: *mut libc::c_char = + Curl_cstrdup.expect("non-null function pointer")((*data).state.url); + #[cfg(CURLDEBUG)] + let new_url: *mut libc::c_char = curl_dbg_strdup( + (*data).state.url, + 640, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).req.newurl = new_url; /* clone URL */ + if ((*data).req.newurl).is_null() { + return CURLE_OUT_OF_MEMORY; + } + (*data).state.authhost.set_done(1 as bit); + } + } + if http_should_fail(data) { + Curl_failf( + data, + b"The requested URL returned error: %d\0" as *const u8 as *const libc::c_char, + (*data).req.httpcode, + ); + result = CURLE_HTTP_RETURNED_ERROR; } } - if http_should_fail(data) { - Curl_failf( - data, - b"The requested URL returned error: %d\0" as *const u8 as *const libc::c_char, - (*data).req.httpcode, - ); - result = CURLE_HTTP_RETURNED_ERROR; - } -} return result; } @@ -873,156 +881,162 @@ extern "C" fn output_auth_headers( let mut result: CURLcode = CURLE_OK; let flag1: bool = if cfg!(not(CURL_DISABLE_CRYPTO_AUTH)) { - unsafe { (*authstatus).picked == CURLAUTH_AWS_SIGV4} + unsafe { (*authstatus).picked == CURLAUTH_AWS_SIGV4 } } else { false }; let flag2: bool = if cfg!(USE_SPNEGO) { - unsafe { (*authstatus).picked == CURLAUTH_NEGOTIATE} + unsafe { (*authstatus).picked == CURLAUTH_NEGOTIATE } } else { false }; let flag3: bool = if cfg!(USE_NTLM) { - unsafe {(*authstatus).picked == CURLAUTH_NTLM} + unsafe { (*authstatus).picked == CURLAUTH_NTLM } } else { false }; let flag4: bool = if cfg!(all(USE_NTLM, NTLM_WB_ENABLED)) { - unsafe { (*authstatus).picked == CURLAUTH_NTLM_WB} + unsafe { (*authstatus).picked == CURLAUTH_NTLM_WB } } else { false }; let flag5: bool = if cfg!(not(CURL_DISABLE_CRYPTO_AUTH)) { - unsafe { (*authstatus).picked == CURLAUTH_DIGEST} + unsafe { (*authstatus).picked == CURLAUTH_DIGEST } } else { false }; if flag1 { auth = b"AWS_SIGV4\0" as *const u8 as *const libc::c_char; - result =unsafe { Curl_output_aws_sigv4(data, proxy)}; + result = unsafe { Curl_output_aws_sigv4(data, proxy) }; if result as u64 != 0 { return result; } } else if flag2 { auth = b"Negotiate\0" as *const u8 as *const libc::c_char; - result =unsafe { Curl_output_negotiate(data, conn, proxy)}; + result = unsafe { Curl_output_negotiate(data, conn, proxy) }; if result as u64 != 0 { return result; } } else if flag3 { auth = b"NTLM\0" as *const u8 as *const libc::c_char; - result = unsafe {Curl_output_ntlm(data, proxy)}; + result = unsafe { Curl_output_ntlm(data, proxy) }; if result as u64 != 0 { return result; } } else if flag4 { auth = b"NTLM_WB\0" as *const u8 as *const libc::c_char; - result =unsafe { Curl_output_ntlm_wb(data, conn, proxy)}; + result = unsafe { Curl_output_ntlm_wb(data, conn, proxy) }; if result as u64 != 0 { return result; } } else if flag5 { auth = b"Digest\0" as *const u8 as *const libc::c_char; - result = unsafe {Curl_output_digest(data, proxy, request as *const u8, path as *const u8)}; + result = + unsafe { Curl_output_digest(data, proxy, request as *const u8, path as *const u8) }; if result as u64 != 0 { return result; } - } else if unsafe {(*authstatus).picked == CURLAUTH_BASIC} { + } else if unsafe { (*authstatus).picked == CURLAUTH_BASIC } { unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let flag6: bool = proxy as i32 != 0 - && ((*conn).bits).proxy_user_passwd() as i32 != 0 - && (Curl_checkProxyheaders( - data, - conn, - b"Proxy-authorization\0" as *const u8 as *const libc::c_char, - )) - .is_null() - || !proxy + #[cfg(not(CURL_DISABLE_PROXY))] + let flag6: bool = proxy as i32 != 0 + && ((*conn).bits).proxy_user_passwd() as i32 != 0 + && (Curl_checkProxyheaders( + data, + conn, + b"Proxy-authorization\0" as *const u8 as *const libc::c_char, + )) + .is_null() + || !proxy + && ((*conn).bits).user_passwd() as i32 != 0 + && (Curl_checkheaders( + data, + b"Authorization\0" as *const u8 as *const libc::c_char, + )) + .is_null(); + #[cfg(CURL_DISABLE_PROXY)] + let flag6: bool = !proxy && ((*conn).bits).user_passwd() as i32 != 0 && (Curl_checkheaders( data, b"Authorization\0" as *const u8 as *const libc::c_char, )) .is_null(); - #[cfg(CURL_DISABLE_PROXY)] - let flag6: bool = !proxy - && ((*conn).bits).user_passwd() as i32 != 0 - && (Curl_checkheaders(data, b"Authorization\0" as *const u8 as *const libc::c_char)) - .is_null(); - if flag6 { - auth = b"Basic\0" as *const u8 as *const libc::c_char; - result = http_output_basic(data, proxy); - if result as u64 != 0 { - return result; + if flag6 { + auth = b"Basic\0" as *const u8 as *const libc::c_char; + result = http_output_basic(data, proxy); + if result as u64 != 0 { + return result; + } } - } - /* NOTE: this function should set 'done' TRUE, as the other auth - functions work that way */ - (*authstatus).set_done(1 as bit); - } + /* NOTE: this function should set 'done' TRUE, as the other auth + functions work that way */ + (*authstatus).set_done(1 as bit); + } } - if unsafe {(*authstatus).picked == CURLAUTH_BEARER} { + if unsafe { (*authstatus).picked == CURLAUTH_BEARER } { unsafe { - /* Bearer */ - if !proxy - && !((*data).set.str_0[STRING_BEARER as i32 as usize]).is_null() - && (Curl_checkheaders(data, b"Authorization\0" as *const u8 as *const libc::c_char)) - .is_null() - { - auth = b"Bearer\0" as *const u8 as *const libc::c_char; - result = http_output_bearer(data); - if result as u64 != 0 { - return result; + /* Bearer */ + if !proxy + && !((*data).set.str_0[STRING_BEARER as i32 as usize]).is_null() + && (Curl_checkheaders(data, b"Authorization\0" as *const u8 as *const libc::c_char)) + .is_null() + { + auth = b"Bearer\0" as *const u8 as *const libc::c_char; + result = http_output_bearer(data); + if result as u64 != 0 { + return result; + } } - } - /* NOTE: this function should set 'done' TRUE, as the other auth - functions work that way */ - (*authstatus).set_done(1 as bit);} + /* NOTE: this function should set 'done' TRUE, as the other auth + functions work that way */ + (*authstatus).set_done(1 as bit); + } } if !auth.is_null() { unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - Curl_infof( - data, - b"%s auth using %s with user '%s'\0" as *const u8 as *const libc::c_char, - if proxy as i32 != 0 { - b"Proxy\0" as *const u8 as *const libc::c_char - } else { - b"Server\0" as *const u8 as *const libc::c_char - }, - auth, - if proxy as i32 != 0 { - if !((*data).state.aptr.proxyuser).is_null() { - (*data).state.aptr.proxyuser as *const libc::c_char + #[cfg(not(CURL_DISABLE_PROXY))] + Curl_infof( + data, + b"%s auth using %s with user '%s'\0" as *const u8 as *const libc::c_char, + if proxy as i32 != 0 { + b"Proxy\0" as *const u8 as *const libc::c_char + } else { + b"Server\0" as *const u8 as *const libc::c_char + }, + auth, + if proxy as i32 != 0 { + if !((*data).state.aptr.proxyuser).is_null() { + (*data).state.aptr.proxyuser as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + } + } else if !((*data).state.aptr.user).is_null() { + (*data).state.aptr.user as *const libc::c_char } else { b"\0" as *const u8 as *const libc::c_char - } - } else if !((*data).state.aptr.user).is_null() { - (*data).state.aptr.user as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - ); - #[cfg(CURL_DISABLE_PROXY)] - Curl_infof( - data, - b"Server auth using %s with user '%s'\0" as *const u8 as *const libc::c_char, - auth, - if !((*data).state.aptr.user).is_null() { - (*data).state.aptr.user as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - ); - (*authstatus).set_multipass((if (*authstatus).done() == 0 { 1 } else { 0 }) as bit); - } + }, + ); + #[cfg(CURL_DISABLE_PROXY)] + Curl_infof( + data, + b"Server auth using %s with user '%s'\0" as *const u8 as *const libc::c_char, + auth, + if !((*data).state.aptr.user).is_null() { + (*data).state.aptr.user as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + (*authstatus).set_multipass((if (*authstatus).done() == 0 { 1 } else { 0 }) as bit); + } } else { unsafe { - (*authstatus).set_multipass(0 as bit);} + (*authstatus).set_multipass(0 as bit); + } } return CURLE_OK; } @@ -1054,12 +1068,12 @@ pub extern "C" fn Curl_http_output_auth( let mut result: CURLcode = CURLE_OK; let mut authhost: *mut auth = 0 as *mut auth; let mut authproxy: *mut auth = 0 as *mut auth; - + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - unsafe{ - if !data.is_null() { - } else { - __assert_fail( + unsafe { + if !data.is_null() { + } else { + __assert_fail( b"data\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 805 as libc::c_int as libc::c_uint, @@ -1071,99 +1085,115 @@ pub extern "C" fn Curl_http_output_auth( )) .as_ptr(), ); - }} - authhost = unsafe{&mut (*data).state.authhost}; - authproxy =unsafe{ &mut (*data).state.authproxy}; + } + } + authhost = unsafe { &mut (*data).state.authhost }; + authproxy = unsafe { &mut (*data).state.authproxy }; #[cfg(not(CURL_DISABLE_PROXY))] - let flag1: bool = unsafe{((*conn).bits).httpproxy() as libc::c_int != 0 - && ((*conn).bits).proxy_user_passwd() as libc::c_int != 0 - || ((*conn).bits).user_passwd() as libc::c_int != 0 - || !((*data).set.str_0[STRING_BEARER as libc::c_int as usize]).is_null()}; + let flag1: bool = unsafe { + ((*conn).bits).httpproxy() as libc::c_int != 0 + && ((*conn).bits).proxy_user_passwd() as libc::c_int != 0 + || ((*conn).bits).user_passwd() as libc::c_int != 0 + || !((*data).set.str_0[STRING_BEARER as libc::c_int as usize]).is_null() + }; #[cfg(CURL_DISABLE_PROXY)] - let flag1: bool =unsafe{ ((*conn).bits).user_passwd() as libc::c_int != 0 - || !((*data).set.str_0[STRING_BEARER as libc::c_int as usize]).is_null()}; + let flag1: bool = unsafe { + ((*conn).bits).user_passwd() as libc::c_int != 0 + || !((*data).set.str_0[STRING_BEARER as libc::c_int as usize]).is_null() + }; if flag1 { } else { - unsafe{ - (*authhost).set_done(1 as libc::c_int as bit); - (*authproxy).set_done(1 as libc::c_int as bit);} + unsafe { + (*authhost).set_done(1 as libc::c_int as bit); + (*authproxy).set_done(1 as libc::c_int as bit); + } return CURLE_OK; } - if unsafe{(*authhost).want != 0 && (*authhost).picked == 0} { + if unsafe { (*authhost).want != 0 && (*authhost).picked == 0 } { /* The app has selected one or more methods, but none has been picked so far by a server round-trip. Then we set the picked one to the want one, and if this is one single bit it'll be used instantly. */ - unsafe{(*authhost).picked = (*authhost).want;} + unsafe { + (*authhost).picked = (*authhost).want; + } } - if unsafe{(*authproxy).want != 0 && (*authproxy).picked == 0} { + if unsafe { (*authproxy).want != 0 && (*authproxy).picked == 0 } { /* The app has selected one or more methods, but none has been picked so far by a proxy round-trip. Then we set the picked one to the want one, and if this is one single bit it'll be used instantly. */ - unsafe{(*authproxy).picked = (*authproxy).want;} + unsafe { + (*authproxy).picked = (*authproxy).want; + } } - unsafe{ - match () { - #[cfg(not(CURL_DISABLE_PROXY))] - /* Send proxy authentication header if needed */ - _ => { - if ((*conn).bits).httpproxy() as libc::c_int != 0 - && ((*conn).bits).tunnel_proxy() == proxytunnel as bit - { - result = output_auth_headers( - data, - conn, - authproxy, - request, - path, - 1 as libc::c_int != 0, - ); - if result as u64 != 0 { - return result; + unsafe { + match () { + #[cfg(not(CURL_DISABLE_PROXY))] + /* Send proxy authentication header if needed */ + _ => { + if ((*conn).bits).httpproxy() as libc::c_int != 0 + && ((*conn).bits).tunnel_proxy() == proxytunnel as bit + { + result = output_auth_headers( + data, + conn, + authproxy, + request, + path, + 1 as libc::c_int != 0, + ); + if result as u64 != 0 { + return result; + } + } else { + (*authproxy).set_done(1 as libc::c_int as bit); } - } else { + } + /* CURL_DISABLE_PROXY */ + #[cfg(CURL_DISABLE_PROXY)] + /* we have no proxy so let's pretend we're done authenticating + with it */ + _ => { (*authproxy).set_done(1 as libc::c_int as bit); } } - /* CURL_DISABLE_PROXY */ - #[cfg(CURL_DISABLE_PROXY)] - /* we have no proxy so let's pretend we're done authenticating - with it */ - _ => { - (*authproxy).set_done(1 as libc::c_int as bit); - } } -} #[cfg(not(CURL_DISABLE_NETRC))] - let flag2: bool =unsafe{ ((*data).state).this_is_a_follow() == 0 - || ((*conn).bits).netrc() as libc::c_int != 0 - || ((*data).state.first_host).is_null() - || ((*data).set).allow_auth_to_other_hosts() as libc::c_int != 0 - || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0}; + let flag2: bool = unsafe { + ((*data).state).this_is_a_follow() == 0 + || ((*conn).bits).netrc() as libc::c_int != 0 + || ((*data).state.first_host).is_null() + || ((*data).set).allow_auth_to_other_hosts() as libc::c_int != 0 + || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0 + }; /* To prevent the user+password to get sent to other than the original host due to a location-follow, we do some weirdo checks here */ #[cfg(CURL_DISABLE_NETRC)] - let flag2: bool =unsafe{ ((*data).state).this_is_a_follow() == 0 - || ((*data).state.first_host).is_null() - || ((*data).set).allow_auth_to_other_hosts() as libc::c_int != 0 - || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0}; - unsafe{ - if flag2 { - result = output_auth_headers(data, conn, authhost, request, path, 0 as libc::c_int != 0); - } else { - (*authhost).set_done(1 as libc::c_int as bit); + let flag2: bool = unsafe { + ((*data).state).this_is_a_follow() == 0 + || ((*data).state.first_host).is_null() + || ((*data).set).allow_auth_to_other_hosts() as libc::c_int != 0 + || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0 + }; + unsafe { + if flag2 { + result = + output_auth_headers(data, conn, authhost, request, path, 0 as libc::c_int != 0); + } else { + (*authhost).set_done(1 as libc::c_int as bit); + } + if ((*authhost).multipass() as libc::c_int != 0 && (*authhost).done() == 0 + || (*authproxy).multipass() as libc::c_int != 0 && (*authproxy).done() == 0) + && httpreq as libc::c_uint != HTTPREQ_GET as libc::c_int as libc::c_uint + && httpreq as libc::c_uint != HTTPREQ_HEAD as libc::c_int as libc::c_uint + { + let ref mut fresh8 = (*conn).bits; + (*fresh8).set_authneg(1 as libc::c_int as bit); + } else { + let ref mut fresh9 = (*conn).bits; + (*fresh9).set_authneg(0 as libc::c_int as bit); + } } - if ((*authhost).multipass() as libc::c_int != 0 && (*authhost).done() == 0 - || (*authproxy).multipass() as libc::c_int != 0 && (*authproxy).done() == 0) - && httpreq as libc::c_uint != HTTPREQ_GET as libc::c_int as libc::c_uint - && httpreq as libc::c_uint != HTTPREQ_HEAD as libc::c_int as libc::c_uint - { - let ref mut fresh8 = (*conn).bits; - (*fresh8).set_authneg(1 as libc::c_int as bit); - } else { - let ref mut fresh9 = (*conn).bits; - (*fresh9).set_authneg(0 as libc::c_int as bit); - }} return result; } @@ -1178,8 +1208,9 @@ pub extern "C" fn Curl_http_output_auth( mut path: *const libc::c_char, mut proxytunnel: bool, ) -> CURLcode { - unsafe{ - return CURLE_OK;} + unsafe { + return CURLE_OK; + } } /* @@ -1188,10 +1219,12 @@ pub extern "C" fn Curl_http_output_auth( * proxy CONNECT loop. */ extern "C" fn is_valid_auth_separator(mut ch: libc::c_char) -> libc::c_int { - unsafe{ - return (ch as libc::c_int == '\0' as i32 - || ch as libc::c_int == ',' as i32 - || Curl_isspace(ch as libc::c_uchar as libc::c_int) != 0) as libc::c_int;} + unsafe { + return (ch as libc::c_int == '\0' as i32 + || ch as libc::c_int == ',' as i32 + || Curl_isspace(ch as libc::c_uchar as libc::c_int) != 0) + as libc::c_int; + } } #[no_mangle] @@ -1203,25 +1236,29 @@ pub extern "C" fn Curl_http_input_auth( /* * This resource requires authentication */ - let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut conn: *mut connectdata = unsafe { (*data).conn }; #[cfg(USE_SPNEGO)] - let mut negstate: *mut curlnegotiate =unsafe{ if proxy as i32 != 0 { - &mut (*conn).proxy_negotiate_state - } else { - &mut (*conn).http_negotiate_state - }}; + let mut negstate: *mut curlnegotiate = unsafe { + if proxy as i32 != 0 { + &mut (*conn).proxy_negotiate_state + } else { + &mut (*conn).http_negotiate_state + } + }; let mut availp: *mut u64 = 0 as *mut u64; let mut authp: *mut auth = 0 as *mut auth; if proxy { - unsafe{ - availp = &mut (*data).info.proxyauthavail; - authp = &mut (*data).state.authproxy;} + unsafe { + availp = &mut (*data).info.proxyauthavail; + authp = &mut (*data).state.authproxy; + } } else { - unsafe{ - availp = &mut (*data).info.httpauthavail; - authp = &mut (*data).state.authhost;} + unsafe { + availp = &mut (*data).info.httpauthavail; + authp = &mut (*data).state.authhost; + } } /* @@ -1239,218 +1276,220 @@ pub extern "C" fn Curl_http_input_auth( * headers have been received but then only to a single preferred method * (bit). */ - unsafe{ - while *auth != 0 { - #[cfg(USE_SPNEGO)] - let flag1: bool = curl_strnequal( - b"Negotiate\0" as *const u8 as *const libc::c_char, - auth, - strlen(b"Negotiate\0" as *const u8 as *const libc::c_char), - ) != 0 - && is_valid_auth_separator(*auth.offset(9 as i32 as isize)) != 0; - #[cfg(not(USE_SPNEGO))] - let flag1: bool = false; - #[cfg(USE_NTLM)] - let flag2: bool = curl_strnequal( - b"NTLM\0" as *const u8 as *const libc::c_char, - auth, - strlen(b"NTLM\0" as *const u8 as *const libc::c_char), - ) != 0 - && is_valid_auth_separator(*auth.offset(4 as isize)) != 0; - #[cfg(not(USE_NTLM))] - let flag2: bool = false; - #[cfg(not(CURL_DISABLE_CRYPTO_AUTH))] - let flag3: bool = curl_strnequal( - b"Digest\0" as *const u8 as *const libc::c_char, - auth, - strlen(b"Digest\0" as *const u8 as *const libc::c_char), - ) != 0 - && is_valid_auth_separator(*auth.offset(6 as isize)) != 0; - #[cfg(CURL_DISABLE_CRYPTO_AUTH)] - let flag3: bool = false; - if flag1 { - match () { - #[cfg(USE_SPNEGO)] - _ => { - if (*authp).avail & (1 as u64) << 2 != 0 - || Curl_auth_is_spnego_supported() as i32 != 0 - { - *availp |= (1 as u64) << 2; - (*authp).avail |= (1 as u64) << 2; - if (*authp).picked == (1 as u64) << 2 { - let mut result: CURLcode = - Curl_input_negotiate(data, conn, proxy, auth); - if result as u64 == 0 { - (*data).req.newurl = Curl_cstrdup - .expect("non-null function pointer")( - (*data).state.url - ); - if ((*data).req.newurl).is_null() { - return CURLE_OUT_OF_MEMORY; + unsafe { + while *auth != 0 { + #[cfg(USE_SPNEGO)] + let flag1: bool = curl_strnequal( + b"Negotiate\0" as *const u8 as *const libc::c_char, + auth, + strlen(b"Negotiate\0" as *const u8 as *const libc::c_char), + ) != 0 + && is_valid_auth_separator(*auth.offset(9 as i32 as isize)) != 0; + #[cfg(not(USE_SPNEGO))] + let flag1: bool = false; + #[cfg(USE_NTLM)] + let flag2: bool = curl_strnequal( + b"NTLM\0" as *const u8 as *const libc::c_char, + auth, + strlen(b"NTLM\0" as *const u8 as *const libc::c_char), + ) != 0 + && is_valid_auth_separator(*auth.offset(4 as isize)) != 0; + #[cfg(not(USE_NTLM))] + let flag2: bool = false; + #[cfg(not(CURL_DISABLE_CRYPTO_AUTH))] + let flag3: bool = curl_strnequal( + b"Digest\0" as *const u8 as *const libc::c_char, + auth, + strlen(b"Digest\0" as *const u8 as *const libc::c_char), + ) != 0 + && is_valid_auth_separator(*auth.offset(6 as isize)) != 0; + #[cfg(CURL_DISABLE_CRYPTO_AUTH)] + let flag3: bool = false; + if flag1 { + match () { + #[cfg(USE_SPNEGO)] + _ => { + if (*authp).avail & (1 as u64) << 2 != 0 + || Curl_auth_is_spnego_supported() as i32 != 0 + { + *availp |= (1 as u64) << 2; + (*authp).avail |= (1 as u64) << 2; + if (*authp).picked == (1 as u64) << 2 { + let mut result: CURLcode = + Curl_input_negotiate(data, conn, proxy, auth); + if result as u64 == 0 { + (*data).req.newurl = Curl_cstrdup + .expect("non-null function pointer")( + (*data).state.url + ); + if ((*data).req.newurl).is_null() { + return CURLE_OUT_OF_MEMORY; + } + (*data).state.set_authproblem(0 as bit); + *negstate = GSS_AUTHRECV; + } else { + (*data).state.set_authproblem(1 as bit); } - (*data).state.set_authproblem(0 as bit); - *negstate = GSS_AUTHRECV; - } else { - (*data).state.set_authproblem(1 as bit); } } } + #[cfg(not(USE_SPNEGO))] + _ => {} } - #[cfg(not(USE_SPNEGO))] - _ => {} - } - // if (*authp).avail & (1 as i32 as u64) << 2 as i32 - // != 0 || Curl_auth_is_spnego_supported() as i32 != 0 - // { - // *availp |= (1 as i32 as u64) << 2 as i32; - // (*authp).avail - // |= (1 as i32 as u64) << 2 as i32; - // if (*authp).picked - // == (1 as i32 as u64) << 2 as i32 - // { - // let mut result: CURLcode = Curl_input_negotiate( - // data, - // conn, - // proxy, - // auth, - // ); - // if result as u64 == 0 { - // (*data).req.newurl = Curl_cstrdup - // .expect("non-null function pointer")((*data).state.url); - // if ((*data).req.newurl).is_null() { - // return CURLE_OUT_OF_MEMORY; - // } - // (*data).state.set_authproblem(0 as i32 as bit); - // *negstate = GSS_AUTHRECV; - // } else { - // (*data).state.set_authproblem(1 as i32 as bit); - // } - // } - // } - } else if flag2 { - if (*authp).avail & CURLAUTH_NTLM != 0 - || (*authp).avail & CURLAUTH_NTLM_WB != 0 - || Curl_auth_is_ntlm_supported() as i32 != 0 - { - *availp |= CURLAUTH_NTLM; - (*authp).avail |= CURLAUTH_NTLM; - if (*authp).picked == CURLAUTH_NTLM || (*authp).picked == CURLAUTH_NTLM_WB { - let mut result_0: CURLcode = Curl_input_ntlm(data, proxy, auth); - if result_0 as u64 == 0 { - (*data).state.set_authproblem(0 as bit); - if (*authp).picked == CURLAUTH_NTLM_WB { - *availp &= !CURLAUTH_NTLM; - (*authp).avail &= !CURLAUTH_NTLM; - *availp |= CURLAUTH_NTLM_WB; - (*authp).avail |= CURLAUTH_NTLM_WB; - result_0 = Curl_input_ntlm_wb(data, conn, proxy, auth); - if result_0 as u64 != 0 { - Curl_infof( - data, - b"Authentication problem. Ignoring this.\0" as *const u8 - as *const libc::c_char, - ); - (*data).state.set_authproblem(1 as bit); + // if (*authp).avail & (1 as i32 as u64) << 2 as i32 + // != 0 || Curl_auth_is_spnego_supported() as i32 != 0 + // { + // *availp |= (1 as i32 as u64) << 2 as i32; + // (*authp).avail + // |= (1 as i32 as u64) << 2 as i32; + // if (*authp).picked + // == (1 as i32 as u64) << 2 as i32 + // { + // let mut result: CURLcode = Curl_input_negotiate( + // data, + // conn, + // proxy, + // auth, + // ); + // if result as u64 == 0 { + // (*data).req.newurl = Curl_cstrdup + // .expect("non-null function pointer")((*data).state.url); + // if ((*data).req.newurl).is_null() { + // return CURLE_OUT_OF_MEMORY; + // } + // (*data).state.set_authproblem(0 as i32 as bit); + // *negstate = GSS_AUTHRECV; + // } else { + // (*data).state.set_authproblem(1 as i32 as bit); + // } + // } + // } + } else if flag2 { + if (*authp).avail & CURLAUTH_NTLM != 0 + || (*authp).avail & CURLAUTH_NTLM_WB != 0 + || Curl_auth_is_ntlm_supported() as i32 != 0 + { + *availp |= CURLAUTH_NTLM; + (*authp).avail |= CURLAUTH_NTLM; + if (*authp).picked == CURLAUTH_NTLM || (*authp).picked == CURLAUTH_NTLM_WB { + let mut result_0: CURLcode = Curl_input_ntlm(data, proxy, auth); + if result_0 as u64 == 0 { + (*data).state.set_authproblem(0 as bit); + if (*authp).picked == CURLAUTH_NTLM_WB { + *availp &= !CURLAUTH_NTLM; + (*authp).avail &= !CURLAUTH_NTLM; + *availp |= CURLAUTH_NTLM_WB; + (*authp).avail |= CURLAUTH_NTLM_WB; + result_0 = Curl_input_ntlm_wb(data, conn, proxy, auth); + if result_0 as u64 != 0 { + Curl_infof( + data, + b"Authentication problem. Ignoring this.\0" as *const u8 + as *const libc::c_char, + ); + (*data).state.set_authproblem(1 as bit); + } } + } else { + Curl_infof( + data, + b"Authentication problem. Ignoring this.\0" as *const u8 + as *const libc::c_char, + ); + (*data).state.set_authproblem(1 as bit); } - } else { - Curl_infof( - data, - b"Authentication problem. Ignoring this.\0" as *const u8 - as *const libc::c_char, - ); - (*data).state.set_authproblem(1 as bit); } } - } - } else if flag3 { - match () { - #[cfg(not(CURL_DISABLE_CRYPTO_AUTH))] - _ => { - if (*authp).avail & CURLAUTH_DIGEST != 0 as u64 { - Curl_infof( - data, - b"Ignoring duplicate digest auth header.\0" as *const u8 - as *const libc::c_char, - ); - } else if Curl_auth_is_digest_supported() { - let mut result: CURLcode = CURLE_OK; - - *availp |= CURLAUTH_DIGEST; - (*authp).avail |= CURLAUTH_DIGEST; - - /* We call this function on input Digest headers even if Digest - * authentication isn't activated yet, as we need to store the - * incoming data from this header in case we are going to use - * Digest */ - result = Curl_input_digest(data, proxy, auth); - if result as u64 != 0 { + } else if flag3 { + match () { + #[cfg(not(CURL_DISABLE_CRYPTO_AUTH))] + _ => { + if (*authp).avail & CURLAUTH_DIGEST != 0 as u64 { Curl_infof( data, - b"Authentication problem. Ignoring this.\0" as *const u8 + b"Ignoring duplicate digest auth header.\0" as *const u8 as *const libc::c_char, ); - (*data).state.set_authproblem(1 as bit); + } else if Curl_auth_is_digest_supported() { + let mut result: CURLcode = CURLE_OK; + + *availp |= CURLAUTH_DIGEST; + (*authp).avail |= CURLAUTH_DIGEST; + + /* We call this function on input Digest headers even if Digest + * authentication isn't activated yet, as we need to store the + * incoming data from this header in case we are going to use + * Digest */ + result = Curl_input_digest(data, proxy, auth); + if result as u64 != 0 { + Curl_infof( + data, + b"Authentication problem. Ignoring this.\0" as *const u8 + as *const libc::c_char, + ); + (*data).state.set_authproblem(1 as bit); + } } } + #[cfg(CURL_DISABLE_CRYPTO_AUTH)] + _ => {} + } + } else if curl_strnequal( + b"Basic\0" as *const u8 as *const libc::c_char, + auth, + strlen(b"Basic\0" as *const u8 as *const libc::c_char), + ) != 0 + && is_valid_auth_separator(*auth.offset(5 as isize)) != 0 + { + *availp |= CURLAUTH_BASIC; + (*authp).avail |= CURLAUTH_BASIC; + if (*authp).picked == CURLAUTH_BASIC { + /* We asked for Basic authentication but got a 40X back + anyway, which basically means our name+password isn't + valid. */ + (*authp).avail = CURLAUTH_NONE; + Curl_infof( + data, + b"Authentication problem. Ignoring this.\0" as *const u8 + as *const libc::c_char, + ); + (*data).state.set_authproblem(1 as bit); + } + } else if curl_strnequal( + b"Bearer\0" as *const u8 as *const libc::c_char, + auth, + strlen(b"Bearer\0" as *const u8 as *const libc::c_char), + ) != 0 + && is_valid_auth_separator(*auth.offset(6 as isize)) != 0 + { + *availp |= CURLAUTH_BEARER; + (*authp).avail |= CURLAUTH_BEARER; + if (*authp).picked == CURLAUTH_BEARER { + /* We asked for Bearer authentication but got a 40X back + anyway, which basically means our token isn't valid. */ + (*authp).avail = CURLAUTH_NONE; + Curl_infof( + data, + b"Authentication problem. Ignoring this.\0" as *const u8 + as *const libc::c_char, + ); + (*data).state.set_authproblem(1 as bit); } - #[cfg(CURL_DISABLE_CRYPTO_AUTH)] - _ => {} } - } else if curl_strnequal( - b"Basic\0" as *const u8 as *const libc::c_char, - auth, - strlen(b"Basic\0" as *const u8 as *const libc::c_char), - ) != 0 - && is_valid_auth_separator(*auth.offset(5 as isize)) != 0 - { - *availp |= CURLAUTH_BASIC; - (*authp).avail |= CURLAUTH_BASIC; - if (*authp).picked == CURLAUTH_BASIC { - /* We asked for Basic authentication but got a 40X back - anyway, which basically means our name+password isn't - valid. */ - (*authp).avail = CURLAUTH_NONE; - Curl_infof( - data, - b"Authentication problem. Ignoring this.\0" as *const u8 as *const libc::c_char, - ); - (*data).state.set_authproblem(1 as bit); + + /* there may be multiple methods on one line, so keep reading */ + while *auth as i32 != 0 && *auth as i32 != ',' as i32 { + /* read up to the next comma */ + auth = auth.offset(1); } - } else if curl_strnequal( - b"Bearer\0" as *const u8 as *const libc::c_char, - auth, - strlen(b"Bearer\0" as *const u8 as *const libc::c_char), - ) != 0 - && is_valid_auth_separator(*auth.offset(6 as isize)) != 0 - { - *availp |= CURLAUTH_BEARER; - (*authp).avail |= CURLAUTH_BEARER; - if (*authp).picked == CURLAUTH_BEARER { - /* We asked for Bearer authentication but got a 40X back - anyway, which basically means our token isn't valid. */ - (*authp).avail = CURLAUTH_NONE; - Curl_infof( - data, - b"Authentication problem. Ignoring this.\0" as *const u8 as *const libc::c_char, - ); - (*data).state.set_authproblem(1 as bit); + if *auth as i32 == ',' as i32 { + /* if we're on a comma, skip it */ + auth = auth.offset(1); + } + while *auth as i32 != 0 && Curl_isspace(*auth as u8 as i32) != 0 { + auth = auth.offset(1); } } - - /* there may be multiple methods on one line, so keep reading */ - while *auth as i32 != 0 && *auth as i32 != ',' as i32 { - /* read up to the next comma */ - auth = auth.offset(1); - } - if *auth as i32 == ',' as i32 { - /* if we're on a comma, skip it */ - auth = auth.offset(1); - } - while *auth as i32 != 0 && Curl_isspace(*auth as u8 as i32) != 0 { - auth = auth.offset(1); - } - } } return CURLE_OK; } @@ -1467,42 +1506,42 @@ pub extern "C" fn Curl_http_input_auth( */ extern "C" fn http_should_fail(mut data: *mut Curl_easy) -> bool { let mut httpcode: i32 = 0; - unsafe{ - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !data.is_null() { - } else { - __assert_fail( - b"data\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 1090 as u32, - (*::std::mem::transmute::<&[u8; 43], &[libc::c_char; 43]>( - b"_Bool http_should_fail(struct Curl_easy *)\0", - )) - .as_ptr(), - ); - } + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !data.is_null() { + } else { + __assert_fail( + b"data\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 1090 as u32, + (*::std::mem::transmute::<&[u8; 43], &[libc::c_char; 43]>( + b"_Bool http_should_fail(struct Curl_easy *)\0", + )) + .as_ptr(), + ); + } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !((*data).conn).is_null() { - } else { - __assert_fail( - b"data->conn\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 1091 as u32, - (*::std::mem::transmute::<&[u8; 43], &[libc::c_char; 43]>( - b"_Bool http_should_fail(struct Curl_easy *)\0", - )) - .as_ptr(), - ); - } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !((*data).conn).is_null() { + } else { + __assert_fail( + b"data->conn\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 1091 as u32, + (*::std::mem::transmute::<&[u8; 43], &[libc::c_char; 43]>( + b"_Bool http_should_fail(struct Curl_easy *)\0", + )) + .as_ptr(), + ); + } } - httpcode =unsafe{ (*data).req.httpcode}; + httpcode = unsafe { (*data).req.httpcode }; /* ** If we haven't been asked to fail on error, ** don't fail. */ - if unsafe{((*data).set).http_fail_on_error() == 0 }{ + if unsafe { ((*data).set).http_fail_on_error() == 0 } { return false; } @@ -1517,10 +1556,11 @@ extern "C" fn http_should_fail(mut data: *mut Curl_easy) -> bool { ** A 416 response to a resume request is presumably because the file is ** already completely downloaded and thus not actually a fail. */ - if unsafe{(*data).state.resume_from != 0 - && (*data).state.httpreq as u32 == HTTPREQ_GET - && httpcode == 416} - { + if unsafe { + (*data).state.resume_from != 0 + && (*data).state.httpreq as u32 == HTTPREQ_GET + && httpcode == 416 + } { return false; } @@ -1536,19 +1576,19 @@ extern "C" fn http_should_fail(mut data: *mut Curl_easy) -> bool { ** All we have left to deal with is 401 and 407 */ #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - unsafe{ - if httpcode == 401 || httpcode == 407 { - } else { - __assert_fail( - b"(httpcode == 401) || (httpcode == 407)\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 1126 as u32, - (*::std::mem::transmute::<&[u8; 43], &[libc::c_char; 43]>( - b"_Bool http_should_fail(struct Curl_easy *)\0", - )) - .as_ptr(), - ); - } + unsafe { + if httpcode == 401 || httpcode == 407 { + } else { + __assert_fail( + b"(httpcode == 401) || (httpcode == 407)\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 1126 as u32, + (*::std::mem::transmute::<&[u8; 43], &[libc::c_char; 43]>( + b"_Bool http_should_fail(struct Curl_easy *)\0", + )) + .as_ptr(), + ); + } } /* ** Examine the current authentication state to see if this @@ -1568,15 +1608,16 @@ extern "C" fn http_should_fail(mut data: *mut Curl_easy) -> bool { ** Either we're not authenticating, or we're supposed to ** be authenticating something else. This is an error. */ - unsafe{ - if httpcode == 401 && ((*(*data).conn).bits).user_passwd() == 0 { - return true; - } - #[cfg(not(CURL_DISABLE_PROXY))] - if httpcode == 407 && ((*(*data).conn).bits).proxy_user_passwd() == 0 { - return true; + unsafe { + if httpcode == 401 && ((*(*data).conn).bits).user_passwd() == 0 { + return true; + } + #[cfg(not(CURL_DISABLE_PROXY))] + if httpcode == 407 && ((*(*data).conn).bits).proxy_user_passwd() == 0 { + return true; + } + return ((*data).state).authproblem() != 0; } - return ((*data).state).authproblem() != 0;} } /* @@ -1595,62 +1636,63 @@ extern "C" fn readmoredata( mut userp: *mut libc::c_void, ) -> size_t { let mut data: *mut Curl_easy = userp as *mut Curl_easy; - let mut http: *mut HTTP = unsafe{(*data).req.p.http}; + let mut http: *mut HTTP = unsafe { (*data).req.p.http }; let mut fullsize: size_t = size.wrapping_mul(nitems); - unsafe{ - if (*http).postsize == 0 { - /* nothing to return */ - return 0 as size_t; - } + unsafe { + if (*http).postsize == 0 { + /* nothing to return */ + return 0 as size_t; + } - /* make sure that a HTTP request is never sent away chunked! */ - (*data).req.set_forbidchunk( - (if (*http).sending as u32 == HTTPSEND_REQUEST { - 1 - } else { - 0 - }) as bit, - ); - - /* speed limit */ - if (*data).set.max_send_speed != 0 - && (*data).set.max_send_speed < fullsize as curl_off_t - && (*data).set.max_send_speed < (*http).postsize - { - fullsize = (*data).set.max_send_speed as size_t; - } else if (*http).postsize <= fullsize as curl_off_t { - memcpy( - buffer as *mut libc::c_void, - (*http).postdata as *const libc::c_void, - (*http).postsize as size_t, + /* make sure that a HTTP request is never sent away chunked! */ + (*data).req.set_forbidchunk( + (if (*http).sending as u32 == HTTPSEND_REQUEST { + 1 + } else { + 0 + }) as bit, ); - fullsize = (*http).postsize as size_t; - if (*http).backup.postsize != 0 { - /* move backup data into focus and continue on that */ - (*http).postdata = (*http).backup.postdata; - (*http).postsize = (*http).backup.postsize; - (*data).state.fread_func = (*http).backup.fread_func; - (*data).state.in_0 = (*http).backup.fread_in; + /* speed limit */ + if (*data).set.max_send_speed != 0 + && (*data).set.max_send_speed < fullsize as curl_off_t + && (*data).set.max_send_speed < (*http).postsize + { + fullsize = (*data).set.max_send_speed as size_t; + } else if (*http).postsize <= fullsize as curl_off_t { + memcpy( + buffer as *mut libc::c_void, + (*http).postdata as *const libc::c_void, + (*http).postsize as size_t, + ); + fullsize = (*http).postsize as size_t; - (*http).sending += 1; /* move one step up */ + if (*http).backup.postsize != 0 { + /* move backup data into focus and continue on that */ + (*http).postdata = (*http).backup.postdata; + (*http).postsize = (*http).backup.postsize; + (*data).state.fread_func = (*http).backup.fread_func; + (*data).state.in_0 = (*http).backup.fread_in; - (*http).backup.postsize = 0 as curl_off_t; - } else { - (*http).postsize = 0 as curl_off_t; - } + (*http).sending += 1; /* move one step up */ - return fullsize; - } + (*http).backup.postsize = 0 as curl_off_t; + } else { + (*http).postsize = 0 as curl_off_t; + } - memcpy( - buffer as *mut libc::c_void, - (*http).postdata as *const libc::c_void, - fullsize, - ); + return fullsize; + } + + memcpy( + buffer as *mut libc::c_void, + (*http).postdata as *const libc::c_void, + fullsize, + ); - (*http).postdata = (*http).postdata.offset(fullsize as isize); - (*http).postsize = ((*http).postsize as u64).wrapping_sub(fullsize) as curl_off_t as curl_off_t; + (*http).postdata = (*http).postdata.offset(fullsize as isize); + (*http).postsize = + ((*http).postsize as u64).wrapping_sub(fullsize) as curl_off_t as curl_off_t; } return fullsize; } @@ -1677,16 +1719,16 @@ pub extern "C" fn Curl_buffer_send( let mut result: CURLcode = CURLE_OK; let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; let mut size: size_t = 0; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut http: *mut HTTP =unsafe{ (*data).req.p.http}; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut http: *mut HTTP = unsafe { (*data).req.p.http }; let mut sendsize: size_t = 0; let mut sockfd: curl_socket_t = 0; let mut headersize: size_t = 0; - unsafe{ - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if socketindex <= 1 { - } else { - __assert_fail( + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if socketindex <= 1 { + } else { + __assert_fail( b"socketindex <= 1\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 1240 as u32, @@ -1698,23 +1740,24 @@ pub extern "C" fn Curl_buffer_send( )) .as_ptr(), ); - }} + } + } - sockfd =unsafe{ (*conn).sock[socketindex as usize]}; + sockfd = unsafe { (*conn).sock[socketindex as usize] }; /* The looping below is required since we use non-blocking sockets, but due to the circumstances we will just loop and try again and again etc */ - ptr =unsafe{ Curl_dyn_ptr(in_0)}; - size =unsafe{ Curl_dyn_len(in_0)}; + ptr = unsafe { Curl_dyn_ptr(in_0) }; + size = unsafe { Curl_dyn_len(in_0) }; headersize = size.wrapping_sub(included_body_bytes as size_t); /* the initial part that isn't body is header */ - unsafe{ - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if size > included_body_bytes as size_t { - } else { - __assert_fail( + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if size > included_body_bytes as size_t { + } else { + __assert_fail( b"size > (size_t)included_body_bytes\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 1253 as u32, @@ -1726,34 +1769,41 @@ pub extern "C" fn Curl_buffer_send( )) .as_ptr(), ); - }} + } + } result = CURLE_OK; /* Curl_convert_to_network calls failf if unsuccessful */ if result as u64 != 0 { /* conversion failed, free memory and return to the caller */ - unsafe{Curl_dyn_free(in_0);} + unsafe { + Curl_dyn_free(in_0); + } return result; } #[cfg(not(CURL_DISABLE_PROXY))] - let flag: bool =unsafe{ ((*(*conn).handler).flags & PROTOPT_SSL != 0 - || (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32) - && (*conn).httpversion as i32 != 20}; + let flag: bool = unsafe { + ((*(*conn).handler).flags & PROTOPT_SSL != 0 + || (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32) + && (*conn).httpversion as i32 != 20 + }; #[cfg(CURL_DISABLE_PROXY)] - let flag: bool =unsafe{ (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 - && (*conn).httpversion as i32 != 20}; + let flag: bool = unsafe { + (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 + && (*conn).httpversion as i32 != 20 + }; /* Make sure this doesn't send more body bytes than what the max send speed says. The request bytes do not count to the max speed. */ - unsafe{ - if flag { - if (*data).set.max_send_speed != 0 && included_body_bytes > (*data).set.max_send_speed { - let mut overflow: curl_off_t = included_body_bytes - (*data).set.max_send_speed; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (overflow as size_t) < size { - } else { - __assert_fail( + unsafe { + if flag { + if (*data).set.max_send_speed != 0 && included_body_bytes > (*data).set.max_send_speed { + let mut overflow: curl_off_t = included_body_bytes - (*data).set.max_send_speed; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (overflow as size_t) < size { + } else { + __assert_fail( b"(size_t)overflow < size\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 1275 as u32, @@ -1765,61 +1815,62 @@ pub extern "C" fn Curl_buffer_send( )) .as_ptr(), ); + } + sendsize = size.wrapping_sub(overflow as size_t); + } else { + sendsize = size; } - sendsize = size.wrapping_sub(overflow as size_t); - } else { - sendsize = size; - } - - /* OpenSSL is very picky and we must send the SAME buffer pointer to the - library when we attempt to re-send this buffer. Sending the same data - is not enough, we must use the exact same address. For this reason, we - must copy the data to the uploadbuffer first, since that is the buffer - we will be using if this send is retried later. - */ - result = Curl_get_upload_buffer(data); - if result as u64 != 0 { - /* malloc failed, free memory and return to the caller */ - Curl_dyn_free(in_0); - return result; - } - /* We never send more than upload_buffer_size bytes in one single chunk - when we speak HTTPS, as if only a fraction of it is sent now, this data - needs to fit into the normal read-callback buffer later on and that - buffer is using this size. - */ - if sendsize > (*data).set.upload_buffer_size as size_t { - sendsize = (*data).set.upload_buffer_size as size_t; - } - memcpy( - (*data).state.ulbuf as *mut libc::c_void, - ptr as *const libc::c_void, - sendsize, - ); - ptr = (*data).state.ulbuf; - } else { - #[cfg(CURLDEBUG)] - { - /* Allow debug builds to override this logic to force short initial - sends + /* OpenSSL is very picky and we must send the SAME buffer pointer to the + library when we attempt to re-send this buffer. Sending the same data + is not enough, we must use the exact same address. For this reason, we + must copy the data to the uploadbuffer first, since that is the buffer + we will be using if this send is retried later. */ - let mut p: *mut libc::c_char = - getenv(b"CURL_SMALLREQSEND\0" as *const u8 as *const libc::c_char); - if !p.is_null() { - let mut altsize: size_t = strtoul(p, 0 as *mut *mut libc::c_char, 10); - if altsize != 0 { - sendsize = if size < altsize { size } else { altsize }; - } else { - sendsize = size; - } - } else if (*data).set.max_send_speed != 0 - && included_body_bytes > (*data).set.max_send_speed + result = Curl_get_upload_buffer(data); + if result as u64 != 0 { + /* malloc failed, free memory and return to the caller */ + Curl_dyn_free(in_0); + return result; + } + /* We never send more than upload_buffer_size bytes in one single chunk + when we speak HTTPS, as if only a fraction of it is sent now, this data + needs to fit into the normal read-callback buffer later on and that + buffer is using this size. + */ + if sendsize > (*data).set.upload_buffer_size as size_t { + sendsize = (*data).set.upload_buffer_size as size_t; + } + + memcpy( + (*data).state.ulbuf as *mut libc::c_void, + ptr as *const libc::c_void, + sendsize, + ); + ptr = (*data).state.ulbuf; + } else { + #[cfg(CURLDEBUG)] { - let mut overflow_0: curl_off_t = included_body_bytes - (*data).set.max_send_speed; - if (overflow_0 as size_t) < size { - } else { - __assert_fail( + /* Allow debug builds to override this logic to force short initial + sends + */ + let mut p: *mut libc::c_char = + getenv(b"CURL_SMALLREQSEND\0" as *const u8 as *const libc::c_char); + if !p.is_null() { + let mut altsize: size_t = strtoul(p, 0 as *mut *mut libc::c_char, 10); + if altsize != 0 { + sendsize = if size < altsize { size } else { altsize }; + } else { + sendsize = size; + } + } else if (*data).set.max_send_speed != 0 + && included_body_bytes > (*data).set.max_send_speed + { + let mut overflow_0: curl_off_t = + included_body_bytes - (*data).set.max_send_speed; + if (overflow_0 as size_t) < size { + } else { + __assert_fail( b"(size_t)overflow < size\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 1326 as u32, @@ -1831,137 +1882,145 @@ pub extern "C" fn Curl_buffer_send( )) .as_ptr(), ); + } + sendsize = size.wrapping_sub(overflow_0 as size_t); + } else { + sendsize = size; } - sendsize = size.wrapping_sub(overflow_0 as size_t); - } else { - sendsize = size; } - } - #[cfg(not(CURLDEBUG))] - { - /* Make sure this doesn't send more body bytes than what the max send - speed says. The request bytes do not count to the max speed. - */ - if (*data).set.max_send_speed != 0 && included_body_bytes > (*data).set.max_send_speed { - let mut overflow_0: curl_off_t = included_body_bytes - (*data).set.max_send_speed; - sendsize = size.wrapping_sub(overflow_0 as size_t); - } else { - sendsize = size; + #[cfg(not(CURLDEBUG))] + { + /* Make sure this doesn't send more body bytes than what the max send + speed says. The request bytes do not count to the max speed. + */ + if (*data).set.max_send_speed != 0 + && included_body_bytes > (*data).set.max_send_speed + { + let mut overflow_0: curl_off_t = + included_body_bytes - (*data).set.max_send_speed; + sendsize = size.wrapping_sub(overflow_0 as size_t); + } else { + sendsize = size; + } } } } - } - result = unsafe{Curl_write( - data, - sockfd, - ptr as *const libc::c_void, - sendsize, - &mut amount, - )}; + result = unsafe { + Curl_write( + data, + sockfd, + ptr as *const libc::c_void, + sendsize, + &mut amount, + ) + }; if result as u64 == 0 { - unsafe{ - /* - * Note that we may not send the entire chunk at once, and we have a set - * number of data bytes at the end of the big buffer (out of which we may - * only send away a part). - */ - /* how much of the header that was sent */ - let mut headlen: size_t = if amount as size_t > headersize { - headersize - } else { - amount as size_t - }; + unsafe { + /* + * Note that we may not send the entire chunk at once, and we have a set + * number of data bytes at the end of the big buffer (out of which we may + * only send away a part). + */ + /* how much of the header that was sent */ + let mut headlen: size_t = if amount as size_t > headersize { + headersize + } else { + amount as size_t + }; - /* this data _may_ contain binary stuff */ - let mut bodylen: size_t = (amount as u64).wrapping_sub(headlen); - Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen); - if bodylen != 0 { - /* there was body data sent beyond the initial header part, pass that on - to the debug callback too */ - Curl_debug( - data, - CURLINFO_DATA_OUT, - ptr.offset(headlen as isize), - bodylen, - ); - } + /* this data _may_ contain binary stuff */ + let mut bodylen: size_t = (amount as u64).wrapping_sub(headlen); + Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen); + if bodylen != 0 { + /* there was body data sent beyond the initial header part, pass that on + to the debug callback too */ + Curl_debug( + data, + CURLINFO_DATA_OUT, + ptr.offset(headlen as isize), + bodylen, + ); + } - /* 'amount' can never be a very large value here so typecasting it so a - signed 31 bit value should not cause problems even if ssize_t is - 64bit */ - *bytes_written += amount; + /* 'amount' can never be a very large value here so typecasting it so a + signed 31 bit value should not cause problems even if ssize_t is + 64bit */ + *bytes_written += amount; - if !http.is_null() { - /* if we sent a piece of the body here, up the byte counter for it - accordingly */ - (*data).req.writebytecount = ((*data).req.writebytecount as u64).wrapping_add(bodylen) - as curl_off_t as curl_off_t; - Curl_pgrsSetUploadCounter(data, (*data).req.writebytecount); + if !http.is_null() { + /* if we sent a piece of the body here, up the byte counter for it + accordingly */ + (*data).req.writebytecount = ((*data).req.writebytecount as u64) + .wrapping_add(bodylen) + as curl_off_t as curl_off_t; + Curl_pgrsSetUploadCounter(data, (*data).req.writebytecount); - if amount as size_t != size { - /* The whole request could not be sent in one system call. We must - queue it up and send it later when we get the chance. We must not - loop here and wait until it might work again. */ - - size = (size as u64).wrapping_sub(amount as u64) as size_t as size_t; - - ptr = (Curl_dyn_ptr(in_0)).offset(amount as isize); - - /* backup the currently set pointers */ - (*http).backup.fread_func = (*data).state.fread_func; - (*http).backup.fread_in = (*data).state.in_0; - (*http).backup.postdata = (*http).postdata; - (*http).backup.postsize = (*http).postsize; - - /* set the new pointers for the request-sending */ - (*data).state.fread_func = ::std::mem::transmute::< - Option< - unsafe extern "C" fn( - *mut libc::c_char, - size_t, - size_t, - *mut libc::c_void, - ) -> size_t, - >, - curl_read_callback, - >(Some( - readmoredata - as unsafe extern "C" fn( - *mut libc::c_char, - size_t, - size_t, - *mut libc::c_void, - ) -> size_t, - )); - (*data).state.in_0 = data as *mut libc::c_void; - (*http).postdata = ptr; - (*http).postsize = size as curl_off_t; - - /* this much data is remaining header: */ - (*data).req.pendingheader = headersize.wrapping_sub(headlen) as curl_off_t; - (*http).send_buffer = *in_0; /* copy the whole struct */ - (*http).sending = HTTPSEND_REQUEST; + if amount as size_t != size { + /* The whole request could not be sent in one system call. We must + queue it up and send it later when we get the chance. We must not + loop here and wait until it might work again. */ - return CURLE_OK; + size = (size as u64).wrapping_sub(amount as u64) as size_t as size_t; + + ptr = (Curl_dyn_ptr(in_0)).offset(amount as isize); + + /* backup the currently set pointers */ + (*http).backup.fread_func = (*data).state.fread_func; + (*http).backup.fread_in = (*data).state.in_0; + (*http).backup.postdata = (*http).postdata; + (*http).backup.postsize = (*http).postsize; + + /* set the new pointers for the request-sending */ + (*data).state.fread_func = ::std::mem::transmute::< + Option< + unsafe extern "C" fn( + *mut libc::c_char, + size_t, + size_t, + *mut libc::c_void, + ) -> size_t, + >, + curl_read_callback, + >(Some( + readmoredata + as unsafe extern "C" fn( + *mut libc::c_char, + size_t, + size_t, + *mut libc::c_void, + ) -> size_t, + )); + (*data).state.in_0 = data as *mut libc::c_void; + (*http).postdata = ptr; + (*http).postsize = size as curl_off_t; + + /* this much data is remaining header: */ + (*data).req.pendingheader = headersize.wrapping_sub(headlen) as curl_off_t; + (*http).send_buffer = *in_0; /* copy the whole struct */ + (*http).sending = HTTPSEND_REQUEST; + + return CURLE_OK; + } + (*http).sending = HTTPSEND_BODY; + } else if amount as size_t != size { + /* We have no continue-send mechanism now, fail. This can only happen + when this function is used from the CONNECT sending function. We + currently (stupidly) assume that the whole request is always sent + away in the first single chunk. + + This needs FIXing. + */ + return CURLE_SEND_ERROR; } - (*http).sending = HTTPSEND_BODY; - } else if amount as size_t != size { - /* We have no continue-send mechanism now, fail. This can only happen - when this function is used from the CONNECT sending function. We - currently (stupidly) assume that the whole request is always sent - away in the first single chunk. - - This needs FIXing. - */ - return CURLE_SEND_ERROR; } } -} -unsafe{Curl_dyn_free(in_0); + unsafe { + Curl_dyn_free(in_0); - /* no remaining header data */ - (*data).req.pendingheader = 0 as curl_off_t;} + /* no remaining header data */ + (*data).req.pendingheader = 0 as curl_off_t; + } return result; } @@ -1974,8 +2033,9 @@ pub extern "C" fn Curl_buffer_send( mut included_body_bytes: curl_off_t, mut socketindex: i32, ) -> CURLcode { - unsafe{ - return CURLE_OK;} + unsafe { + return CURLE_OK; + } } /* @@ -1995,48 +2055,48 @@ pub extern "C" fn Curl_compareheader( * The field value MAY be preceded by any amount of LWS, though a single SP * is preferred." */ - let mut hlen: size_t = unsafe{strlen(header)}; + let mut hlen: size_t = unsafe { strlen(header) }; let mut clen: size_t = 0; let mut len: size_t = 0; let mut start: *const libc::c_char = 0 as *const libc::c_char; let mut end: *const libc::c_char = 0 as *const libc::c_char; - if unsafe{Curl_strncasecompare(headerline, header, hlen) == 0} { + if unsafe { Curl_strncasecompare(headerline, header, hlen) == 0 } { return false; /* doesn't start with header */ } /* pass the header */ - start =unsafe{ &*headerline.offset(hlen as isize) as *const libc::c_char}; + start = unsafe { &*headerline.offset(hlen as isize) as *const libc::c_char }; /* pass all whitespace */ - while unsafe{*start as i32 != 0 && Curl_isspace(*start as u8 as i32) != 0} { - start = unsafe{start.offset(1)}; + while unsafe { *start as i32 != 0 && Curl_isspace(*start as u8 as i32) != 0 } { + start = unsafe { start.offset(1) }; } /* find the end of the header line */ - end = unsafe{strchr(start, '\r' as i32)}; /* lines end with CRLF */ + end = unsafe { strchr(start, '\r' as i32) }; /* lines end with CRLF */ if end.is_null() { /* in case there's a non-standard compliant line here */ - end =unsafe{ strchr(start, '\n' as i32)}; + end = unsafe { strchr(start, '\n' as i32) }; if end.is_null() { /* hm, there's no line ending here, use the zero byte! */ - end = unsafe{strchr(start, '\0' as i32)}; + end = unsafe { strchr(start, '\0' as i32) }; } } - len = unsafe{end.offset_from(start) as i64 as size_t}; /* length of the content part of the input line */ - clen = unsafe{strlen(content)}; /* length of the word to find */ + len = unsafe { end.offset_from(start) as i64 as size_t }; /* length of the content part of the input line */ + clen = unsafe { strlen(content) }; /* length of the word to find */ /* find the content string in the rest of the line */ while len >= clen { - unsafe{ - if Curl_strncasecompare(start, content, clen) != 0 { - return true; /* match! */ + unsafe { + if Curl_strncasecompare(start, content, clen) != 0 { + return true; /* match! */ + } + len = len.wrapping_sub(1); + start = start.offset(1); } - len = len.wrapping_sub(1); - start = start.offset(1); - } } return false; /* no match */ } @@ -2046,68 +2106,70 @@ pub extern "C" fn Curl_compareheader( * the generic Curl_connect(). */ #[no_mangle] -pub extern "C" fn Curl_http_connect( - mut data: *mut Curl_easy, - mut done: *mut bool, -) -> CURLcode { +pub extern "C" fn Curl_http_connect(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - + let mut conn: *mut connectdata = unsafe { (*data).conn }; /* We default to persistent connections. We set this already in this connect function to make the re-use checks properly be able to check this bit. */ #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - unsafe{Curl_conncontrol(conn, FIRSTSOCKET);} + unsafe { + Curl_conncontrol(conn, FIRSTSOCKET); + } #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - unsafe{Curl_conncontrol( - conn, - FIRSTSOCKET, - b"HTTP default\0" as *const u8 as *const libc::c_char, - );} - unsafe{ - match () { - #[cfg(not(CURL_DISABLE_PROXY))] - _ => { - /* the CONNECT procedure might not have been completed */ - result = Curl_proxy_connect(data, 0 as i32); - if result as u64 != 0 { - return result; - } - - if ((*conn).bits).proxy_connect_closed() != 0 { - /* this is not an error, just part of the connection negotiation */ - return CURLE_OK; - } - - if (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as i32 as u32 - && !(*conn).bits.proxy_ssl_connected[0 as i32 as usize] - { - return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */ - } - if Curl_connect_ongoing(conn) { - /* nothing else to do except wait right now - we're not done here. */ - return CURLE_OK; - } - if ((*data).set).haproxyprotocol() != 0 { - /* add HAProxy PROXY protocol header */ - result = add_haproxy_protocol_header(data); + unsafe { + Curl_conncontrol( + conn, + FIRSTSOCKET, + b"HTTP default\0" as *const u8 as *const libc::c_char, + ); + } + unsafe { + match () { + #[cfg(not(CURL_DISABLE_PROXY))] + _ => { + /* the CONNECT procedure might not have been completed */ + result = Curl_proxy_connect(data, 0 as i32); if result as u64 != 0 { return result; } + + if ((*conn).bits).proxy_connect_closed() != 0 { + /* this is not an error, just part of the connection negotiation */ + return CURLE_OK; + } + + if (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as i32 as u32 + && !(*conn).bits.proxy_ssl_connected[0 as i32 as usize] + { + return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */ + } + if Curl_connect_ongoing(conn) { + /* nothing else to do except wait right now - we're not done here. */ + return CURLE_OK; + } + if ((*data).set).haproxyprotocol() != 0 { + /* add HAProxy PROXY protocol header */ + result = add_haproxy_protocol_header(data); + if result as u64 != 0 { + return result; + } + } } + #[cfg(CURL_DISABLE_PROXY)] + _ => {} } - #[cfg(CURL_DISABLE_PROXY)] - _ => {} } -} - if unsafe{(*(*conn).given).protocol & CURLPROTO_HTTPS != 0} { + if unsafe { (*(*conn).given).protocol & CURLPROTO_HTTPS != 0 } { /* perform SSL initialization */ - result = unsafe{https_connecting(data, done)}; + result = unsafe { https_connecting(data, done) }; if result as u64 != 0 { return result; } } else { - unsafe{ *done = true;} + unsafe { + *done = true; + } } return CURLE_OK; } @@ -2121,8 +2183,9 @@ extern "C" fn http_getsock_do( mut socks: *mut curl_socket_t, ) -> i32 { /* write mode */ - unsafe{ - *socks.offset(0 as isize) = (*conn).sock[FIRSTSOCKET as usize];} + unsafe { + *socks.offset(0 as isize) = (*conn).sock[FIRSTSOCKET as usize]; + } return GETSOCK_WRITESOCK(0); } @@ -2140,57 +2203,63 @@ extern "C" fn add_haproxy_protocol_header(mut data: *mut Curl_easy) -> CURLcode let mut tcp_version: *const libc::c_char = 0 as *const libc::c_char; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - unsafe{if !((*data).conn).is_null() { - } else { - __assert_fail( - b"data->conn\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 1546 as u32, - (*::std::mem::transmute::<&[u8; 57], &[libc::c_char; 57]>( - b"CURLcode add_haproxy_protocol_header(struct Curl_easy *)\0", - )) - .as_ptr(), - ); - }} - unsafe{ Curl_dyn_init(&mut req, 2048 as size_t);} + unsafe { + if !((*data).conn).is_null() { + } else { + __assert_fail( + b"data->conn\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 1546 as u32, + (*::std::mem::transmute::<&[u8; 57], &[libc::c_char; 57]>( + b"CURLcode add_haproxy_protocol_header(struct Curl_easy *)\0", + )) + .as_ptr(), + ); + } + } + unsafe { + Curl_dyn_init(&mut req, 2048 as size_t); + } #[cfg(USE_UNIX_SOCKETS)] - let flag: bool =unsafe{ !((*(*data).conn).unix_domain_socket).is_null()}; + let flag: bool = unsafe { !((*(*data).conn).unix_domain_socket).is_null() }; #[cfg(not(USE_UNIX_SOCKETS))] let flag: bool = false; - unsafe{ - if flag { - /* the buffer is large enough to hold this! */ - result = Curl_dyn_add( - &mut req, - b"PROXY UNKNOWN\r\n\0" as *const u8 as *const libc::c_char, - ); - } else { - /* Emit the correct prefix for IPv6 */ - tcp_version = if ((*(*data).conn).bits).ipv6() as i32 != 0 { - b"TCP6\0" as *const u8 as *const libc::c_char + unsafe { + if flag { + /* the buffer is large enough to hold this! */ + result = Curl_dyn_add( + &mut req, + b"PROXY UNKNOWN\r\n\0" as *const u8 as *const libc::c_char, + ); } else { - b"TCP4\0" as *const u8 as *const libc::c_char - }; - result = Curl_dyn_addf( - &mut req as *mut dynbuf, - b"PROXY %s %s %s %i %i\r\n\0" as *const u8 as *const libc::c_char, - tcp_version, - ((*data).info.conn_local_ip).as_mut_ptr(), - ((*data).info.conn_primary_ip).as_mut_ptr(), - (*data).info.conn_local_port, - (*data).info.conn_primary_port, - ); - }} + /* Emit the correct prefix for IPv6 */ + tcp_version = if ((*(*data).conn).bits).ipv6() as i32 != 0 { + b"TCP6\0" as *const u8 as *const libc::c_char + } else { + b"TCP4\0" as *const u8 as *const libc::c_char + }; + result = Curl_dyn_addf( + &mut req as *mut dynbuf, + b"PROXY %s %s %s %i %i\r\n\0" as *const u8 as *const libc::c_char, + tcp_version, + ((*data).info.conn_local_ip).as_mut_ptr(), + ((*data).info.conn_primary_ip).as_mut_ptr(), + (*data).info.conn_local_port, + (*data).info.conn_primary_port, + ); + } + } if result as u64 == 0 { - unsafe{ - result = Curl_buffer_send( - &mut req, - data, - &mut (*data).info.request_size, - 0 as curl_off_t, - FIRSTSOCKET, - );} + unsafe { + result = Curl_buffer_send( + &mut req, + data, + &mut (*data).info.request_size, + 0 as curl_off_t, + FIRSTSOCKET, + ); + } } return result; } @@ -2198,41 +2267,48 @@ extern "C" fn add_haproxy_protocol_header(mut data: *mut Curl_easy) -> CURLcode #[cfg(USE_SSL)] extern "C" fn https_connecting(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut conn: *mut connectdata = unsafe { (*data).conn }; #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - unsafe{if !data.is_null() && (*(*(*data).conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 { - } else { - __assert_fail( - b"(data) && (data->conn->handler->flags & (1<<0))\0" as *const u8 - as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 1581 as u32, - (*::std::mem::transmute::<&[u8; 55], &[libc::c_char; 55]>( - b"CURLcode https_connecting(struct Curl_easy *, _Bool *)\0", - )) - .as_ptr(), - ); - }} + unsafe { + if !data.is_null() + && (*(*(*data).conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 + { + } else { + __assert_fail( + b"(data) && (data->conn->handler->flags & (1<<0))\0" as *const u8 + as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 1581 as u32, + (*::std::mem::transmute::<&[u8; 55], &[libc::c_char; 55]>( + b"CURLcode https_connecting(struct Curl_easy *, _Bool *)\0", + )) + .as_ptr(), + ); + } + } #[cfg(ENABLE_QUIC)] - unsafe{if (*conn).transport as u32 == TRNSPRT_QUIC as i32 as u32 { - *done = true; - return CURLE_OK; - }} - unsafe{ - /* perform SSL initialization for this socket */ - result = Curl_ssl_connect_nonblocking(data, conn, false, 0, done); - if result as u64 != 0 { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 1); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 1, - b"Failed HTTPS connection\0" as *const u8 as *const libc::c_char, - ); + unsafe { + if (*conn).transport as u32 == TRNSPRT_QUIC as i32 as u32 { + *done = true; + return CURLE_OK; + } + } + unsafe { + /* perform SSL initialization for this socket */ + result = Curl_ssl_connect_nonblocking(data, conn, false, 0, done); + if result as u64 != 0 { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 1); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 1, + b"Failed HTTPS connection\0" as *const u8 as *const libc::c_char, + ); + } + return result; } - return result;} } #[cfg(not(USE_SSL))] @@ -2246,11 +2322,12 @@ extern "C" fn https_getsock( mut conn: *mut connectdata, mut socks: *mut curl_socket_t, ) -> i32 { - unsafe{ - if (*(*conn).handler).flags & PROTOPT_SSL != 0 { - return ((*Curl_ssl).getsock).expect("non-null function pointer")(conn, socks); + unsafe { + if (*(*conn).handler).flags & PROTOPT_SSL != 0 { + return ((*Curl_ssl).getsock).expect("non-null function pointer")(conn, socks); + } + return 0; } - return 0;} } #[no_mangle] @@ -2259,65 +2336,66 @@ pub extern "C" fn Curl_http_done( mut status: CURLcode, mut premature: bool, ) -> CURLcode { - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut http: *mut HTTP =unsafe{ (*data).req.p.http}; - unsafe{ - /* Clear multipass flag. If authentication isn't done yet, then it will get - * a chance to be set back to true when we output the next auth header */ - (*data).state.authhost.set_multipass(0 as bit); - (*data).state.authproxy.set_multipass(0 as bit); + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut http: *mut HTTP = unsafe { (*data).req.p.http }; + unsafe { + /* Clear multipass flag. If authentication isn't done yet, then it will get + * a chance to be set back to true when we output the next auth header */ + (*data).state.authhost.set_multipass(0 as bit); + (*data).state.authproxy.set_multipass(0 as bit); - Curl_unencode_cleanup(data); + Curl_unencode_cleanup(data); - /* set the proper values (possibly modified on POST) */ - (*conn).seek_func = (*data).set.seek_func; /* restore */ - (*conn).seek_client = (*data).set.seek_client; /* restore */ + /* set the proper values (possibly modified on POST) */ + (*conn).seek_func = (*data).set.seek_func; /* restore */ + (*conn).seek_client = (*data).set.seek_client; /* restore */ - if http.is_null() { - return CURLE_OK; - } + if http.is_null() { + return CURLE_OK; + } - Curl_dyn_free(&mut (*http).send_buffer); - Curl_http2_done(data, premature); - #[cfg(any( - all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), - not(CURL_DISABLE_SMTP), - not(CURL_DISABLE_IMAP) - ))] - Curl_mime_cleanpart(&mut (*http).form); - Curl_dyn_reset(&mut (*data).state.headerb); - #[cfg(all(not(CURL_DISABLE_HTTP), USE_HYPER))] - Curl_hyper_done(data); - - if status as u64 != 0 { - return status; - } + Curl_dyn_free(&mut (*http).send_buffer); + Curl_http2_done(data, premature); + #[cfg(any( + all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), + not(CURL_DISABLE_SMTP), + not(CURL_DISABLE_IMAP) + ))] + Curl_mime_cleanpart(&mut (*http).form); + Curl_dyn_reset(&mut (*data).state.headerb); + #[cfg(all(not(CURL_DISABLE_HTTP), USE_HYPER))] + Curl_hyper_done(data); + + if status as u64 != 0 { + return status; + } - if !premature /* this check is pointless when DONE is called before the + if !premature /* this check is pointless when DONE is called before the entire operation is complete */ && ((*conn).bits).retry() == 0 && ((*data).set).connect_only() == 0 && (*data).req.bytecount + (*data).req.headerbytecount - (*data).req.deductheadercount <= 0 as i64 - { - /* If this connection isn't simply closed to be retried, AND nothing was - read from the HTTP server (that counts), this can't be right so we - return an error here */ - Curl_failf( - data, - b"Empty reply from server\0" as *const u8 as *const libc::c_char, - ); - /* Mark it as closed to avoid the "left intact" message */ - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 2); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 2, - b"Empty reply from server\0" as *const u8 as *const libc::c_char, - ); - return CURLE_GOT_NOTHING; - }} + { + /* If this connection isn't simply closed to be retried, AND nothing was + read from the HTTP server (that counts), this can't be right so we + return an error here */ + Curl_failf( + data, + b"Empty reply from server\0" as *const u8 as *const libc::c_char, + ); + /* Mark it as closed to avoid the "left intact" message */ + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 2); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 2, + b"Empty reply from server\0" as *const u8 as *const libc::c_char, + ); + return CURLE_GOT_NOTHING; + } + } return CURLE_OK; } @@ -2335,17 +2413,18 @@ pub extern "C" fn Curl_use_http_1_1plus( mut data: *const Curl_easy, mut conn: *const connectdata, ) -> bool { - unsafe{ - if (*data).state.httpversion as i32 == 10 || (*conn).httpversion as i32 == 10 { - return false; - } - if (*data).state.httpwant as i32 == CURL_HTTP_VERSION_1_0 as i32 - && (*conn).httpversion as i32 <= 10 - { - return false; + unsafe { + if (*data).state.httpversion as i32 == 10 || (*conn).httpversion as i32 == 10 { + return false; + } + if (*data).state.httpwant as i32 == CURL_HTTP_VERSION_1_0 as i32 + && (*conn).httpversion as i32 <= 10 + { + return false; + } + return (*data).state.httpwant as i32 == CURL_HTTP_VERSION_NONE as i32 + || (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_1_1 as i32; } - return (*data).state.httpwant as i32 == CURL_HTTP_VERSION_NONE as i32 - || (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_1_1 as i32;} } #[cfg(not(USE_HYPER))] @@ -2353,21 +2432,22 @@ extern "C" fn get_http_string( mut data: *const Curl_easy, mut conn: *const connectdata, ) -> *const libc::c_char { - unsafe{ - #[cfg(ENABLE_QUIC)] - if (*data).state.httpwant as i32 == CURL_HTTP_VERSION_3 as i32 - || (*conn).httpversion as i32 == 30 - { - return b"3\0" as *const u8 as *const libc::c_char; - } - #[cfg(USE_NGHTTP2)] - if !((*conn).proto.httpc.h2).is_null() { - return b"2\0" as *const u8 as *const libc::c_char; - } - if Curl_use_http_1_1plus(data, conn) { - return b"1.1\0" as *const u8 as *const libc::c_char; + unsafe { + #[cfg(ENABLE_QUIC)] + if (*data).state.httpwant as i32 == CURL_HTTP_VERSION_3 as i32 + || (*conn).httpversion as i32 == 30 + { + return b"3\0" as *const u8 as *const libc::c_char; + } + #[cfg(USE_NGHTTP2)] + if !((*conn).proto.httpc.h2).is_null() { + return b"2\0" as *const u8 as *const libc::c_char; + } + if Curl_use_http_1_1plus(data, conn) { + return b"1.1\0" as *const u8 as *const libc::c_char; + } + return b"1.0\0" as *const u8 as *const libc::c_char; } - return b"1.0\0" as *const u8 as *const libc::c_char;} } /* check and possibly add an Expect: header */ @@ -2377,34 +2457,35 @@ extern "C" fn expect100( mut req: *mut dynbuf, ) -> CURLcode { let mut result: CURLcode = CURLE_OK; - unsafe{ - (*data).state.set_expect100header(0 as bit); /* default to false unless it is set - to TRUE below */ - if ((*data).state).disableexpect() == 0 - && Curl_use_http_1_1plus(data, conn) as i32 != 0 - && ((*conn).httpversion as i32) < 20 - { - /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an - Expect: 100-continue to the headers which actually speeds up post - operations (as there is one packet coming back from the web server) */ - let mut ptr: *const libc::c_char = - Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char); - if !ptr.is_null() { - (*data).state.set_expect100header(Curl_compareheader( - ptr, - b"Expect:\0" as *const u8 as *const libc::c_char, - b"100-continue\0" as *const u8 as *const libc::c_char, - ) as bit); - } else { - result = Curl_dyn_add( - req, - b"Expect: 100-continue\r\n\0" as *const u8 as *const libc::c_char, - ); - if result as u64 == 0 { - (*data).state.set_expect100header(1 as bit); + unsafe { + (*data).state.set_expect100header(0 as bit); /* default to false unless it is set + to TRUE below */ + if ((*data).state).disableexpect() == 0 + && Curl_use_http_1_1plus(data, conn) as i32 != 0 + && ((*conn).httpversion as i32) < 20 + { + /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an + Expect: 100-continue to the headers which actually speeds up post + operations (as there is one packet coming back from the web server) */ + let mut ptr: *const libc::c_char = + Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char); + if !ptr.is_null() { + (*data).state.set_expect100header(Curl_compareheader( + ptr, + b"Expect:\0" as *const u8 as *const libc::c_char, + b"100-continue\0" as *const u8 as *const libc::c_char, + ) as bit); + } else { + result = Curl_dyn_add( + req, + b"Expect: 100-continue\r\n\0" as *const u8 as *const libc::c_char, + ); + if result as u64 == 0 { + (*data).state.set_expect100header(1 as bit); + } } } - }} + } return result; } @@ -2419,12 +2500,14 @@ pub extern "C" fn Curl_http_compile_trailers( let mut endofline_native: *const libc::c_char = 0 as *const libc::c_char; let mut endofline_network: *const libc::c_char = 0 as *const libc::c_char; // TODO 测试通过后,把注释删掉 - let flag: bool = unsafe{if cfg!(CURL_DO_LINEEND_CONV) { - ((*handle).state).prefer_ascii() as i32 != 0 || ((*handle).set).crlf() as i32 != 0 - } else { - ((*handle).set).crlf() as i32 != 0 - /* \n will become \r\n later on */ - }}; + let flag: bool = unsafe { + if cfg!(CURL_DO_LINEEND_CONV) { + ((*handle).state).prefer_ascii() as i32 != 0 || ((*handle).set).crlf() as i32 != 0 + } else { + ((*handle).set).crlf() as i32 != 0 + /* \n will become \r\n later on */ + } + }; if flag { endofline_native = b"\n\0" as *const u8 as *const libc::c_char; endofline_network = b"\n\0" as *const u8 as *const libc::c_char; @@ -2433,29 +2516,29 @@ pub extern "C" fn Curl_http_compile_trailers( endofline_network = b"\r\n\0" as *const u8 as *const libc::c_char; } while !trailers.is_null() { - unsafe{ - /* only add correctly formatted trailers */ - ptr = strchr((*trailers).data, ':' as i32); - if !ptr.is_null() && *ptr.offset(1 as isize) as i32 == ' ' as i32 { - result = Curl_dyn_add(b, (*trailers).data); - if result as u64 != 0 { - return result; - } - result = Curl_dyn_add(b, endofline_native); - if result as u64 != 0 { - return result; + unsafe { + /* only add correctly formatted trailers */ + ptr = strchr((*trailers).data, ':' as i32); + if !ptr.is_null() && *ptr.offset(1 as isize) as i32 == ' ' as i32 { + result = Curl_dyn_add(b, (*trailers).data); + if result as u64 != 0 { + return result; + } + result = Curl_dyn_add(b, endofline_native); + if result as u64 != 0 { + return result; + } + } else { + Curl_infof( + handle, + b"Malformatted trailing header ! Skipping trailer.\0" as *const u8 + as *const libc::c_char, + ); } - } else { - Curl_infof( - handle, - b"Malformatted trailing header ! Skipping trailer.\0" as *const u8 - as *const libc::c_char, - ); + trailers = (*trailers).next; } - trailers = (*trailers).next; } - } - result =unsafe{ Curl_dyn_add(b, endofline_network)}; + result = unsafe { Curl_dyn_add(b, endofline_network) }; return result; } @@ -2466,219 +2549,232 @@ pub extern "C" fn Curl_add_custom_headers( mut is_connect: bool, mut req: *mut dynbuf, ) -> CURLcode { - unsafe{ - let mut conn: *mut connectdata = (*data).conn; - let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; - let mut h: [*mut curl_slist; 2] = [0 as *mut curl_slist; 2]; - let mut headers: *mut curl_slist = 0 as *mut curl_slist; - let mut numlists: i32 = 1; - let mut i: i32 = 0; - let mut proxy: proxy_use = HEADER_SERVER; - if is_connect { - proxy = HEADER_CONNECT; - } else { - proxy = (if ((*conn).bits).httpproxy() as i32 != 0 && ((*conn).bits).tunnel_proxy() == 0 { - HEADER_PROXY as i32 + unsafe { + let mut conn: *mut connectdata = (*data).conn; + let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut h: [*mut curl_slist; 2] = [0 as *mut curl_slist; 2]; + let mut headers: *mut curl_slist = 0 as *mut curl_slist; + let mut numlists: i32 = 1; + let mut i: i32 = 0; + let mut proxy: proxy_use = HEADER_SERVER; + if is_connect { + proxy = HEADER_CONNECT; } else { - HEADER_SERVER as i32 - }) as proxy_use; - } - match proxy as u32 { - 0 => { - h[0 as usize] = (*data).set.headers; - } - 1 => { - h[0 as usize] = (*data).set.headers; - if ((*data).set).sep_headers() != 0 { - h[1 as usize] = (*data).set.proxyheaders; - numlists += 1; - } - } - 2 => { - if ((*data).set).sep_headers() != 0 { - h[0 as usize] = (*data).set.proxyheaders; + proxy = (if ((*conn).bits).httpproxy() as i32 != 0 && ((*conn).bits).tunnel_proxy() == 0 + { + HEADER_PROXY as i32 } else { + HEADER_SERVER as i32 + }) as proxy_use; + } + match proxy as u32 { + 0 => { + h[0 as usize] = (*data).set.headers; + } + 1 => { h[0 as usize] = (*data).set.headers; + if ((*data).set).sep_headers() != 0 { + h[1 as usize] = (*data).set.proxyheaders; + numlists += 1; + } + } + 2 => { + if ((*data).set).sep_headers() != 0 { + h[0 as usize] = (*data).set.proxyheaders; + } else { + h[0 as usize] = (*data).set.headers; + } } + _ => {} } - _ => {} - } - i = 0; - while i < numlists { - headers = h[i as usize]; - while !headers.is_null() { - let mut semicolonp: *mut libc::c_char = 0 as *mut libc::c_char; - ptr = strchr((*headers).data, ':' as i32); - if ptr.is_null() { - let mut optr: *mut libc::c_char = 0 as *mut libc::c_char; - ptr = strchr((*headers).data, ';' as i32); - if !ptr.is_null() { - optr = ptr; - ptr = ptr.offset(1); - while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + i = 0; + while i < numlists { + headers = h[i as usize]; + while !headers.is_null() { + let mut semicolonp: *mut libc::c_char = 0 as *mut libc::c_char; + ptr = strchr((*headers).data, ':' as i32); + if ptr.is_null() { + let mut optr: *mut libc::c_char = 0 as *mut libc::c_char; + ptr = strchr((*headers).data, ';' as i32); + if !ptr.is_null() { + optr = ptr; ptr = ptr.offset(1); - } - if *ptr != 0 { - optr = 0 as *mut libc::c_char; - } else { - ptr = ptr.offset(-1); - if *ptr as i32 == ';' as i32 { - match () { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - _ => { - semicolonp = Curl_cstrdup.expect("non-null function pointer")( - (*headers).data, - ); + while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + ptr = ptr.offset(1); + } + if *ptr != 0 { + optr = 0 as *mut libc::c_char; + } else { + ptr = ptr.offset(-1); + if *ptr as i32 == ';' as i32 { + match () { + #[cfg(not(all( + DEBUGBUILD, + not(CURL_DISABLE_VERBOSE_STRINGS) + )))] + _ => { + semicolonp = Curl_cstrdup + .expect("non-null function pointer")( + (*headers).data + ); + } + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + _ => { + semicolonp = curl_dbg_strdup( + (*headers).data, + 1857 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + } } - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - _ => { - semicolonp = curl_dbg_strdup( - (*headers).data, - 1857 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); + if semicolonp.is_null() { + Curl_dyn_free(req); + return CURLE_OUT_OF_MEMORY; } + *semicolonp + .offset(ptr.offset_from((*headers).data) as i64 as isize) = + ':' as i32 as libc::c_char; + optr = &mut *semicolonp + .offset(ptr.offset_from((*headers).data) as i64 as isize) + as *mut libc::c_char; } - if semicolonp.is_null() { - Curl_dyn_free(req); - return CURLE_OUT_OF_MEMORY; - } - *semicolonp.offset(ptr.offset_from((*headers).data) as i64 as isize) = - ':' as i32 as libc::c_char; - optr = &mut *semicolonp - .offset(ptr.offset_from((*headers).data) as i64 as isize) - as *mut libc::c_char; } + ptr = optr; } - ptr = optr; } - } - if !ptr.is_null() { - ptr = ptr.offset(1); - while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + if !ptr.is_null() { ptr = ptr.offset(1); - } - if *ptr as i32 != 0 || !semicolonp.is_null() { - let mut result: CURLcode = CURLE_OK; - let mut compare: *mut libc::c_char = if !semicolonp.is_null() { - semicolonp - } else { - (*headers).data - }; - if !(!((*data).state.aptr.host).is_null() - && curl_strnequal( - b"Host:\0" as *const u8 as *const libc::c_char, - compare, - strlen(b"Host:\0" as *const u8 as *const libc::c_char), - ) != 0) - { - if !((*data).state.httpreq as u32 == HTTPREQ_POST_FORM as i32 as u32 + while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + ptr = ptr.offset(1); + } + if *ptr as i32 != 0 || !semicolonp.is_null() { + let mut result: CURLcode = CURLE_OK; + let mut compare: *mut libc::c_char = if !semicolonp.is_null() { + semicolonp + } else { + (*headers).data + }; + if !(!((*data).state.aptr.host).is_null() && curl_strnequal( - b"Content-Type:\0" as *const u8 as *const libc::c_char, + b"Host:\0" as *const u8 as *const libc::c_char, compare, - strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), + strlen(b"Host:\0" as *const u8 as *const libc::c_char), ) != 0) { - if !((*data).state.httpreq as u32 == HTTPREQ_POST_MIME as i32 as u32 + if !((*data).state.httpreq as u32 == HTTPREQ_POST_FORM as i32 as u32 && curl_strnequal( b"Content-Type:\0" as *const u8 as *const libc::c_char, compare, strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), ) != 0) { - if !(((*conn).bits).authneg() as i32 != 0 + if !((*data).state.httpreq as u32 + == HTTPREQ_POST_MIME as i32 as u32 && curl_strnequal( - b"Content-Length:\0" as *const u8 as *const libc::c_char, + b"Content-Type:\0" as *const u8 as *const libc::c_char, compare, strlen( - b"Content-Length:\0" as *const u8 - as *const libc::c_char, + b"Content-Type:\0" as *const u8 as *const libc::c_char, ), ) != 0) { - if !(!((*data).state.aptr.te).is_null() + if !(((*conn).bits).authneg() as i32 != 0 && curl_strnequal( - b"Connection:\0" as *const u8 as *const libc::c_char, + b"Content-Length:\0" as *const u8 + as *const libc::c_char, compare, strlen( - b"Connection:\0" as *const u8 + b"Content-Length:\0" as *const u8 as *const libc::c_char, ), ) != 0) { - if !((*conn).httpversion as i32 >= 20 as i32 + if !(!((*data).state.aptr.te).is_null() && curl_strnequal( - b"Transfer-Encoding:\0" as *const u8 + b"Connection:\0" as *const u8 as *const libc::c_char, compare, strlen( - b"Transfer-Encoding:\0" as *const u8 + b"Connection:\0" as *const u8 as *const libc::c_char, ), ) != 0) { - if !((curl_strnequal( - b"Authorization:\0" as *const u8 - as *const libc::c_char, - compare, - strlen( - b"Authorization:\0" as *const u8 - as *const libc::c_char, - ), - ) != 0 - || curl_strnequal( - b"Cookie:\0" as *const u8 + if !((*conn).httpversion as i32 >= 20 as i32 + && curl_strnequal( + b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, compare, strlen( - b"Cookie:\0" as *const u8 + b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, ), ) != 0) - && (((*data).state).this_is_a_follow() as i32 != 0 - && !((*data).state.first_host).is_null() - && ((*data).set).allow_auth_to_other_hosts() - == 0 - && Curl_strcasecompare( - (*data).state.first_host, - (*conn).host.name, - ) == 0)) { - result = Curl_hyper_header( - data, - req as *mut hyper_headers, + if !((curl_strnequal( + b"Authorization:\0" as *const u8 + as *const libc::c_char, compare, - ); + strlen( + b"Authorization:\0" as *const u8 + as *const libc::c_char, + ), + ) != 0 + || curl_strnequal( + b"Cookie:\0" as *const u8 + as *const libc::c_char, + compare, + strlen( + b"Cookie:\0" as *const u8 + as *const libc::c_char, + ), + ) != 0) + && (((*data).state).this_is_a_follow() as i32 + != 0 + && !((*data).state.first_host).is_null() + && ((*data).set) + .allow_auth_to_other_hosts() + == 0 + && Curl_strcasecompare( + (*data).state.first_host, + (*conn).host.name, + ) == 0)) + { + result = Curl_hyper_header( + data, + req as *mut hyper_headers, + compare, + ); + } } } } } } } - } - if !semicolonp.is_null() { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - semicolonp as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - semicolonp as *mut libc::c_void, - 1929 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - } - if result as u64 != 0 { - return result; + if !semicolonp.is_null() { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + semicolonp as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + semicolonp as *mut libc::c_void, + 1929 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + } + if result as u64 != 0 { + return result; + } } } + headers = (*headers).next; } - headers = (*headers).next; + i += 1; } - i += 1; + return CURLE_OK; } - return CURLE_OK; -} } const HEADER_SERVER: u32 = 0; /* direct to server */ @@ -2692,129 +2788,134 @@ pub extern "C" fn Curl_add_custom_headers( mut is_connect: bool, mut req: *mut dynbuf, ) -> CURLcode { - let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut conn: *mut connectdata = unsafe { (*data).conn }; let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; let mut h: [*mut curl_slist; 2] = [0 as *mut curl_slist; 2]; let mut headers: *mut curl_slist = 0 as *mut curl_slist; let mut numlists: i32 = 1; /* by default */ let mut i: i32 = 0; - unsafe{ - match () { - #[cfg(not(CURL_DISABLE_PROXY))] - _ => { - let mut proxy: proxy_use = HEADER_SERVER; - if is_connect { - proxy = HEADER_CONNECT; - } else { - proxy = (if ((*conn).bits).httpproxy() as i32 != 0 - && ((*conn).bits).tunnel_proxy() == 0 - { - HEADER_PROXY as i32 + unsafe { + match () { + #[cfg(not(CURL_DISABLE_PROXY))] + _ => { + let mut proxy: proxy_use = HEADER_SERVER; + if is_connect { + proxy = HEADER_CONNECT; } else { - HEADER_SERVER as i32 - }) as proxy_use; - } - match proxy as u32 { - HEADER_SERVER => { - h[0 as usize] = (*data).set.headers; + proxy = (if ((*conn).bits).httpproxy() as i32 != 0 + && ((*conn).bits).tunnel_proxy() == 0 + { + HEADER_PROXY as i32 + } else { + HEADER_SERVER as i32 + }) as proxy_use; } - HEADER_PROXY => { - h[0 as usize] = (*data).set.headers; - if ((*data).set).sep_headers() != 0 { - h[1 as usize] = (*data).set.proxyheaders; - numlists += 1; + match proxy as u32 { + HEADER_SERVER => { + h[0 as usize] = (*data).set.headers; } - } - HEADER_CONNECT => { - if ((*data).set).sep_headers() != 0 { - h[0 as usize] = (*data).set.proxyheaders; - } else { + HEADER_PROXY => { h[0 as usize] = (*data).set.headers; + if ((*data).set).sep_headers() != 0 { + h[1 as usize] = (*data).set.proxyheaders; + numlists += 1; + } } + HEADER_CONNECT => { + if ((*data).set).sep_headers() != 0 { + h[0 as usize] = (*data).set.proxyheaders; + } else { + h[0 as usize] = (*data).set.headers; + } + } + _ => {} } - _ => {} + } + #[cfg(CURL_DISABLE_PROXY)] + _ => { + h[0 as usize] = (*data).set.headers; } } - #[cfg(CURL_DISABLE_PROXY)] - _ => { - h[0 as usize] = (*data).set.headers; - } - } - /* loop through one or two lists */ - i = 0; - while i < numlists { - headers = h[i as usize]; - - while !headers.is_null() { - let mut semicolonp: *mut libc::c_char = 0 as *mut libc::c_char; - ptr = strchr((*headers).data, ':' as i32); - if ptr.is_null() { - let mut optr: *mut libc::c_char = 0 as *mut libc::c_char; - /* no colon, semicolon? */ - ptr = strchr((*headers).data, ';' as i32); - if !ptr.is_null() { - optr = ptr; - ptr = ptr.offset(1); /* pass the semicolon */ - while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { - ptr = ptr.offset(1); - } + /* loop through one or two lists */ + i = 0; + while i < numlists { + headers = h[i as usize]; + + while !headers.is_null() { + let mut semicolonp: *mut libc::c_char = 0 as *mut libc::c_char; + ptr = strchr((*headers).data, ':' as i32); + if ptr.is_null() { + let mut optr: *mut libc::c_char = 0 as *mut libc::c_char; + /* no colon, semicolon? */ + ptr = strchr((*headers).data, ';' as i32); + if !ptr.is_null() { + optr = ptr; + ptr = ptr.offset(1); /* pass the semicolon */ + while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + ptr = ptr.offset(1); + } - if *ptr != 0 { - optr = 0 as *mut libc::c_char; - } else { - ptr = ptr.offset(-1); - if *ptr as i32 == ';' as i32 { - /* this may be used for something else in the future */ - match () { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - _ => { - semicolonp = Curl_cstrdup.expect("non-null function pointer")( - (*headers).data, - ); + if *ptr != 0 { + optr = 0 as *mut libc::c_char; + } else { + ptr = ptr.offset(-1); + if *ptr as i32 == ';' as i32 { + /* this may be used for something else in the future */ + match () { + #[cfg(not(all( + DEBUGBUILD, + not(CURL_DISABLE_VERBOSE_STRINGS) + )))] + _ => { + semicolonp = Curl_cstrdup + .expect("non-null function pointer")( + (*headers).data + ); + } + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + _ => { + semicolonp = curl_dbg_strdup( + (*headers).data, + 1857, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + } } - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - _ => { - semicolonp = curl_dbg_strdup( - (*headers).data, - 1857, - b"http.c\0" as *const u8 as *const libc::c_char, - ); + if semicolonp.is_null() { + /* copy the source */ + #[cfg(not(USE_HYPER))] + Curl_dyn_free(req); + return CURLE_OUT_OF_MEMORY; } + /* put a colon where the semicolon is */ + *semicolonp + .offset(ptr.offset_from((*headers).data) as i64 as isize) = + ':' as i32 as libc::c_char; + /* point at the colon */ + optr = &mut *semicolonp + .offset(ptr.offset_from((*headers).data) as i64 as isize) + as *mut libc::c_char; } - if semicolonp.is_null() { - /* copy the source */ - #[cfg(not(USE_HYPER))] - Curl_dyn_free(req); - return CURLE_OUT_OF_MEMORY; - } - /* put a colon where the semicolon is */ - *semicolonp.offset(ptr.offset_from((*headers).data) as i64 as isize) = - ':' as i32 as libc::c_char; - /* point at the colon */ - optr = &mut *semicolonp - .offset(ptr.offset_from((*headers).data) as i64 as isize) - as *mut libc::c_char; } + ptr = optr; } - ptr = optr; } - } - if !ptr.is_null() { - /* we require a colon for this to be a true header */ - ptr = ptr.offset(1); - while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + if !ptr.is_null() { + /* we require a colon for this to be a true header */ ptr = ptr.offset(1); - } - if *ptr as i32 != 0 || !semicolonp.is_null() { - /* only send this if the contents was non-blank or done special */ - let mut result: CURLcode = CURLE_OK; - let mut compare: *mut libc::c_char = if !semicolonp.is_null() { - semicolonp - } else { - (*headers).data - }; - if !(!((*data).state.aptr.host).is_null() && + while *ptr as i32 != 0 && Curl_isspace(*ptr as u8 as i32) != 0 { + ptr = ptr.offset(1); + } + if *ptr as i32 != 0 || !semicolonp.is_null() { + /* only send this if the contents was non-blank or done special */ + let mut result: CURLcode = CURLE_OK; + let mut compare: *mut libc::c_char = if !semicolonp.is_null() { + semicolonp + } else { + (*headers).data + }; + if !(!((*data).state.aptr.host).is_null() && /* a Host: header was sent already, don't pass on any custom Host: header as that will produce *two* in the same request! */ curl_strnequal( @@ -2822,24 +2923,24 @@ pub extern "C" fn Curl_add_custom_headers( compare, strlen(b"Host:\0" as *const u8 as *const libc::c_char), ) != 0) - { - if !((*data).state.httpreq as u32 == HTTPREQ_POST_FORM + { + if !((*data).state.httpreq as u32 == HTTPREQ_POST_FORM /* this header (extended by formdata.c) is sent later */ && curl_strnequal( b"Content-Type:\0" as *const u8 as *const libc::c_char, compare, strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), ) != 0) - { - if !((*data).state.httpreq as u32 == HTTPREQ_POST_MIME + { + if !((*data).state.httpreq as u32 == HTTPREQ_POST_MIME /* this header is sent later */ && curl_strnequal( b"Content-Type:\0" as *const u8 as *const libc::c_char, compare, strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), ) != 0) - { - if !(((*conn).bits).authneg() as i32 != 0 + { + if !(((*conn).bits).authneg() as i32 != 0 && /* while doing auth neg, don't allow the custom length since we will force length zero then */ @@ -2851,8 +2952,8 @@ pub extern "C" fn Curl_add_custom_headers( as *const libc::c_char, ), ) != 0) - { - if !(!((*data).state.aptr.te).is_null() + { + if !(!((*data).state.aptr.te).is_null() && /* when asking for Transfer-Encoding, don't pass on a custom Connection: */ @@ -2864,8 +2965,8 @@ pub extern "C" fn Curl_add_custom_headers( as *const libc::c_char, ), ) != 0) - { - if !((*conn).httpversion as i32 >= 20 + { + if !((*conn).httpversion as i32 >= 20 && /* HTTP/2 doesn't support chunked requests */ curl_strnequal( @@ -2877,8 +2978,8 @@ pub extern "C" fn Curl_add_custom_headers( as *const libc::c_char, ), ) != 0) - { - if !((curl_strnequal( + { + if !((curl_strnequal( b"Authorization:\0" as *const u8 as *const libc::c_char, compare, @@ -2906,21 +3007,23 @@ pub extern "C" fn Curl_add_custom_headers( (*data).state.first_host, (*conn).host.name, ) == 0)) - { - match () { - #[cfg(USE_HYPER)] - _ => { - result = - Curl_hyper_header(data, req, compare); - } - #[cfg(not(USE_HYPER))] - _ => { - result = Curl_dyn_addf( - req, - b"%s\r\n\0" as *const u8 - as *const libc::c_char, - compare, - ); + { + match () { + #[cfg(USE_HYPER)] + _ => { + result = Curl_hyper_header( + data, req, compare, + ); + } + #[cfg(not(USE_HYPER))] + _ => { + result = Curl_dyn_addf( + req, + b"%s\r\n\0" as *const u8 + as *const libc::c_char, + compare, + ); + } } } } @@ -2929,28 +3032,27 @@ pub extern "C" fn Curl_add_custom_headers( } } } - } - if !semicolonp.is_null() { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - semicolonp as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - semicolonp as *mut libc::c_void, - 1929 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - } - if result as u64 != 0 { - return result; + if !semicolonp.is_null() { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + semicolonp as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + semicolonp as *mut libc::c_void, + 1929 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + } + if result as u64 != 0 { + return result; + } } } + headers = (*headers).next; } - headers = (*headers).next; + i += 1; } - i += 1; - } } return CURLE_OK; } @@ -2965,84 +3067,84 @@ pub extern "C" fn Curl_add_timecondition( mut data: *mut Curl_easy, mut req: *mut dynbuf, ) -> CURLcode { - unsafe{ - let mut tm: *const tm = 0 as *const tm; - let mut keeptime: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *const libc::c_char, - }; - let mut result: CURLcode = CURLE_OK; - let mut datestr: [libc::c_char; 80] = [0; 80]; - let mut condp: *const libc::c_char = 0 as *const libc::c_char; - if (*data).set.timecondition as u32 == CURL_TIMECOND_NONE as i32 as u32 { - /* no condition was asked for */ - return CURLE_OK; - } - result = Curl_gmtime((*data).set.timevalue, &mut keeptime); - if result as u64 != 0 { - Curl_failf( - data, - b"Invalid TIMEVALUE\0" as *const u8 as *const libc::c_char, - ); - return result; - } - tm = &mut keeptime; - - match (*data).set.timecondition as u32 { - CURL_TIMECOND_IFMODSINCE => { - condp = b"If-Modified-Since\0" as *const u8 as *const libc::c_char; + unsafe { + let mut tm: *const tm = 0 as *const tm; + let mut keeptime: tm = tm { + tm_sec: 0, + tm_min: 0, + tm_hour: 0, + tm_mday: 0, + tm_mon: 0, + tm_year: 0, + tm_wday: 0, + tm_yday: 0, + tm_isdst: 0, + tm_gmtoff: 0, + tm_zone: 0 as *const libc::c_char, + }; + let mut result: CURLcode = CURLE_OK; + let mut datestr: [libc::c_char; 80] = [0; 80]; + let mut condp: *const libc::c_char = 0 as *const libc::c_char; + if (*data).set.timecondition as u32 == CURL_TIMECOND_NONE as i32 as u32 { + /* no condition was asked for */ + return CURLE_OK; } - CURL_TIMECOND_IFUNMODSINCE => { - condp = b"If-Unmodified-Since\0" as *const u8 as *const libc::c_char; + result = Curl_gmtime((*data).set.timevalue, &mut keeptime); + if result as u64 != 0 { + Curl_failf( + data, + b"Invalid TIMEVALUE\0" as *const u8 as *const libc::c_char, + ); + return result; + } + tm = &mut keeptime; + + match (*data).set.timecondition as u32 { + CURL_TIMECOND_IFMODSINCE => { + condp = b"If-Modified-Since\0" as *const u8 as *const libc::c_char; + } + CURL_TIMECOND_IFUNMODSINCE => { + condp = b"If-Unmodified-Since\0" as *const u8 as *const libc::c_char; + } + CURL_TIMECOND_LASTMOD => { + condp = b"Last-Modified\0" as *const u8 as *const libc::c_char; + } + _ => return CURLE_BAD_FUNCTION_ARGUMENT, } - CURL_TIMECOND_LASTMOD => { - condp = b"Last-Modified\0" as *const u8 as *const libc::c_char; + if !(Curl_checkheaders(data, condp)).is_null() { + /* A custom header was specified; it will be sent instead. */ + return CURLE_OK; } - _ => return CURLE_BAD_FUNCTION_ARGUMENT, - } - if !(Curl_checkheaders(data, condp)).is_null() { - /* A custom header was specified; it will be sent instead. */ - return CURLE_OK; - } - /* The If-Modified-Since header family should have their times set in - * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be - * represented in Greenwich Mean Time (GMT), without exception. For the - * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal - * Time)." (see page 20 of RFC2616). - */ + /* The If-Modified-Since header family should have their times set in + * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be + * represented in Greenwich Mean Time (GMT), without exception. For the + * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal + * Time)." (see page 20 of RFC2616). + */ - /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - curl_msnprintf( - datestr.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 80]>() as u64, - b"%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\0" as *const u8 as *const libc::c_char, - condp, - Curl_wkday[(if (*tm).tm_wday != 0 { - (*tm).tm_wday - 1 as i32 - } else { - 6 as i32 - }) as usize], - (*tm).tm_mday, - Curl_month[(*tm).tm_mon as usize], - (*tm).tm_year + 1900 as i32, - (*tm).tm_hour, - (*tm).tm_min, - (*tm).tm_sec, - ); - - result = Curl_hyper_header(data, req as *mut hyper_headers, datestr.as_mut_ptr()); - return result; -} + /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ + curl_msnprintf( + datestr.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 80]>() as u64, + b"%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\0" as *const u8 as *const libc::c_char, + condp, + Curl_wkday[(if (*tm).tm_wday != 0 { + (*tm).tm_wday - 1 as i32 + } else { + 6 as i32 + }) as usize], + (*tm).tm_mday, + Curl_month[(*tm).tm_mon as usize], + (*tm).tm_year + 1900 as i32, + (*tm).tm_hour, + (*tm).tm_min, + (*tm).tm_sec, + ); + + result = Curl_hyper_header(data, req as *mut hyper_headers, datestr.as_mut_ptr()); + return result; + } } #[cfg(all(not(CURL_DISABLE_PARSEDATE), not(USE_HYPER)))] @@ -3068,54 +3170,54 @@ pub extern "C" fn Curl_add_timecondition( let mut result: CURLcode = CURLE_OK; let mut datestr: [libc::c_char; 80] = [0; 80]; let mut condp: *const libc::c_char = 0 as *const libc::c_char; - unsafe{ - if (*data).set.timecondition as u32 == CURL_TIMECOND_NONE as i32 as u32 { - return CURLE_OK; - } - result = Curl_gmtime((*data).set.timevalue, &mut keeptime); - if result as u64 != 0 { - Curl_failf( - data, - b"Invalid TIMEVALUE\0" as *const u8 as *const libc::c_char, - ); - return result; - } - tm = &mut keeptime; - match (*data).set.timecondition as u32 { - CURL_TIMECOND_IFMODSINCE => { - condp = b"If-Modified-Since\0" as *const u8 as *const libc::c_char; + unsafe { + if (*data).set.timecondition as u32 == CURL_TIMECOND_NONE as i32 as u32 { + return CURLE_OK; + } + result = Curl_gmtime((*data).set.timevalue, &mut keeptime); + if result as u64 != 0 { + Curl_failf( + data, + b"Invalid TIMEVALUE\0" as *const u8 as *const libc::c_char, + ); + return result; } - CURL_TIMECOND_IFUNMODSINCE => { - condp = b"If-Unmodified-Since\0" as *const u8 as *const libc::c_char; + tm = &mut keeptime; + match (*data).set.timecondition as u32 { + CURL_TIMECOND_IFMODSINCE => { + condp = b"If-Modified-Since\0" as *const u8 as *const libc::c_char; + } + CURL_TIMECOND_IFUNMODSINCE => { + condp = b"If-Unmodified-Since\0" as *const u8 as *const libc::c_char; + } + CURL_TIMECOND_LASTMOD => { + condp = b"Last-Modified\0" as *const u8 as *const libc::c_char; + } + _ => return CURLE_BAD_FUNCTION_ARGUMENT, } - CURL_TIMECOND_LASTMOD => { - condp = b"Last-Modified\0" as *const u8 as *const libc::c_char; + if !(Curl_checkheaders(data, condp)).is_null() { + return CURLE_OK; } - _ => return CURLE_BAD_FUNCTION_ARGUMENT, - } - if !(Curl_checkheaders(data, condp)).is_null() { - return CURLE_OK; + curl_msnprintf( + datestr.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 80]>() as u64, + b"%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\0" as *const u8 as *const libc::c_char, + condp, + Curl_wkday[(if (*tm).tm_wday != 0 { + (*tm).tm_wday - 1 + } else { + 6 + }) as usize], + (*tm).tm_mday, + Curl_month[(*tm).tm_mon as usize], + (*tm).tm_year + 1900, + (*tm).tm_hour, + (*tm).tm_min, + (*tm).tm_sec, + ); + result = Curl_dyn_add(req, datestr.as_mut_ptr()); + return result; } - curl_msnprintf( - datestr.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 80]>() as u64, - b"%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\0" as *const u8 as *const libc::c_char, - condp, - Curl_wkday[(if (*tm).tm_wday != 0 { - (*tm).tm_wday - 1 - } else { - 6 - }) as usize], - (*tm).tm_mday, - Curl_month[(*tm).tm_mon as usize], - (*tm).tm_year + 1900, - (*tm).tm_hour, - (*tm).tm_min, - (*tm).tm_sec, - ); - result = Curl_dyn_add(req, datestr.as_mut_ptr()); - return result; -} } /* disabled */ @@ -3124,8 +3226,9 @@ pub extern "C" fn Curl_add_timecondition( mut data: *mut Curl_easy, mut req: *mut dynbuf, ) -> CURLcode { - unsafe{ - return CURLE_OK;} + unsafe { + return CURLE_OK; + } } const PROTO_FAMILY_HTTP: u32 = 1 << 0 | 1 << 1; @@ -3138,27 +3241,27 @@ pub extern "C" fn Curl_http_method( mut method: *mut *const libc::c_char, mut reqp: *mut Curl_HttpReq, ) { - let mut httpreq: Curl_HttpReq =unsafe{ (*data).state.httpreq}; + let mut httpreq: Curl_HttpReq = unsafe { (*data).state.httpreq }; let mut request: *const libc::c_char = 0 as *const libc::c_char; - unsafe{ - if (*(*conn).handler).protocol & (PROTO_FAMILY_HTTP | CURLPROTO_FTP) != 0 - && ((*data).set).upload() as i32 != 0 - { - httpreq = HTTPREQ_PUT; - } - - /* Now set the 'request' pointer to the proper request string */ - if !((*data).set.str_0[STRING_CUSTOMREQUEST as i32 as usize]).is_null() { - request = (*data).set.str_0[STRING_CUSTOMREQUEST as i32 as usize]; - } else if ((*data).set).opt_no_body() != 0 { - request = b"HEAD\0" as *const u8 as *const libc::c_char; - } else { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if httpreq as u32 >= HTTPREQ_GET as i32 as u32 - && httpreq as u32 <= HTTPREQ_HEAD as i32 as u32 + unsafe { + if (*(*conn).handler).protocol & (PROTO_FAMILY_HTTP | CURLPROTO_FTP) != 0 + && ((*data).set).upload() as i32 != 0 { + httpreq = HTTPREQ_PUT; + } + + /* Now set the 'request' pointer to the proper request string */ + if !((*data).set.str_0[STRING_CUSTOMREQUEST as i32 as usize]).is_null() { + request = (*data).set.str_0[STRING_CUSTOMREQUEST as i32 as usize]; + } else if ((*data).set).opt_no_body() != 0 { + request = b"HEAD\0" as *const u8 as *const libc::c_char; } else { - __assert_fail( + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if httpreq as u32 >= HTTPREQ_GET as i32 as u32 + && httpreq as u32 <= HTTPREQ_HEAD as i32 as u32 + { + } else { + __assert_fail( b"(httpreq >= HTTPREQ_GET) && (httpreq <= HTTPREQ_HEAD)\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, @@ -3171,8 +3274,8 @@ pub extern "C" fn Curl_http_method( )) .as_ptr(), ); - } - match httpreq as u32 { + } + match httpreq as u32 { HTTPREQ_POST | HTTPREQ_POST_FORM | HTTPREQ_POST_MIME => { request = b"POST\0" as *const u8 as *const libc::c_char; } @@ -3186,209 +3289,213 @@ pub extern "C" fn Curl_http_method( request = b"GET\0" as *const u8 as *const libc::c_char; } } + } + *method = request; + *reqp = httpreq; } - *method = request; - *reqp = httpreq;} } #[no_mangle] pub extern "C" fn Curl_http_useragent(mut data: *mut Curl_easy) -> CURLcode { - unsafe{ - /* The User-Agent string might have been allocated in url.c already, because - it might have been used in the proxy connect, but if we have got a header - with the user-agent string specified, we erase the previously made string - here. */ - if !(Curl_checkheaders(data, b"User-Agent\0" as *const u8 as *const libc::c_char)).is_null() { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.uagent as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.uagent as *mut libc::c_void, - 2072, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - (*data).state.aptr.uagent = 0 as *mut libc::c_char; + unsafe { + /* The User-Agent string might have been allocated in url.c already, because + it might have been used in the proxy connect, but if we have got a header + with the user-agent string specified, we erase the previously made string + here. */ + if !(Curl_checkheaders(data, b"User-Agent\0" as *const u8 as *const libc::c_char)).is_null() + { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.uagent as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.uagent as *mut libc::c_void, + 2072, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).state.aptr.uagent = 0 as *mut libc::c_char; + } + return CURLE_OK; } - return CURLE_OK; -} } #[no_mangle] -pub extern "C" fn Curl_http_host( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, -) -> CURLcode { +pub extern "C" fn Curl_http_host(mut data: *mut Curl_easy, mut conn: *mut connectdata) -> CURLcode { let mut ptr: *const libc::c_char = 0 as *const libc::c_char; - unsafe{ - if ((*data).state).this_is_a_follow() == 0 { - /* Free to avoid leaking memory on multiple requests*/ + unsafe { + if ((*data).state).this_is_a_follow() == 0 { + /* Free to avoid leaking memory on multiple requests*/ + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.first_host as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.first_host as *mut libc::c_void, + 2084, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + match () { + #[cfg(not(CURLDEBUG))] + _ => { + (*data).state.first_host = + Curl_cstrdup.expect("non-null function pointer")((*conn).host.name); + } + #[cfg(CURLDEBUG)] + _ => { + (*data).state.first_host = curl_dbg_strdup( + (*conn).host.name, + 2086 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + } + } + if ((*data).state.first_host).is_null() { + return CURLE_OUT_OF_MEMORY; + } + (*data).state.first_remote_port = (*conn).remote_port; + } #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( - (*data).state.first_host as *mut libc::c_void, + (*data).state.aptr.host as *mut libc::c_void, ); #[cfg(CURLDEBUG)] curl_dbg_free( - (*data).state.first_host as *mut libc::c_void, - 2084, + (*data).state.aptr.host as *mut libc::c_void, + 2092 as i32, b"http.c\0" as *const u8 as *const libc::c_char, ); - match () { - #[cfg(not(CURLDEBUG))] - _ => { - (*data).state.first_host = - Curl_cstrdup.expect("non-null function pointer")((*conn).host.name); - } - #[cfg(CURLDEBUG)] - _ => { - (*data).state.first_host = curl_dbg_strdup( - (*conn).host.name, - 2086 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - } - } - if ((*data).state.first_host).is_null() { - return CURLE_OUT_OF_MEMORY; - } - (*data).state.first_remote_port = (*conn).remote_port; - } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")((*data).state.aptr.host as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.host as *mut libc::c_void, - 2092 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - (*data).state.aptr.host = 0 as *mut libc::c_char; - ptr = Curl_checkheaders(data, b"Host\0" as *const u8 as *const libc::c_char); - if !ptr.is_null() - && (((*data).state).this_is_a_follow() == 0 - || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0) - { - match () { - #[cfg(not(CURL_DISABLE_COOKIES))] - /* If we have a given custom Host: header, we extract the host name in - order to possibly use it for cookie reasons later on. We only allow the - custom Host: header if this is NOT a redirect, as setting Host: in the - redirected request is being out on thin ice. Except if the host name - is the same as the first one! */ - _ => { - let mut cookiehost: *mut libc::c_char = Curl_copy_header_value(ptr); - if cookiehost.is_null() { - return CURLE_OUT_OF_MEMORY; - } - if *cookiehost == 0 { - /* ignore empty data */ - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(cookiehost as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - cookiehost as *mut libc::c_void, - 2108, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - } else { - /* If the host begins with '[', we start searching for the port after - the bracket has been closed */ - if *cookiehost as i32 == '[' as i32 { - let mut closingbracket: *mut libc::c_char = 0 as *mut libc::c_char; - /* since the 'cookiehost' is an allocated memory area that will be - freed later we cannot simply increment the pointer */ - memmove( + (*data).state.aptr.host = 0 as *mut libc::c_char; + ptr = Curl_checkheaders(data, b"Host\0" as *const u8 as *const libc::c_char); + if !ptr.is_null() + && (((*data).state).this_is_a_follow() == 0 + || Curl_strcasecompare((*data).state.first_host, (*conn).host.name) != 0) + { + match () { + #[cfg(not(CURL_DISABLE_COOKIES))] + /* If we have a given custom Host: header, we extract the host name in + order to possibly use it for cookie reasons later on. We only allow the + custom Host: header if this is NOT a redirect, as setting Host: in the + redirected request is being out on thin ice. Except if the host name + is the same as the first one! */ + _ => { + let mut cookiehost: *mut libc::c_char = Curl_copy_header_value(ptr); + if cookiehost.is_null() { + return CURLE_OUT_OF_MEMORY; + } + if *cookiehost == 0 { + /* ignore empty data */ + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( cookiehost as *mut libc::c_void, - cookiehost.offset(1 as i32 as isize) as *const libc::c_void, - (strlen(cookiehost)).wrapping_sub(1 as u64), ); - closingbracket = strchr(cookiehost, ']' as i32); - if !closingbracket.is_null() { - *closingbracket = 0 as libc::c_char; - } + #[cfg(CURLDEBUG)] + curl_dbg_free( + cookiehost as *mut libc::c_void, + 2108, + b"http.c\0" as *const u8 as *const libc::c_char, + ); } else { - let mut startsearch: i32 = 0; - let mut colon: *mut libc::c_char = - strchr(cookiehost.offset(startsearch as isize), ':' as i32); - if !colon.is_null() { - *colon = 0 as i32 as libc::c_char; /* The host must not include an embedded port number */ + /* If the host begins with '[', we start searching for the port after + the bracket has been closed */ + if *cookiehost as i32 == '[' as i32 { + let mut closingbracket: *mut libc::c_char = 0 as *mut libc::c_char; + /* since the 'cookiehost' is an allocated memory area that will be + freed later we cannot simply increment the pointer */ + memmove( + cookiehost as *mut libc::c_void, + cookiehost.offset(1 as i32 as isize) as *const libc::c_void, + (strlen(cookiehost)).wrapping_sub(1 as u64), + ); + closingbracket = strchr(cookiehost, ']' as i32); + if !closingbracket.is_null() { + *closingbracket = 0 as libc::c_char; + } + } else { + let mut startsearch: i32 = 0; + let mut colon: *mut libc::c_char = + strchr(cookiehost.offset(startsearch as isize), ':' as i32); + if !colon.is_null() { + *colon = 0 as i32 as libc::c_char; /* The host must not include an embedded port number */ + } } + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.cookiehost as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.cookiehost as *mut libc::c_void, + 2127, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).state.aptr.cookiehost = 0 as *mut libc::c_char; + (*data).state.aptr.cookiehost = cookiehost; } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.cookiehost as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.cookiehost as *mut libc::c_void, - 2127, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - (*data).state.aptr.cookiehost = 0 as *mut libc::c_char; - (*data).state.aptr.cookiehost = cookiehost; } + #[cfg(CURL_DISABLE_COOKIES)] + _ => {} } - #[cfg(CURL_DISABLE_COOKIES)] - _ => {} - } - if strcmp(b"Host:\0" as *const u8 as *const libc::c_char, ptr) != 0 { - (*data).state.aptr.host = curl_maprintf( - b"Host:%s\r\n\0" as *const u8 as *const libc::c_char, - &*ptr.offset(5 as i32 as isize) as *const libc::c_char, - ); + if strcmp(b"Host:\0" as *const u8 as *const libc::c_char, ptr) != 0 { + (*data).state.aptr.host = curl_maprintf( + b"Host:%s\r\n\0" as *const u8 as *const libc::c_char, + &*ptr.offset(5 as i32 as isize) as *const libc::c_char, + ); + if ((*data).state.aptr.host).is_null() { + return CURLE_OUT_OF_MEMORY; + } + } else { + /* when clearing the header */ + (*data).state.aptr.host = 0 as *mut libc::c_char; + } + } else { + /* When building Host: headers, we must put the host name within + [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ + let mut host: *const libc::c_char = (*conn).host.name; + if (*(*conn).given).protocol & CURLPROTO_HTTPS != 0 && (*conn).remote_port == PORT_HTTPS + || (*(*conn).given).protocol & CURLPROTO_HTTP != 0 + && (*conn).remote_port == PORT_HTTP + { + /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include + the port number in the host string */ + (*data).state.aptr.host = curl_maprintf( + b"Host: %s%s%s\r\n\0" as *const u8 as *const libc::c_char, + if ((*conn).bits).ipv6_ip() as i32 != 0 { + b"[\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + host, + if ((*conn).bits).ipv6_ip() as i32 != 0 { + b"]\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + } else { + (*data).state.aptr.host = curl_maprintf( + b"Host: %s%s%s:%d\r\n\0" as *const u8 as *const libc::c_char, + if ((*conn).bits).ipv6_ip() as i32 != 0 { + b"[\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + host, + if ((*conn).bits).ipv6_ip() as i32 != 0 { + b"]\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + (*conn).remote_port, + ); + } + /* without Host: we can't make a nice request */ if ((*data).state.aptr.host).is_null() { return CURLE_OUT_OF_MEMORY; } - } else { - /* when clearing the header */ - (*data).state.aptr.host = 0 as *mut libc::c_char; - } - } else { - /* When building Host: headers, we must put the host name within - [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ - let mut host: *const libc::c_char = (*conn).host.name; - if (*(*conn).given).protocol & CURLPROTO_HTTPS != 0 && (*conn).remote_port == PORT_HTTPS - || (*(*conn).given).protocol & CURLPROTO_HTTP != 0 && (*conn).remote_port == PORT_HTTP - { - /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include - the port number in the host string */ - (*data).state.aptr.host = curl_maprintf( - b"Host: %s%s%s\r\n\0" as *const u8 as *const libc::c_char, - if ((*conn).bits).ipv6_ip() as i32 != 0 { - b"[\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - host, - if ((*conn).bits).ipv6_ip() as i32 != 0 { - b"]\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - ); - } else { - (*data).state.aptr.host = curl_maprintf( - b"Host: %s%s%s:%d\r\n\0" as *const u8 as *const libc::c_char, - if ((*conn).bits).ipv6_ip() as i32 != 0 { - b"[\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - host, - if ((*conn).bits).ipv6_ip() as i32 != 0 { - b"]\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - (*conn).remote_port, - ); - } - /* without Host: we can't make a nice request */ - if ((*data).state.aptr.host).is_null() { - return CURLE_OUT_OF_MEMORY; } } -} return CURLE_OK; } @@ -3402,129 +3509,147 @@ pub extern "C" fn Curl_http_target( mut r: *mut dynbuf, ) -> CURLcode { let mut result: CURLcode = CURLE_OK; - let mut path: *const libc::c_char =unsafe{ (*data).state.up.path}; - let mut query: *const libc::c_char =unsafe{ (*data).state.up.query}; - unsafe{ - if !((*data).set.str_0[STRING_TARGET as i32 as usize]).is_null() { - path = (*data).set.str_0[STRING_TARGET as i32 as usize]; - query = 0 as *const libc::c_char; - } - match () { - #[cfg(not(CURL_DISABLE_PROXY))] - _ => { - if ((*conn).bits).httpproxy() as i32 != 0 && ((*conn).bits).tunnel_proxy() == 0 { - /* Using a proxy but does not tunnel through it */ - - /* The path sent to the proxy is in fact the entire URL. But if the remote - host is a IDN-name, we must make sure that the request we produce only - uses the encoded host name! */ - - /* and no fragment part */ - let mut uc: CURLUcode = CURLUE_OK; - let mut url: *mut libc::c_char = 0 as *mut libc::c_char; - let mut h: *mut CURLU = curl_url_dup((*data).state.uh); - if h.is_null() { - return CURLE_OUT_OF_MEMORY; - } - - if (*conn).host.dispname != (*conn).host.name as *const libc::c_char { - uc = curl_url_set(h, CURLUPART_HOST, (*conn).host.name, 0 as i32 as u32); - if uc as u64 != 0 { - curl_url_cleanup(h); + let mut path: *const libc::c_char = unsafe { (*data).state.up.path }; + let mut query: *const libc::c_char = unsafe { (*data).state.up.query }; + unsafe { + if !((*data).set.str_0[STRING_TARGET as i32 as usize]).is_null() { + path = (*data).set.str_0[STRING_TARGET as i32 as usize]; + query = 0 as *const libc::c_char; + } + match () { + #[cfg(not(CURL_DISABLE_PROXY))] + _ => { + if ((*conn).bits).httpproxy() as i32 != 0 && ((*conn).bits).tunnel_proxy() == 0 { + /* Using a proxy but does not tunnel through it */ + + /* The path sent to the proxy is in fact the entire URL. But if the remote + host is a IDN-name, we must make sure that the request we produce only + uses the encoded host name! */ + + /* and no fragment part */ + let mut uc: CURLUcode = CURLUE_OK; + let mut url: *mut libc::c_char = 0 as *mut libc::c_char; + let mut h: *mut CURLU = curl_url_dup((*data).state.uh); + if h.is_null() { return CURLE_OUT_OF_MEMORY; } - } - uc = curl_url_set(h, CURLUPART_FRAGMENT, 0 as *const libc::c_char, 0 as u32); - if uc as u64 != 0 { - curl_url_cleanup(h); - return CURLE_OUT_OF_MEMORY; - } - if Curl_strcasecompare( - b"http\0" as *const u8 as *const libc::c_char, - (*data).state.up.scheme, - ) != 0 - { - /* when getting HTTP, we don't want the userinfo the URL */ - uc = curl_url_set(h, CURLUPART_USER, 0 as *const libc::c_char, 0 as i32 as u32); + if (*conn).host.dispname != (*conn).host.name as *const libc::c_char { + uc = curl_url_set(h, CURLUPART_HOST, (*conn).host.name, 0 as i32 as u32); + if uc as u64 != 0 { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + } + uc = curl_url_set(h, CURLUPART_FRAGMENT, 0 as *const libc::c_char, 0 as u32); if uc as u64 != 0 { curl_url_cleanup(h); return CURLE_OUT_OF_MEMORY; } - uc = curl_url_set(h, CURLUPART_PASSWORD, 0 as *const libc::c_char, 0 as u32); + + if Curl_strcasecompare( + b"http\0" as *const u8 as *const libc::c_char, + (*data).state.up.scheme, + ) != 0 + { + /* when getting HTTP, we don't want the userinfo the URL */ + uc = curl_url_set( + h, + CURLUPART_USER, + 0 as *const libc::c_char, + 0 as i32 as u32, + ); + if uc as u64 != 0 { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + uc = + curl_url_set(h, CURLUPART_PASSWORD, 0 as *const libc::c_char, 0 as u32); + if uc as u64 != 0 { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + } + /* Extract the URL to use in the request. Store in STRING_TEMP_URL for + clean-up reasons if the function returns before the free() further + down. */ + uc = curl_url_get(h, CURLUPART_URL, &mut url, ((1 as i32) << 1 as i32) as u32); if uc as u64 != 0 { curl_url_cleanup(h); return CURLE_OUT_OF_MEMORY; } - } - /* Extract the URL to use in the request. Store in STRING_TEMP_URL for - clean-up reasons if the function returns before the free() further - down. */ - uc = curl_url_get(h, CURLUPART_URL, &mut url, ((1 as i32) << 1 as i32) as u32); - if uc as u64 != 0 { curl_url_cleanup(h); - return CURLE_OUT_OF_MEMORY; - } - curl_url_cleanup(h); - result = Curl_dyn_add( - r, - if !((*data).set.str_0[STRING_TARGET as i32 as usize]).is_null() { - (*data).set.str_0[STRING_TARGET as i32 as usize] - } else { - url - }, - ); + result = Curl_dyn_add( + r, + if !((*data).set.str_0[STRING_TARGET as i32 as usize]).is_null() { + (*data).set.str_0[STRING_TARGET as i32 as usize] + } else { + url + }, + ); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(url as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - url as *mut libc::c_void, - 2241, - b"http.c\0" as *const u8 as *const libc::c_char, - ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(url as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + url as *mut libc::c_void, + 2241, + b"http.c\0" as *const u8 as *const libc::c_char, + ); - /* target or url */ - if result as u64 != 0 { - return result; - } - if Curl_strcasecompare( - b"ftp\0" as *const u8 as *const libc::c_char, - (*data).state.up.scheme, - ) != 0 - { - if ((*data).set).proxy_transfer_mode() != 0 { - /* when doing ftp, append ;type= if not present */ - let mut type_0: *mut libc::c_char = - strstr(path, b";type=\0" as *const u8 as *const libc::c_char); - if !type_0.is_null() - && *type_0.offset(6 as isize) as i32 != 0 - && *type_0.offset(7 as isize) as i32 == 0 - { - match Curl_raw_toupper(*type_0.offset(6 as isize)) as i32 { - 65 | 68 | 73 => {} - _ => { - type_0 = 0 as *mut libc::c_char; + /* target or url */ + if result as u64 != 0 { + return result; + } + if Curl_strcasecompare( + b"ftp\0" as *const u8 as *const libc::c_char, + (*data).state.up.scheme, + ) != 0 + { + if ((*data).set).proxy_transfer_mode() != 0 { + /* when doing ftp, append ;type= if not present */ + let mut type_0: *mut libc::c_char = + strstr(path, b";type=\0" as *const u8 as *const libc::c_char); + if !type_0.is_null() + && *type_0.offset(6 as isize) as i32 != 0 + && *type_0.offset(7 as isize) as i32 == 0 + { + match Curl_raw_toupper(*type_0.offset(6 as isize)) as i32 { + 65 | 68 | 73 => {} + _ => { + type_0 = 0 as *mut libc::c_char; + } } } - } - if type_0.is_null() { - result = Curl_dyn_addf( - r, - b";type=%c\0" as *const u8 as *const libc::c_char, - if ((*data).state).prefer_ascii() as i32 != 0 { - 'a' as i32 - } else { - 'i' as i32 - }, - ); - if result as u64 != 0 { - return result; + if type_0.is_null() { + result = Curl_dyn_addf( + r, + b";type=%c\0" as *const u8 as *const libc::c_char, + if ((*data).state).prefer_ascii() as i32 != 0 { + 'a' as i32 + } else { + 'i' as i32 + }, + ); + if result as u64 != 0 { + return result; + } } } } + } else { + result = Curl_dyn_add(r, path); + if result as u64 != 0 { + return result; + } + if !query.is_null() { + result = + Curl_dyn_addf(r, b"?%s\0" as *const u8 as *const libc::c_char, query); + } } - } else { + } + #[cfg(CURL_DISABLE_PROXY)] + _ => { result = Curl_dyn_add(r, path); if result as u64 != 0 { return result; @@ -3534,18 +3659,7 @@ pub extern "C" fn Curl_http_target( } } } - #[cfg(CURL_DISABLE_PROXY)] - _ => { - result = Curl_dyn_add(r, path); - if result as u64 != 0 { - return result; - } - if !query.is_null() { - result = Curl_dyn_addf(r, b"?%s\0" as *const u8 as *const libc::c_char, query); - } - } } -} return result; } @@ -3558,149 +3672,152 @@ pub extern "C" fn Curl_http_body( ) -> CURLcode { let mut result: CURLcode = CURLE_OK; let mut ptr: *const libc::c_char = 0 as *const libc::c_char; - let mut http: *mut HTTP =unsafe{ (*data).req.p.http}; - unsafe{(*http).postsize = 0 as curl_off_t;} - unsafe{ - match httpreq as u32 { - HTTPREQ_POST_MIME => { - (*http).sendit = &mut (*data).set.mimepost; - } - HTTPREQ_POST_FORM => { - /* Convert the form structure into a mime structure. */ - #[cfg(any( - all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), - not(CURL_DISABLE_SMTP), - not(CURL_DISABLE_IMAP) - ))] - Curl_mime_cleanpart(&mut (*http).form); - // TODO 待测试 + let mut http: *mut HTTP = unsafe { (*data).req.p.http }; + unsafe { + (*http).postsize = 0 as curl_off_t; + } + unsafe { + match httpreq as u32 { + HTTPREQ_POST_MIME => { + (*http).sendit = &mut (*data).set.mimepost; + } + HTTPREQ_POST_FORM => { + /* Convert the form structure into a mime structure. */ + #[cfg(any( + all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), + not(CURL_DISABLE_SMTP), + not(CURL_DISABLE_IMAP) + ))] + Curl_mime_cleanpart(&mut (*http).form); + // TODO 待测试 + match () { + #[cfg(not(CURL_DISABLE_MIME))] + _ => { + result = Curl_getformdata( + data, + &mut (*http).form, + (*data).set.httppost, + (*data).state.fread_func, + ); + } + #[cfg(CURL_DISABLE_MIME)] + _ => { + result = CURLE_NOT_BUILT_IN; + } + } + // result = Curl_getformdata( + // data, + // &mut (*http).form, + // (*data).set.httppost, + // (*data).state.fread_func, + // ); + if result as u64 != 0 { + return result; + } + (*http).sendit = &mut (*http).form; + } + _ => { + (*http).sendit = 0 as *mut curl_mimepart; + } + } + + #[cfg(not(CURL_DISABLE_MIME))] + if !((*http).sendit).is_null() { + let mut cthdr: *const libc::c_char = + Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char); + + /* Read and seek body only. */ + (*(*http).sendit).flags |= MIME_BODY_ONLY; + + /* Prepare the mime structure headers & set content type. */ + if !cthdr.is_null() { + cthdr = cthdr.offset(13 as i32 as isize); + while *cthdr as i32 == ' ' as i32 { + cthdr = cthdr.offset(1); + } + } else if (*(*http).sendit).kind as u32 == MIMEKIND_MULTIPART as i32 as u32 { + cthdr = b"multipart/form-data\0" as *const u8 as *const libc::c_char; + } + curl_mime_headers((*http).sendit, (*data).set.headers, 0 as i32); + // 好像这里其实可以不要条件编译 match () { - #[cfg(not(CURL_DISABLE_MIME))] + #[cfg(any( + all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), + not(CURL_DISABLE_SMTP), + not(CURL_DISABLE_IMAP) + ))] _ => { - result = Curl_getformdata( - data, - &mut (*http).form, - (*data).set.httppost, - (*data).state.fread_func, + result = Curl_mime_prepare_headers( + (*http).sendit, + cthdr, + 0 as *const libc::c_char, + MIMESTRATEGY_FORM, ); } - #[cfg(CURL_DISABLE_MIME)] _ => { result = CURLE_NOT_BUILT_IN; } } - // result = Curl_getformdata( - // data, - // &mut (*http).form, - // (*data).set.httppost, - // (*data).state.fread_func, + // result = Curl_mime_prepare_headers( + // (*http).sendit, + // cthdr, + // 0 as *const libc::c_char, + // MIMESTRATEGY_FORM, // ); + curl_mime_headers((*http).sendit, 0 as *mut curl_slist, 0 as i32); + if result as u64 == 0 { + result = Curl_mime_rewind((*http).sendit); + } if result as u64 != 0 { return result; } - (*http).sendit = &mut (*http).form; - } - _ => { - (*http).sendit = 0 as *mut curl_mimepart; - } - } - - #[cfg(not(CURL_DISABLE_MIME))] - if !((*http).sendit).is_null() { - let mut cthdr: *const libc::c_char = - Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char); - - /* Read and seek body only. */ - (*(*http).sendit).flags |= MIME_BODY_ONLY; - - /* Prepare the mime structure headers & set content type. */ - if !cthdr.is_null() { - cthdr = cthdr.offset(13 as i32 as isize); - while *cthdr as i32 == ' ' as i32 { - cthdr = cthdr.offset(1); - } - } else if (*(*http).sendit).kind as u32 == MIMEKIND_MULTIPART as i32 as u32 { - cthdr = b"multipart/form-data\0" as *const u8 as *const libc::c_char; - } - curl_mime_headers((*http).sendit, (*data).set.headers, 0 as i32); - // 好像这里其实可以不要条件编译 - match () { - #[cfg(any( - all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), - not(CURL_DISABLE_SMTP), - not(CURL_DISABLE_IMAP) - ))] - _ => { - result = Curl_mime_prepare_headers( - (*http).sendit, - cthdr, - 0 as *const libc::c_char, - MIMESTRATEGY_FORM, - ); - } - _ => { - result = CURLE_NOT_BUILT_IN; - } - } - // result = Curl_mime_prepare_headers( - // (*http).sendit, - // cthdr, - // 0 as *const libc::c_char, - // MIMESTRATEGY_FORM, - // ); - curl_mime_headers((*http).sendit, 0 as *mut curl_slist, 0 as i32); - if result as u64 == 0 { - result = Curl_mime_rewind((*http).sendit); + (*http).postsize = Curl_mime_size((*http).sendit); } - if result as u64 != 0 { - return result; - } - (*http).postsize = Curl_mime_size((*http).sendit); - } - ptr = Curl_checkheaders( - data, - b"Transfer-Encoding\0" as *const u8 as *const libc::c_char, - ); - if !ptr.is_null() { - /* Some kind of TE is requested, check if 'chunked' is chosen */ - (*data).req.set_upload_chunky(Curl_compareheader( - ptr, - b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, - b"chunked\0" as *const u8 as *const libc::c_char, - ) as bit); - } else { - if (*(*conn).handler).protocol & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32) as u32 - != 0 - && ((httpreq as u32 == HTTPREQ_POST_MIME as i32 as u32 - || httpreq as u32 == HTTPREQ_POST_FORM as i32 as u32) - && (*http).postsize < 0 as i32 as i64 - || (((*data).set).upload() as i32 != 0 - || httpreq as u32 == HTTPREQ_POST as i32 as u32) - && (*data).state.infilesize == -(1 as i32) as i64) - { - if !(((*conn).bits).authneg() != 0) { - if Curl_use_http_1_1plus(data, conn) { - if ((*conn).httpversion as i32) < 20 { - (*data).req.set_upload_chunky(1 as bit); + ptr = Curl_checkheaders( + data, + b"Transfer-Encoding\0" as *const u8 as *const libc::c_char, + ); + if !ptr.is_null() { + /* Some kind of TE is requested, check if 'chunked' is chosen */ + (*data).req.set_upload_chunky(Curl_compareheader( + ptr, + b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, + b"chunked\0" as *const u8 as *const libc::c_char, + ) as bit); + } else { + if (*(*conn).handler).protocol + & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32) as u32 + != 0 + && ((httpreq as u32 == HTTPREQ_POST_MIME as i32 as u32 + || httpreq as u32 == HTTPREQ_POST_FORM as i32 as u32) + && (*http).postsize < 0 as i32 as i64 + || (((*data).set).upload() as i32 != 0 + || httpreq as u32 == HTTPREQ_POST as i32 as u32) + && (*data).state.infilesize == -(1 as i32) as i64) + { + if !(((*conn).bits).authneg() != 0) { + if Curl_use_http_1_1plus(data, conn) { + if ((*conn).httpversion as i32) < 20 { + (*data).req.set_upload_chunky(1 as bit); + } + } else { + Curl_failf( + data, + b"Chunky upload is not supported by HTTP 1.0\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_UPLOAD_FAILED; } - } else { - Curl_failf( - data, - b"Chunky upload is not supported by HTTP 1.0\0" as *const u8 - as *const libc::c_char, - ); - return CURLE_UPLOAD_FAILED; } + } else { + (*data).req.set_upload_chunky(0 as i32 as bit); + } + if ((*data).req).upload_chunky() != 0 { + *tep = b"Transfer-Encoding: chunked\r\n\0" as *const u8 as *const libc::c_char; } - } else { - (*data).req.set_upload_chunky(0 as i32 as bit); - } - if ((*data).req).upload_chunky() != 0 { - *tep = b"Transfer-Encoding: chunked\r\n\0" as *const u8 as *const libc::c_char; } + return result; } - return result; -} } #[no_mangle] @@ -3714,100 +3831,292 @@ pub extern "C" fn Curl_http_bodysend( #[cfg(not(USE_HYPER))] let mut included_body: curl_off_t = 0 as i32 as curl_off_t; let mut result: CURLcode = CURLE_OK; - let mut http: *mut HTTP =unsafe{ (*data).req.p.http}; + let mut http: *mut HTTP = unsafe { (*data).req.p.http }; let mut ptr: *const libc::c_char = 0 as *const libc::c_char; /* If 'authdone' is FALSE, we must not set the write socket index to the Curl_transfer() call below, as we're not ready to actually upload any data yet. */ - unsafe{ - match httpreq as u32 { - HTTPREQ_PUT => { - /* Let's PUT the data to the server! */ - if ((*conn).bits).authneg() != 0 { - (*http).postsize = 0 as curl_off_t; - } else { - (*http).postsize = (*data).state.infilesize; - } - if (*http).postsize != -1 as i64 - && ((*data).req).upload_chunky() == 0 - && (((*conn).bits).authneg() as i32 != 0 - || (Curl_checkheaders( - data, - b"Content-Length\0" as *const u8 as *const libc::c_char, - )) - .is_null()) - { - /* only add Content-Length if not uploading chunked */ - result = Curl_dyn_addf( - r, - b"Content-Length: %ld\r\n\0" as *const u8 as *const libc::c_char, - (*http).postsize, - ); - if result as u64 != 0 { - return result; + unsafe { + match httpreq as u32 { + HTTPREQ_PUT => { + /* Let's PUT the data to the server! */ + if ((*conn).bits).authneg() != 0 { + (*http).postsize = 0 as curl_off_t; + } else { + (*http).postsize = (*data).state.infilesize; } - } - if (*http).postsize != 0 { - result = expect100(data, conn, r); - if result as u64 != 0 { - return result; + if (*http).postsize != -1 as i64 + && ((*data).req).upload_chunky() == 0 + && (((*conn).bits).authneg() as i32 != 0 + || (Curl_checkheaders( + data, + b"Content-Length\0" as *const u8 as *const libc::c_char, + )) + .is_null()) + { + /* only add Content-Length if not uploading chunked */ + result = Curl_dyn_addf( + r, + b"Content-Length: %ld\r\n\0" as *const u8 as *const libc::c_char, + (*http).postsize, + ); + if result as u64 != 0 { + return result; + } } - } - result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - if result as u64 != 0 { - return result; - } - /* set the upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, (*http).postsize); - - /* this sends the buffer and frees all the buffer resources */ - result = Curl_buffer_send(r, data, &mut (*data).info.request_size, 0 as curl_off_t, 0); - /* this sends the buffer and frees all the buffer resources */ - if result as u64 != 0 { - Curl_failf( - data, - b"Failed sending PUT request\0" as *const u8 as *const libc::c_char, - ); - } else { - /* prepare for transfer */ - Curl_setup_transfer( - data, - 0, - -1 as curl_off_t, - true, - if (*http).postsize != 0 { 0 } else { -1 }, - ); - } - if result as u64 != 0 { - return result; - } - } - HTTPREQ_POST_FORM | HTTPREQ_POST_MIME => { - /* This is form posting using mime data. */ - if ((*conn).bits).authneg() != 0 { - /* nothing to post! */ - result = Curl_dyn_add( - r, - b"Content-Length: 0\r\n\r\n\0" as *const u8 as *const libc::c_char, - ); - + if (*http).postsize != 0 { + result = expect100(data, conn, r); + if result as u64 != 0 { + return result; + } + } + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); if result as u64 != 0 { return result; } + /* set the upload size to the progress meter */ + Curl_pgrsSetUploadSize(data, (*http).postsize); + /* this sends the buffer and frees all the buffer resources */ result = Curl_buffer_send(r, data, &mut (*data).info.request_size, 0 as curl_off_t, 0); + /* this sends the buffer and frees all the buffer resources */ if result as u64 != 0 { Curl_failf( data, - b"Failed sending POST request\0" as *const u8 as *const libc::c_char, + b"Failed sending PUT request\0" as *const u8 as *const libc::c_char, ); } else { - Curl_setup_transfer(data, 0, -1 as curl_off_t, true, -1); + /* prepare for transfer */ + Curl_setup_transfer( + data, + 0, + -1 as curl_off_t, + true, + if (*http).postsize != 0 { 0 } else { -1 }, + ); + } + if result as u64 != 0 { + return result; + } + } + HTTPREQ_POST_FORM | HTTPREQ_POST_MIME => { + /* This is form posting using mime data. */ + if ((*conn).bits).authneg() != 0 { + /* nothing to post! */ + result = Curl_dyn_add( + r, + b"Content-Length: 0\r\n\r\n\0" as *const u8 as *const libc::c_char, + ); + + if result as u64 != 0 { + return result; + } + + result = Curl_buffer_send( + r, + data, + &mut (*data).info.request_size, + 0 as curl_off_t, + 0, + ); + if result as u64 != 0 { + Curl_failf( + data, + b"Failed sending POST request\0" as *const u8 as *const libc::c_char, + ); + } else { + Curl_setup_transfer(data, 0, -1 as curl_off_t, true, -1); + } + } else { + (*data).state.infilesize = (*http).postsize; + + /* We only set Content-Length and allow a custom Content-Length if + we don't upload data chunked, as RFC2616 forbids us to set both + kinds of headers (Transfer-Encoding: chunked and Content-Length) */ + if (*http).postsize != -1 as i64 + && ((*data).req).upload_chunky() == 0 + && (((*conn).bits).authneg() as i32 != 0 + || (Curl_checkheaders( + data, + b"Content-Length\0" as *const u8 as *const libc::c_char, + )) + .is_null()) + { + /* we allow replacing this header if not during auth negotiation, + although it isn't very wise to actually set your own */ + result = Curl_dyn_addf( + r, + b"Content-Length: %ld\r\n\0" as *const u8 as *const libc::c_char, + (*http).postsize, + ); + if result as u64 != 0 { + return result; + } + } + // TODO 测试过了就把注释删咯 + if cfg!(not(CURL_DISABLE_MIME)) { + let mut hdr: *mut curl_slist = 0 as *mut curl_slist; + hdr = (*(*http).sendit).curlheaders; + while !hdr.is_null() { + result = Curl_dyn_addf( + r, + b"%s\r\n\0" as *const u8 as *const libc::c_char, + (*hdr).data, + ); + if result as u64 != 0 { + return result; + } + hdr = (*hdr).next; + } + } + // #[cfg(not(CURL_DISABLE_MIME))] + // let mut hdr: *mut curl_slist = 0 as *mut curl_slist; + // #[cfg(not(CURL_DISABLE_MIME))] + // hdr = (*(*http).sendit).curlheaders; + // #[cfg(not(CURL_DISABLE_MIME))] + // while !hdr.is_null() { + // result = Curl_dyn_addf( + // r, + // b"%s\r\n\0" as *const u8 as *const libc::c_char, + // (*hdr).data, + // ); + // if result as u64 != 0 { + // return result; + // } + // hdr = (*hdr).next; + // } + /* For really small posts we don't use Expect: headers at all, and for + the somewhat bigger ones we allow the app to disable it. Just make + sure that the expect100header is always set to the preferred value + here. */ + + ptr = Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char); + if !ptr.is_null() { + (*data).state.set_expect100header(Curl_compareheader( + ptr, + b"Expect:\0" as *const u8 as *const libc::c_char, + b"100-continue\0" as *const u8 as *const libc::c_char, + ) as bit); + } else if (*http).postsize > EXPECT_100_THRESHOLD || (*http).postsize < 0 as i64 + { + /* make the request end in a true CRLF */ + result = expect100(data, conn, r); + if result as u64 != 0 { + return result; + } + } else { + (*data).state.set_expect100header(0 as bit); + } + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); + if result as u64 != 0 { + return result; + } + + /* set the upload size to the progress meter */ + Curl_pgrsSetUploadSize(data, (*http).postsize); + let ref mut fresh51 = (*data).state.fread_func; + // TODO 这里也有条件编译 + match () { + #[cfg(any( + all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), + not(CURL_DISABLE_SMTP), + not(CURL_DISABLE_IMAP) + ))] + _ => { + *fresh51 = ::std::mem::transmute::< + Option< + unsafe extern "C" fn( + *mut libc::c_char, + size_t, + size_t, + *mut libc::c_void, + ) + -> size_t, + >, + curl_read_callback, + >(Some( + Curl_mime_read + as unsafe extern "C" fn( + *mut libc::c_char, + size_t, + size_t, + *mut libc::c_void, + ) + -> size_t, + )); + } + _ => { + // TODO + } + } + // *fresh51 = ::std::mem::transmute::< + // Option< + // unsafe extern "C" fn( + // *mut libc::c_char, + // size_t, + // size_t, + // *mut libc::c_void, + // ) -> size_t, + // >, + // curl_read_callback, + // >(Some( + // Curl_mime_read + // as unsafe extern "C" fn( + // *mut libc::c_char, + // size_t, + // size_t, + // *mut libc::c_void, + // ) -> size_t, + // )); + + /* Read from mime structure. */ + (*data).state.in_0 = (*http).sendit as *mut libc::c_void; + (*http).sending = HTTPSEND_BODY; + + /* this sends the buffer and frees all the buffer resources */ + result = Curl_buffer_send( + r, + data, + &mut (*data).info.request_size, + 0 as curl_off_t, + 0, + ); + + if result as u64 != 0 { + Curl_failf( + data, + b"Failed sending POST request\0" as *const u8 as *const libc::c_char, + ); + } else { + /* prepare for transfer */ + Curl_setup_transfer( + data, + FIRSTSOCKET, + -1 as curl_off_t, + true, + if (*http).postsize != 0 { + FIRSTSOCKET + } else { + -1 + }, + ); + } + if result as u64 != 0 { + return result; + } + } + } + HTTPREQ_POST => { + /* this is the simple POST, using x-www-form-urlencoded style */ + + if ((*conn).bits).authneg() != 0 { + (*http).postsize = 0 as curl_off_t; + } else { + /* the size of the post body */ + (*http).postsize = (*data).state.infilesize; } - } else { - (*data).state.infilesize = (*http).postsize; /* We only set Content-Length and allow a custom Content-Length if we don't upload data chunked, as RFC2616 forbids us to set both @@ -3832,43 +4141,23 @@ pub extern "C" fn Curl_http_bodysend( return result; } } - // TODO 测试过了就把注释删咯 - if cfg!(not(CURL_DISABLE_MIME)) { - let mut hdr: *mut curl_slist = 0 as *mut curl_slist; - hdr = (*(*http).sendit).curlheaders; - while !hdr.is_null() { - result = Curl_dyn_addf( - r, - b"%s\r\n\0" as *const u8 as *const libc::c_char, - (*hdr).data, - ); - if result as u64 != 0 { - return result; - } - hdr = (*hdr).next; + if (Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char)) + .is_null() + { + result = Curl_dyn_add( + r, + b"Content-Type: application/x-www-form-urlencoded\r\n\0" as *const u8 + as *const libc::c_char, + ); + if result as u64 != 0 { + return result; } } - // #[cfg(not(CURL_DISABLE_MIME))] - // let mut hdr: *mut curl_slist = 0 as *mut curl_slist; - // #[cfg(not(CURL_DISABLE_MIME))] - // hdr = (*(*http).sendit).curlheaders; - // #[cfg(not(CURL_DISABLE_MIME))] - // while !hdr.is_null() { - // result = Curl_dyn_addf( - // r, - // b"%s\r\n\0" as *const u8 as *const libc::c_char, - // (*hdr).data, - // ); - // if result as u64 != 0 { - // return result; - // } - // hdr = (*hdr).next; - // } + /* For really small posts we don't use Expect: headers at all, and for the somewhat bigger ones we allow the app to disable it. Just make sure that the expect100header is always set to the preferred value here. */ - ptr = Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char); if !ptr.is_null() { (*data).state.set_expect100header(Curl_compareheader( @@ -3877,7 +4166,6 @@ pub extern "C" fn Curl_http_bodysend( b"100-continue\0" as *const u8 as *const libc::c_char, ) as bit); } else if (*http).postsize > EXPECT_100_THRESHOLD || (*http).postsize < 0 as i64 { - /* make the request end in a true CRLF */ result = expect100(data, conn, r); if result as u64 != 0 { return result; @@ -3885,23 +4173,75 @@ pub extern "C" fn Curl_http_bodysend( } else { (*data).state.set_expect100header(0 as bit); } - result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - if result as u64 != 0 { - return result; - } - - /* set the upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, (*http).postsize); - let ref mut fresh51 = (*data).state.fread_func; - // TODO 这里也有条件编译 - match () { - #[cfg(any( - all(not(CURL_DISABLE_HTTP), not(CURL_DISABLE_MIME)), - not(CURL_DISABLE_SMTP), - not(CURL_DISABLE_IMAP) - ))] - _ => { - *fresh51 = ::std::mem::transmute::< + // TODO 测试通过了就把match删咯 + let flag: bool = if cfg!(not(USE_HYPER)) { + !((*data).set.postfields).is_null() + } else { + false + }; + if flag { + if (*conn).httpversion as i32 != 20 + && ((*data).state).expect100header() == 0 + && (*http).postsize < (64 * 1024) as i64 + { + /* make the request end in a true CRLF */ + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); + if result as u64 != 0 { + return result; + } + if ((*data).req).upload_chunky() == 0 { + result = Curl_dyn_addn( + r, + (*data).set.postfields, + (*http).postsize as size_t, + ); + included_body = (*http).postsize; + } else { + if (*http).postsize != 0 { + let mut chunk: [libc::c_char; 16] = [0; 16]; + curl_msnprintf( + chunk.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 16]>() as u64, + b"%x\r\n\0" as *const u8 as *const libc::c_char, + (*http).postsize as i32, + ); + result = Curl_dyn_add(r, chunk.as_mut_ptr()); + if result as u64 == 0 { + included_body = ((*http).postsize as u64) + .wrapping_add(strlen(chunk.as_mut_ptr())) + as curl_off_t; + result = Curl_dyn_addn( + r, + (*data).set.postfields, + (*http).postsize as size_t, + ); + if result as u64 == 0 { + result = Curl_dyn_add( + r, + b"\r\n\0" as *const u8 as *const libc::c_char, + ); + } + included_body += 2 as i32 as i64; + } + } + if result as u64 == 0 { + result = Curl_dyn_add( + r, + b"0\r\n\r\n\0" as *const u8 as *const libc::c_char, + ); + included_body += 5 as i32 as i64; + } + } + if result as u64 != 0 { + return result; + } + + /* set the upload size to the progress meter */ + Curl_pgrsSetUploadSize(data, (*http).postsize); + } else { + (*http).postdata = (*data).set.postfields as *const libc::c_char; + (*http).sending = HTTPSEND_BODY; + (*data).state.fread_func = ::std::mem::transmute::< Option< unsafe extern "C" fn( *mut libc::c_char, @@ -3912,7 +4252,7 @@ pub extern "C" fn Curl_http_bodysend( >, curl_read_callback, >(Some( - Curl_mime_read + readmoredata as unsafe extern "C" fn( *mut libc::c_char, size_t, @@ -3920,433 +4260,232 @@ pub extern "C" fn Curl_http_bodysend( *mut libc::c_void, ) -> size_t, )); + (*data).state.in_0 = data as *mut libc::c_void; + Curl_pgrsSetUploadSize(data, (*http).postsize); + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); + if result as u64 != 0 { + return result; + } } - _ => { - // TODO + } else { + /* make the request end in a true CRLF */ + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); + if result as u64 != 0 { + return result; + } + if ((*data).req).upload_chunky() as i32 != 0 + && ((*conn).bits).authneg() as i32 != 0 + { + result = Curl_dyn_add( + r, + b"0\r\n\r\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + if result as u64 != 0 { + return result; + } + } else if (*data).state.infilesize != 0 { + Curl_pgrsSetUploadSize( + data, + if (*http).postsize != 0 { + (*http).postsize + } else { + -1 as i64 + }, + ); + if ((*conn).bits).authneg() == 0 { + (*http).postdata = &mut (*http).postdata as *mut *const libc::c_char + as *mut libc::c_char; + } } } - // *fresh51 = ::std::mem::transmute::< - // Option< - // unsafe extern "C" fn( - // *mut libc::c_char, - // size_t, - // size_t, - // *mut libc::c_void, - // ) -> size_t, - // >, - // curl_read_callback, - // >(Some( - // Curl_mime_read - // as unsafe extern "C" fn( - // *mut libc::c_char, - // size_t, - // size_t, - // *mut libc::c_void, - // ) -> size_t, - // )); - - /* Read from mime structure. */ - (*data).state.in_0 = (*http).sendit as *mut libc::c_void; - (*http).sending = HTTPSEND_BODY; + // match () { + // #[cfg(not(USE_HYPER))] + // _ => { + // if !((*data).set.postfields).is_null() { + // if (*conn).httpversion as i32 != 20 as i32 + // && ((*data).state).expect100header() == 0 + // && (*http).postsize < (64 as i32 * 1024 as i32) as i64 + // { + // result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); + // if result as u64 != 0 { + // return result; + // } + // if ((*data).req).upload_chunky() == 0 { + // result = + // Curl_dyn_addn(r, (*data).set.postfields, (*http).postsize as size_t); + // included_body = (*http).postsize; + // } else { + // if (*http).postsize != 0 { + // let mut chunk: [libc::c_char; 16] = [0; 16]; + // curl_msnprintf( + // chunk.as_mut_ptr(), + // ::std::mem::size_of::<[libc::c_char; 16]>() as u64, + // b"%x\r\n\0" as *const u8 as *const libc::c_char, + // (*http).postsize as i32, + // ); + // result = Curl_dyn_add(r, chunk.as_mut_ptr()); + // if result as u64 == 0 { + // included_body = ((*http).postsize as u64) + // .wrapping_add(strlen(chunk.as_mut_ptr())) + // as curl_off_t; + // result = Curl_dyn_addn( + // r, + // (*data).set.postfields, + // (*http).postsize as size_t, + // ); + // if result as u64 == 0 { + // result = Curl_dyn_add( + // r, + // b"\r\n\0" as *const u8 as *const libc::c_char, + // ); + // } + // included_body += 2 as i32 as i64; + // } + // } + // if result as u64 == 0 { + // result = + // Curl_dyn_add(r, b"0\r\n\r\n\0" as *const u8 as *const libc::c_char); + // included_body += 5 as i32 as i64; + // } + // } + // if result as u64 != 0 { + // return result; + // } + // Curl_pgrsSetUploadSize(data, (*http).postsize); + // } else { + // let ref mut fresh55 = (*http).postdata; + // *fresh55 = (*data).set.postfields as *const libc::c_char; + // (*http).sending = HTTPSEND_BODY; + // let ref mut fresh56 = (*data).state.fread_func; + // *fresh56 = ::std::mem::transmute::< + // Option< + // unsafe extern "C" fn( + // *mut libc::c_char, + // size_t, + // size_t, + // *mut libc::c_void, + // ) -> size_t, + // >, + // curl_read_callback, + // >(Some( + // readmoredata + // as unsafe extern "C" fn( + // *mut libc::c_char, + // size_t, + // size_t, + // *mut libc::c_void, + // ) -> size_t, + // )); + // let ref mut fresh57 = (*data).state.in_0; + // *fresh57 = data as *mut libc::c_void; + // Curl_pgrsSetUploadSize(data, (*http).postsize); + // result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); + // if result as u64 != 0 { + // return result; + // } + // } + // } else { + // result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); + // if result as u64 != 0 { + // return result; + // } + // if ((*data).req).upload_chunky() as i32 != 0 + // && ((*conn).bits).authneg() as i32 != 0 + // { + // result = Curl_dyn_add( + // r, + // b"0\r\n\r\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + // ); + // if result as u64 != 0 { + // return result; + // } + // } else if (*data).state.infilesize != 0 { + // Curl_pgrsSetUploadSize( + // data, + // if (*http).postsize != 0 { + // (*http).postsize + // } else { + // -(1 as i32) as i64 + // }, + // ); + // if ((*conn).bits).authneg() == 0 { + // let ref mut fresh58 = (*http).postdata; + // *fresh58 = + // &mut (*http).postdata as *mut *const libc::c_char as *mut libc::c_char; + // } + // } + // } + // } + // #[cfg(USE_HYPER)] + // _ => { + // result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); + // if result as u64 != 0 { + // return result; + // } + // if ((*data).req).upload_chunky() as i32 != 0 + // && ((*conn).bits).authneg() as i32 != 0 + // { + // result = Curl_dyn_add( + // r, + // b"0\r\n\r\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + // ); + // if result as u64 != 0 { + // return result; + // } + // } else if (*data).state.infilesize != 0 { + // Curl_pgrsSetUploadSize( + // data, + // if (*http).postsize != 0 { + // (*http).postsize + // } else { + // -(1 as i32) as i64 + // }, + // ); + // if ((*conn).bits).authneg() == 0 { + // let ref mut fresh58 = (*http).postdata; + // *fresh58 = + // &mut (*http).postdata as *mut *const libc::c_char as *mut libc::c_char; + // } + // } + // } + // } /* this sends the buffer and frees all the buffer resources */ result = - Curl_buffer_send(r, data, &mut (*data).info.request_size, 0 as curl_off_t, 0); - + Curl_buffer_send(r, data, &mut (*data).info.request_size, included_body, 0); if result as u64 != 0 { Curl_failf( data, - b"Failed sending POST request\0" as *const u8 as *const libc::c_char, + b"Failed sending HTTP POST request\0" as *const u8 as *const libc::c_char, ); } else { - /* prepare for transfer */ Curl_setup_transfer( data, - FIRSTSOCKET, + 0, -1 as curl_off_t, true, - if (*http).postsize != 0 { - FIRSTSOCKET - } else { - -1 - }, + if !((*http).postdata).is_null() { 0 } else { -1 }, ); } - if result as u64 != 0 { - return result; - } - } - } - HTTPREQ_POST => { - /* this is the simple POST, using x-www-form-urlencoded style */ - - if ((*conn).bits).authneg() != 0 { - (*http).postsize = 0 as curl_off_t; - } else { - /* the size of the post body */ - (*http).postsize = (*data).state.infilesize; - } - - /* We only set Content-Length and allow a custom Content-Length if - we don't upload data chunked, as RFC2616 forbids us to set both - kinds of headers (Transfer-Encoding: chunked and Content-Length) */ - if (*http).postsize != -1 as i64 - && ((*data).req).upload_chunky() == 0 - && (((*conn).bits).authneg() as i32 != 0 - || (Curl_checkheaders( - data, - b"Content-Length\0" as *const u8 as *const libc::c_char, - )) - .is_null()) - { - /* we allow replacing this header if not during auth negotiation, - although it isn't very wise to actually set your own */ - result = Curl_dyn_addf( - r, - b"Content-Length: %ld\r\n\0" as *const u8 as *const libc::c_char, - (*http).postsize, - ); - if result as u64 != 0 { - return result; - } - } - if (Curl_checkheaders(data, b"Content-Type\0" as *const u8 as *const libc::c_char)) - .is_null() - { - result = Curl_dyn_add( - r, - b"Content-Type: application/x-www-form-urlencoded\r\n\0" as *const u8 - as *const libc::c_char, - ); - if result as u64 != 0 { - return result; - } - } - - /* For really small posts we don't use Expect: headers at all, and for - the somewhat bigger ones we allow the app to disable it. Just make - sure that the expect100header is always set to the preferred value - here. */ - ptr = Curl_checkheaders(data, b"Expect\0" as *const u8 as *const libc::c_char); - if !ptr.is_null() { - (*data).state.set_expect100header(Curl_compareheader( - ptr, - b"Expect:\0" as *const u8 as *const libc::c_char, - b"100-continue\0" as *const u8 as *const libc::c_char, - ) as bit); - } else if (*http).postsize > EXPECT_100_THRESHOLD || (*http).postsize < 0 as i64 { - result = expect100(data, conn, r); - if result as u64 != 0 { - return result; - } - } else { - (*data).state.set_expect100header(0 as bit); } - // TODO 测试通过了就把match删咯 - let flag: bool = if cfg!(not(USE_HYPER)) { - !((*data).set.postfields).is_null() - } else { - false - }; - if flag { - if (*conn).httpversion as i32 != 20 - && ((*data).state).expect100header() == 0 - && (*http).postsize < (64 * 1024) as i64 - { - /* make the request end in a true CRLF */ - result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - if result as u64 != 0 { - return result; - } - if ((*data).req).upload_chunky() == 0 { - result = - Curl_dyn_addn(r, (*data).set.postfields, (*http).postsize as size_t); - included_body = (*http).postsize; - } else { - if (*http).postsize != 0 { - let mut chunk: [libc::c_char; 16] = [0; 16]; - curl_msnprintf( - chunk.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 16]>() as u64, - b"%x\r\n\0" as *const u8 as *const libc::c_char, - (*http).postsize as i32, - ); - result = Curl_dyn_add(r, chunk.as_mut_ptr()); - if result as u64 == 0 { - included_body = ((*http).postsize as u64) - .wrapping_add(strlen(chunk.as_mut_ptr())) - as curl_off_t; - result = Curl_dyn_addn( - r, - (*data).set.postfields, - (*http).postsize as size_t, - ); - if result as u64 == 0 { - result = Curl_dyn_add( - r, - b"\r\n\0" as *const u8 as *const libc::c_char, - ); - } - included_body += 2 as i32 as i64; - } - } - if result as u64 == 0 { - result = - Curl_dyn_add(r, b"0\r\n\r\n\0" as *const u8 as *const libc::c_char); - included_body += 5 as i32 as i64; - } - } - if result as u64 != 0 { - return result; - } - - /* set the upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, (*http).postsize); - } else { - (*http).postdata = (*data).set.postfields as *const libc::c_char; - (*http).sending = HTTPSEND_BODY; - (*data).state.fread_func = ::std::mem::transmute::< - Option< - unsafe extern "C" fn( - *mut libc::c_char, - size_t, - size_t, - *mut libc::c_void, - ) -> size_t, - >, - curl_read_callback, - >(Some( - readmoredata - as unsafe extern "C" fn( - *mut libc::c_char, - size_t, - size_t, - *mut libc::c_void, - ) -> size_t, - )); - (*data).state.in_0 = data as *mut libc::c_void; - Curl_pgrsSetUploadSize(data, (*http).postsize); - result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - if result as u64 != 0 { - return result; - } - } - } else { - /* make the request end in a true CRLF */ + _ => { result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); if result as u64 != 0 { return result; } - if ((*data).req).upload_chunky() as i32 != 0 && ((*conn).bits).authneg() as i32 != 0 - { - result = Curl_dyn_add( - r, - b"0\r\n\r\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, - ); - if result as u64 != 0 { - return result; - } - } else if (*data).state.infilesize != 0 { - Curl_pgrsSetUploadSize( + result = + Curl_buffer_send(r, data, &mut (*data).info.request_size, 0 as curl_off_t, 0); + if result as u64 != 0 { + Curl_failf( data, - if (*http).postsize != 0 { - (*http).postsize - } else { - -1 as i64 - }, + b"Failed sending HTTP request\0" as *const u8 as *const libc::c_char, ); - if ((*conn).bits).authneg() == 0 { - (*http).postdata = - &mut (*http).postdata as *mut *const libc::c_char as *mut libc::c_char; - } + } else { + Curl_setup_transfer(data, 0, -1 as curl_off_t, true, -1); } } - // match () { - // #[cfg(not(USE_HYPER))] - // _ => { - // if !((*data).set.postfields).is_null() { - // if (*conn).httpversion as i32 != 20 as i32 - // && ((*data).state).expect100header() == 0 - // && (*http).postsize < (64 as i32 * 1024 as i32) as i64 - // { - // result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - // if result as u64 != 0 { - // return result; - // } - // if ((*data).req).upload_chunky() == 0 { - // result = - // Curl_dyn_addn(r, (*data).set.postfields, (*http).postsize as size_t); - // included_body = (*http).postsize; - // } else { - // if (*http).postsize != 0 { - // let mut chunk: [libc::c_char; 16] = [0; 16]; - // curl_msnprintf( - // chunk.as_mut_ptr(), - // ::std::mem::size_of::<[libc::c_char; 16]>() as u64, - // b"%x\r\n\0" as *const u8 as *const libc::c_char, - // (*http).postsize as i32, - // ); - // result = Curl_dyn_add(r, chunk.as_mut_ptr()); - // if result as u64 == 0 { - // included_body = ((*http).postsize as u64) - // .wrapping_add(strlen(chunk.as_mut_ptr())) - // as curl_off_t; - // result = Curl_dyn_addn( - // r, - // (*data).set.postfields, - // (*http).postsize as size_t, - // ); - // if result as u64 == 0 { - // result = Curl_dyn_add( - // r, - // b"\r\n\0" as *const u8 as *const libc::c_char, - // ); - // } - // included_body += 2 as i32 as i64; - // } - // } - // if result as u64 == 0 { - // result = - // Curl_dyn_add(r, b"0\r\n\r\n\0" as *const u8 as *const libc::c_char); - // included_body += 5 as i32 as i64; - // } - // } - // if result as u64 != 0 { - // return result; - // } - // Curl_pgrsSetUploadSize(data, (*http).postsize); - // } else { - // let ref mut fresh55 = (*http).postdata; - // *fresh55 = (*data).set.postfields as *const libc::c_char; - // (*http).sending = HTTPSEND_BODY; - // let ref mut fresh56 = (*data).state.fread_func; - // *fresh56 = ::std::mem::transmute::< - // Option< - // unsafe extern "C" fn( - // *mut libc::c_char, - // size_t, - // size_t, - // *mut libc::c_void, - // ) -> size_t, - // >, - // curl_read_callback, - // >(Some( - // readmoredata - // as unsafe extern "C" fn( - // *mut libc::c_char, - // size_t, - // size_t, - // *mut libc::c_void, - // ) -> size_t, - // )); - // let ref mut fresh57 = (*data).state.in_0; - // *fresh57 = data as *mut libc::c_void; - // Curl_pgrsSetUploadSize(data, (*http).postsize); - // result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - // if result as u64 != 0 { - // return result; - // } - // } - // } else { - // result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - // if result as u64 != 0 { - // return result; - // } - // if ((*data).req).upload_chunky() as i32 != 0 - // && ((*conn).bits).authneg() as i32 != 0 - // { - // result = Curl_dyn_add( - // r, - // b"0\r\n\r\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, - // ); - // if result as u64 != 0 { - // return result; - // } - // } else if (*data).state.infilesize != 0 { - // Curl_pgrsSetUploadSize( - // data, - // if (*http).postsize != 0 { - // (*http).postsize - // } else { - // -(1 as i32) as i64 - // }, - // ); - // if ((*conn).bits).authneg() == 0 { - // let ref mut fresh58 = (*http).postdata; - // *fresh58 = - // &mut (*http).postdata as *mut *const libc::c_char as *mut libc::c_char; - // } - // } - // } - // } - // #[cfg(USE_HYPER)] - // _ => { - // result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - // if result as u64 != 0 { - // return result; - // } - // if ((*data).req).upload_chunky() as i32 != 0 - // && ((*conn).bits).authneg() as i32 != 0 - // { - // result = Curl_dyn_add( - // r, - // b"0\r\n\r\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, - // ); - // if result as u64 != 0 { - // return result; - // } - // } else if (*data).state.infilesize != 0 { - // Curl_pgrsSetUploadSize( - // data, - // if (*http).postsize != 0 { - // (*http).postsize - // } else { - // -(1 as i32) as i64 - // }, - // ); - // if ((*conn).bits).authneg() == 0 { - // let ref mut fresh58 = (*http).postdata; - // *fresh58 = - // &mut (*http).postdata as *mut *const libc::c_char as *mut libc::c_char; - // } - // } - // } - // } - - /* this sends the buffer and frees all the buffer resources */ - result = Curl_buffer_send(r, data, &mut (*data).info.request_size, included_body, 0); - if result as u64 != 0 { - Curl_failf( - data, - b"Failed sending HTTP POST request\0" as *const u8 as *const libc::c_char, - ); - } else { - Curl_setup_transfer( - data, - 0, - -1 as curl_off_t, - true, - if !((*http).postdata).is_null() { 0 } else { -1 }, - ); - } - } - _ => { - result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - if result as u64 != 0 { - return result; - } - result = Curl_buffer_send(r, data, &mut (*data).info.request_size, 0 as curl_off_t, 0); - if result as u64 != 0 { - Curl_failf( - data, - b"Failed sending HTTP request\0" as *const u8 as *const libc::c_char, - ); - } else { - Curl_setup_transfer(data, 0, -1 as curl_off_t, true, -1); - } } } -} return result; } @@ -4359,23 +4498,25 @@ pub extern "C" fn Curl_http_cookies( ) -> CURLcode { let mut result: CURLcode = CURLE_OK; let mut addcookies: *mut libc::c_char = 0 as *mut libc::c_char; - if unsafe{!((*data).set.str_0[STRING_COOKIE as i32 as usize]).is_null() - && (Curl_checkheaders(data, b"Cookie\0" as *const u8 as *const libc::c_char)).is_null()} - { - addcookies = unsafe{(*data).set.str_0[STRING_COOKIE as i32 as usize]}; + if unsafe { + !((*data).set.str_0[STRING_COOKIE as i32 as usize]).is_null() + && (Curl_checkheaders(data, b"Cookie\0" as *const u8 as *const libc::c_char)).is_null() + } { + addcookies = unsafe { (*data).set.str_0[STRING_COOKIE as i32 as usize] }; } - if unsafe{!((*data).cookies).is_null() || !addcookies.is_null()} { + if unsafe { !((*data).cookies).is_null() || !addcookies.is_null() } { let mut co: *mut Cookie = 0 as *mut Cookie; let mut count: i32 = 0 as i32; - if unsafe{!((*data).cookies).is_null() && ((*data).state).cookie_engine() as i32 != 0 }{ - unsafe{ - let mut host: *const libc::c_char = if !((*data).state.aptr.cookiehost).is_null() { - (*data).state.aptr.cookiehost - } else { - (*conn).host.name - }; - let secure_context: bool = - if (*(*conn).handler).protocol & ((1 as i32) << 1 as i32) as u32 != 0 + if unsafe { !((*data).cookies).is_null() && ((*data).state).cookie_engine() as i32 != 0 } { + unsafe { + let mut host: *const libc::c_char = if !((*data).state.aptr.cookiehost).is_null() { + (*data).state.aptr.cookiehost + } else { + (*conn).host.name + }; + let secure_context: bool = if (*(*conn).handler).protocol + & ((1 as i32) << 1 as i32) as u32 + != 0 || Curl_strcasecompare(b"localhost\0" as *const u8 as *const libc::c_char, host) != 0 || strcmp(host, b"127.0.0.1\0" as *const u8 as *const libc::c_char) == 0 @@ -4385,69 +4526,75 @@ pub extern "C" fn Curl_http_cookies( } else { 0 } != 0; - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - co = Curl_cookie_getlist((*data).cookies, host, (*data).state.up.path, secure_context); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + co = Curl_cookie_getlist( + (*data).cookies, + host, + (*data).state.up.path, + secure_context, + ); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); } } - unsafe{ - if !co.is_null() { - let mut store: *mut Cookie = co; - /* now loop through all cookies that matched */ - while !co.is_null() { - if !((*co).value).is_null() { - if 0 as i32 == count { - result = Curl_dyn_add(r, b"Cookie: \0" as *const u8 as *const libc::c_char); + unsafe { + if !co.is_null() { + let mut store: *mut Cookie = co; + /* now loop through all cookies that matched */ + while !co.is_null() { + if !((*co).value).is_null() { + if 0 as i32 == count { + result = + Curl_dyn_add(r, b"Cookie: \0" as *const u8 as *const libc::c_char); + if result as u64 != 0 { + break; + } + } + result = Curl_dyn_addf( + r, + b"%s%s=%s\0" as *const u8 as *const libc::c_char, + if count != 0 { + b"; \0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + (*co).name, + (*co).value, + ); + if result as u64 != 0 { break; } + count += 1; } + co = (*co).next; + } + Curl_cookie_freelist(store); + } + if !addcookies.is_null() && result as u64 == 0 { + if count == 0 { + result = Curl_dyn_add(r, b"Cookie: \0" as *const u8 as *const libc::c_char); + } + if result as u64 == 0 { result = Curl_dyn_addf( r, - b"%s%s=%s\0" as *const u8 as *const libc::c_char, + b"%s%s\0" as *const u8 as *const libc::c_char, if count != 0 { b"; \0" as *const u8 as *const libc::c_char } else { b"\0" as *const u8 as *const libc::c_char }, - (*co).name, - (*co).value, + addcookies, ); - - if result as u64 != 0 { - break; - } count += 1; } - co = (*co).next; } - Curl_cookie_freelist(store); - } - if !addcookies.is_null() && result as u64 == 0 { - if count == 0 { - result = Curl_dyn_add(r, b"Cookie: \0" as *const u8 as *const libc::c_char); + if count != 0 && result as u64 == 0 { + result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); } - if result as u64 == 0 { - result = Curl_dyn_addf( - r, - b"%s%s\0" as *const u8 as *const libc::c_char, - if count != 0 { - b"; \0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - addcookies, - ); - count += 1; + if result as u64 != 0 { + return result; } } - if count != 0 && result as u64 == 0 { - result = Curl_dyn_add(r, b"\r\n\0" as *const u8 as *const libc::c_char); - } - if result as u64 != 0 { - return result; - } - } } return result; } @@ -4458,77 +4605,77 @@ pub extern "C" fn Curl_http_cookies( mut conn: *mut connectdata, mut r: *mut dynbuf, ) -> CURLcode { - unsafe{ - return CURLE_OK;} + unsafe { + return CURLE_OK; + } } #[no_mangle] -pub extern "C" fn Curl_http_range( - mut data: *mut Curl_easy, - mut httpreq: Curl_HttpReq, -) -> CURLcode { - unsafe{ - if ((*data).state).use_range() != 0 { - if (httpreq as u32 == HTTPREQ_GET as i32 as u32 - || httpreq as u32 == HTTPREQ_HEAD as i32 as u32) - && (Curl_checkheaders(data, b"Range\0" as *const u8 as *const libc::c_char)).is_null() - { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.rangeline as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.rangeline as *mut libc::c_void, - 2776 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - (*data).state.aptr.rangeline = curl_maprintf( - b"Range: bytes=%s\r\n\0" as *const u8 as *const libc::c_char, - (*data).state.range, - ); - } else if (httpreq as u32 == HTTPREQ_POST as i32 as u32 - || httpreq as u32 == HTTPREQ_PUT as i32 as u32) - && (Curl_checkheaders(data, b"Content-Range\0" as *const u8 as *const libc::c_char)) - .is_null() - { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.rangeline as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.rangeline as *mut libc::c_void, - 2784 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - if (*data).set.set_resume_from < 0 as i32 as i64 { - (*data).state.aptr.rangeline = curl_maprintf( - b"Content-Range: bytes 0-%ld/%ld\r\n\0" as *const u8 as *const libc::c_char, - (*data).state.infilesize - 1 as i32 as i64, - (*data).state.infilesize, +pub extern "C" fn Curl_http_range(mut data: *mut Curl_easy, mut httpreq: Curl_HttpReq) -> CURLcode { + unsafe { + if ((*data).state).use_range() != 0 { + if (httpreq as u32 == HTTPREQ_GET as i32 as u32 + || httpreq as u32 == HTTPREQ_HEAD as i32 as u32) + && (Curl_checkheaders(data, b"Range\0" as *const u8 as *const libc::c_char)) + .is_null() + { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.rangeline as *mut libc::c_void, ); - } else if (*data).state.resume_from != 0 { - let mut total_expected_size: curl_off_t = - (*data).state.resume_from + (*data).state.infilesize; - (*data).state.aptr.rangeline = curl_maprintf( - b"Content-Range: bytes %s%ld/%ld\r\n\0" as *const u8 as *const libc::c_char, - (*data).state.range, - total_expected_size - 1 as i32 as i64, - total_expected_size, + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.rangeline as *mut libc::c_void, + 2776 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, ); - } else { (*data).state.aptr.rangeline = curl_maprintf( - b"Content-Range: bytes %s/%ld\r\n\0" as *const u8 as *const libc::c_char, + b"Range: bytes=%s\r\n\0" as *const u8 as *const libc::c_char, (*data).state.range, - (*data).state.infilesize, ); - } - if ((*data).state.aptr.rangeline).is_null() { - return CURLE_OUT_OF_MEMORY; + } else if (httpreq as u32 == HTTPREQ_POST as i32 as u32 + || httpreq as u32 == HTTPREQ_PUT as i32 as u32) + && (Curl_checkheaders(data, b"Content-Range\0" as *const u8 as *const libc::c_char)) + .is_null() + { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.rangeline as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.rangeline as *mut libc::c_void, + 2784 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + if (*data).set.set_resume_from < 0 as i32 as i64 { + (*data).state.aptr.rangeline = curl_maprintf( + b"Content-Range: bytes 0-%ld/%ld\r\n\0" as *const u8 as *const libc::c_char, + (*data).state.infilesize - 1 as i32 as i64, + (*data).state.infilesize, + ); + } else if (*data).state.resume_from != 0 { + let mut total_expected_size: curl_off_t = + (*data).state.resume_from + (*data).state.infilesize; + (*data).state.aptr.rangeline = curl_maprintf( + b"Content-Range: bytes %s%ld/%ld\r\n\0" as *const u8 as *const libc::c_char, + (*data).state.range, + total_expected_size - 1 as i32 as i64, + total_expected_size, + ); + } else { + (*data).state.aptr.rangeline = curl_maprintf( + b"Content-Range: bytes %s/%ld\r\n\0" as *const u8 as *const libc::c_char, + (*data).state.range, + (*data).state.infilesize, + ); + } + if ((*data).state.aptr.rangeline).is_null() { + return CURLE_OUT_OF_MEMORY; + } } } + return CURLE_OK; } - return CURLE_OK;} } #[no_mangle] pub extern "C" fn Curl_http_resume( @@ -4536,75 +4683,79 @@ pub extern "C" fn Curl_http_resume( mut conn: *mut connectdata, mut httpreq: Curl_HttpReq, ) -> CURLcode { - unsafe{ - if (HTTPREQ_POST as i32 as u32 == httpreq as u32 || HTTPREQ_PUT as i32 as u32 == httpreq as u32) - && (*data).state.resume_from != 0 - { - if (*data).state.resume_from < 0 as i32 as i64 { - (*data).state.resume_from = 0 as i32 as curl_off_t; - } - if (*data).state.resume_from != 0 && ((*data).state).this_is_a_follow() == 0 { - let mut seekerr: i32 = 2 as i32; - if ((*conn).seek_func).is_some() { - Curl_set_in_callback(data, 1 as i32 != 0); - seekerr = ((*conn).seek_func).expect("non-null function pointer")( - (*conn).seek_client, - (*data).state.resume_from, - 0 as i32, - ); - Curl_set_in_callback(data, 0 as i32 != 0); + unsafe { + if (HTTPREQ_POST as i32 as u32 == httpreq as u32 + || HTTPREQ_PUT as i32 as u32 == httpreq as u32) + && (*data).state.resume_from != 0 + { + if (*data).state.resume_from < 0 as i32 as i64 { + (*data).state.resume_from = 0 as i32 as curl_off_t; } - if seekerr != 0 as i32 { - let mut passed: curl_off_t = 0 as i32 as curl_off_t; - if seekerr != 2 as i32 { - Curl_failf( - data, - b"Could not seek stream\0" as *const u8 as *const libc::c_char, + if (*data).state.resume_from != 0 && ((*data).state).this_is_a_follow() == 0 { + let mut seekerr: i32 = 2 as i32; + if ((*conn).seek_func).is_some() { + Curl_set_in_callback(data, 1 as i32 != 0); + seekerr = ((*conn).seek_func).expect("non-null function pointer")( + (*conn).seek_client, + (*data).state.resume_from, + 0 as i32, ); - return CURLE_READ_ERROR; + Curl_set_in_callback(data, 0 as i32 != 0); } - loop { - let mut readthisamountnow: size_t = - if (*data).state.resume_from - passed > (*data).set.buffer_size { - (*data).set.buffer_size as size_t - } else { - curlx_sotouz((*data).state.resume_from - passed) - }; - let mut actuallyread: size_t = ((*data).state.fread_func) - .expect("non-null function pointer")( - (*data).state.buffer, - 1 as i32 as size_t, - readthisamountnow, - (*data).state.in_0, - ); - passed = (passed as u64).wrapping_add(actuallyread) as curl_off_t as curl_off_t; - if actuallyread == 0 as i32 as u64 || actuallyread > readthisamountnow { + if seekerr != 0 as i32 { + let mut passed: curl_off_t = 0 as i32 as curl_off_t; + if seekerr != 2 as i32 { Curl_failf( data, - b"Could only read %ld bytes from the input\0" as *const u8 - as *const libc::c_char, - passed, + b"Could not seek stream\0" as *const u8 as *const libc::c_char, ); return CURLE_READ_ERROR; } - if !(passed < (*data).state.resume_from) { - break; + loop { + let mut readthisamountnow: size_t = + if (*data).state.resume_from - passed > (*data).set.buffer_size { + (*data).set.buffer_size as size_t + } else { + curlx_sotouz((*data).state.resume_from - passed) + }; + let mut actuallyread: size_t = ((*data).state.fread_func) + .expect("non-null function pointer")( + (*data).state.buffer, + 1 as i32 as size_t, + readthisamountnow, + (*data).state.in_0, + ); + passed = + (passed as u64).wrapping_add(actuallyread) as curl_off_t as curl_off_t; + if actuallyread == 0 as i32 as u64 || actuallyread > readthisamountnow { + Curl_failf( + data, + b"Could only read %ld bytes from the input\0" as *const u8 + as *const libc::c_char, + passed, + ); + return CURLE_READ_ERROR; + } + if !(passed < (*data).state.resume_from) { + break; + } } } - } - if (*data).state.infilesize > 0 as i64 { - (*data).state.infilesize -= (*data).state.resume_from; - if (*data).state.infilesize <= 0 as i32 as i64 { - Curl_failf( - data, - b"File already completely uploaded\0" as *const u8 as *const libc::c_char, - ); - return CURLE_PARTIAL_FILE; + if (*data).state.infilesize > 0 as i64 { + (*data).state.infilesize -= (*data).state.resume_from; + if (*data).state.infilesize <= 0 as i32 as i64 { + Curl_failf( + data, + b"File already completely uploaded\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_PARTIAL_FILE; + } } } } + return CURLE_OK; } - return CURLE_OK;} } #[no_mangle] pub extern "C" fn Curl_http_firstwrite( @@ -4612,15 +4763,15 @@ pub extern "C" fn Curl_http_firstwrite( mut conn: *mut connectdata, mut done: *mut bool, ) -> CURLcode { - let mut k: *mut SingleRequest =unsafe{ &mut (*data).req}; - unsafe{ - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*(*conn).handler).protocol - & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32 | (1 as i32) << 18 as i32) as u32 - != 0 - { - } else { - __assert_fail( + let mut k: *mut SingleRequest = unsafe { &mut (*data).req }; + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*(*conn).handler).protocol + & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32 | (1 as i32) << 18 as i32) as u32 + != 0 + { + } else { + __assert_fail( b"conn->handler->protocol&(((1<<0)|(1<<1))|(1<<18))\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, @@ -4633,581 +4784,597 @@ pub extern "C" fn Curl_http_firstwrite( )) .as_ptr(), ); - } - if ((*data).req).ignore_cl() != 0 { - let ref mut fresh64 = (*k).maxdownload; - *fresh64 = -(1 as i32) as curl_off_t; - (*k).size = *fresh64; - } else if (*k).size != -(1 as i32) as i64 { - if (*data).set.max_filesize != 0 && (*k).size > (*data).set.max_filesize { - Curl_failf( - data, - b"Maximum file size exceeded\0" as *const u8 as *const libc::c_char, - ); - return CURLE_FILESIZE_EXCEEDED; } - Curl_pgrsSetDownloadSize(data, (*k).size); - } - if !((*data).req.newurl).is_null() { - if ((*conn).bits).close() != 0 { - (*k).keepon &= !((1 as i32) << 0 as i32); - *done = 1 as i32 != 0; - return CURLE_OK; + if ((*data).req).ignore_cl() != 0 { + let ref mut fresh64 = (*k).maxdownload; + *fresh64 = -(1 as i32) as curl_off_t; + (*k).size = *fresh64; + } else if (*k).size != -(1 as i32) as i64 { + if (*data).set.max_filesize != 0 && (*k).size > (*data).set.max_filesize { + Curl_failf( + data, + b"Maximum file size exceeded\0" as *const u8 as *const libc::c_char, + ); + return CURLE_FILESIZE_EXCEEDED; + } + Curl_pgrsSetDownloadSize(data, (*k).size); } - (*k).set_ignorebody(1 as i32 as bit); - Curl_infof( - data, - b"Ignoring the response-body\0" as *const u8 as *const libc::c_char, - ); - } - if (*data).state.resume_from != 0 - && (*k).content_range() == 0 - && (*data).state.httpreq as u32 == HTTPREQ_GET as i32 as u32 - && (*k).ignorebody() == 0 - { - if (*k).size == (*data).state.resume_from { + if !((*data).req.newurl).is_null() { + if ((*conn).bits).close() != 0 { + (*k).keepon &= !((1 as i32) << 0 as i32); + *done = 1 as i32 != 0; + return CURLE_OK; + } + (*k).set_ignorebody(1 as i32 as bit); Curl_infof( data, - b"The entire document is already downloaded\0" as *const u8 as *const libc::c_char, - ); - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 1 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 1 as i32, - b"already downloaded\0" as *const u8 as *const libc::c_char, + b"Ignoring the response-body\0" as *const u8 as *const libc::c_char, ); - (*k).keepon &= !((1 as i32) << 0 as i32); - *done = 1 as i32 != 0; - return CURLE_OK; } - Curl_failf( - data, - b"HTTP server doesn't seem to support byte ranges. Cannot resume.\0" as *const u8 - as *const libc::c_char, - ); - return CURLE_RANGE_ERROR; - } - if (*data).set.timecondition as u32 != 0 && ((*data).state.range).is_null() { - if !Curl_meets_timecondition(data, (*k).timeofdoc) { - *done = 1 as i32 != 0; - (*data).info.httpcode = 304 as i32; - Curl_infof( + if (*data).state.resume_from != 0 + && (*k).content_range() == 0 + && (*data).state.httpreq as u32 == HTTPREQ_GET as i32 as u32 + && (*k).ignorebody() == 0 + { + if (*k).size == (*data).state.resume_from { + Curl_infof( + data, + b"The entire document is already downloaded\0" as *const u8 + as *const libc::c_char, + ); + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 1 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 1 as i32, + b"already downloaded\0" as *const u8 as *const libc::c_char, + ); + (*k).keepon &= !((1 as i32) << 0 as i32); + *done = 1 as i32 != 0; + return CURLE_OK; + } + Curl_failf( data, - b"Simulate a HTTP 304 response!\0" as *const u8 as *const libc::c_char, - ); - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 1 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 1 as i32, - b"Simulated 304 handling\0" as *const u8 as *const libc::c_char, + b"HTTP server doesn't seem to support byte ranges. Cannot resume.\0" as *const u8 + as *const libc::c_char, ); - return CURLE_OK; + return CURLE_RANGE_ERROR; + } + if (*data).set.timecondition as u32 != 0 && ((*data).state.range).is_null() { + if !Curl_meets_timecondition(data, (*k).timeofdoc) { + *done = 1 as i32 != 0; + (*data).info.httpcode = 304 as i32; + Curl_infof( + data, + b"Simulate a HTTP 304 response!\0" as *const u8 as *const libc::c_char, + ); + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 1 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 1 as i32, + b"Simulated 304 handling\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OK; + } } - }} + } return CURLE_OK; } #[cfg(HAVE_LIBZ)] #[no_mangle] pub extern "C" fn Curl_transferencode(mut data: *mut Curl_easy) -> CURLcode { - unsafe{ - if (Curl_checkheaders(data, b"TE\0" as *const u8 as *const libc::c_char)).is_null() - && ((*data).set).http_transfer_encoding() as i32 != 0 - { - let mut cptr: *mut libc::c_char = - Curl_checkheaders(data, b"Connection\0" as *const u8 as *const libc::c_char); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")((*data).state.aptr.te as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.te as *mut libc::c_void, - 2990 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - (*data).state.aptr.te = 0 as *mut libc::c_char; - if !cptr.is_null() { - cptr = Curl_copy_header_value(cptr); - if cptr.is_null() { + unsafe { + if (Curl_checkheaders(data, b"TE\0" as *const u8 as *const libc::c_char)).is_null() + && ((*data).set).http_transfer_encoding() as i32 != 0 + { + let mut cptr: *mut libc::c_char = + Curl_checkheaders(data, b"Connection\0" as *const u8 as *const libc::c_char); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.te as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.te as *mut libc::c_void, + 2990 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).state.aptr.te = 0 as *mut libc::c_char; + if !cptr.is_null() { + cptr = Curl_copy_header_value(cptr); + if cptr.is_null() { + return CURLE_OUT_OF_MEMORY; + } + } + (*data).state.aptr.te = curl_maprintf( + b"Connection: %s%sTE\r\nTE: gzip\r\n\0" as *const u8 as *const libc::c_char, + if !cptr.is_null() { + cptr as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !cptr.is_null() && *cptr as i32 != 0 { + b", \0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(cptr as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + cptr as *mut libc::c_void, + 3002 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + if ((*data).state.aptr.te).is_null() { return CURLE_OUT_OF_MEMORY; } } - (*data).state.aptr.te = curl_maprintf( - b"Connection: %s%sTE\r\nTE: gzip\r\n\0" as *const u8 as *const libc::c_char, - if !cptr.is_null() { - cptr as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !cptr.is_null() && *cptr as i32 != 0 { - b", \0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - ); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(cptr as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - cptr as *mut libc::c_void, - 3002 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - if ((*data).state.aptr.te).is_null() { - return CURLE_OUT_OF_MEMORY; - } - }} + } return CURLE_OK; } #[cfg(not(USE_HYPER))] #[no_mangle] pub extern "C" fn Curl_http(mut data: *mut Curl_easy, mut done: *mut bool) -> CURLcode { - unsafe{ - let mut conn: *mut connectdata = (*data).conn; - let mut result: CURLcode = CURLE_OK; - let mut http: *mut HTTP = 0 as *mut HTTP; - let mut httpreq: Curl_HttpReq = HTTPREQ_GET; - let mut te: *const libc::c_char = b"\0" as *const u8 as *const libc::c_char; - let mut request: *const libc::c_char = 0 as *const libc::c_char; - let mut httpstring: *const libc::c_char = 0 as *const libc::c_char; - let mut req: dynbuf = dynbuf { - bufr: 0 as *mut libc::c_char, - leng: 0, - allc: 0, - toobig: 0, - #[cfg(DEBUGBUILD)] - init: 0, - }; - let mut altused: *mut libc::c_char = 0 as *mut libc::c_char; - let mut p_accept: *const libc::c_char = 0 as *const libc::c_char; - *done = 1 as i32 != 0; - if (*conn).transport as u32 != TRNSPRT_QUIC as i32 as u32 { - if ((*conn).httpversion as i32) < 20 as i32 { - match (*conn).negnpn { - 3 => { - (*conn).httpversion = 20 as i32 as u8; - result = - Curl_http2_switched(data, 0 as *const libc::c_char, 0 as i32 as size_t); - if result as u64 != 0 { - return result; + unsafe { + let mut conn: *mut connectdata = (*data).conn; + let mut result: CURLcode = CURLE_OK; + let mut http: *mut HTTP = 0 as *mut HTTP; + let mut httpreq: Curl_HttpReq = HTTPREQ_GET; + let mut te: *const libc::c_char = b"\0" as *const u8 as *const libc::c_char; + let mut request: *const libc::c_char = 0 as *const libc::c_char; + let mut httpstring: *const libc::c_char = 0 as *const libc::c_char; + let mut req: dynbuf = dynbuf { + bufr: 0 as *mut libc::c_char, + leng: 0, + allc: 0, + toobig: 0, + #[cfg(DEBUGBUILD)] + init: 0, + }; + let mut altused: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p_accept: *const libc::c_char = 0 as *const libc::c_char; + *done = 1 as i32 != 0; + if (*conn).transport as u32 != TRNSPRT_QUIC as i32 as u32 { + if ((*conn).httpversion as i32) < 20 as i32 { + match (*conn).negnpn { + 3 => { + (*conn).httpversion = 20 as i32 as u8; + result = + Curl_http2_switched(data, 0 as *const libc::c_char, 0 as i32 as size_t); + if result as u64 != 0 { + return result; + } } - } - 2 => {} - _ => { - #[cfg(USE_NGHTTP2)] - if (*data).state.httpwant as i32 == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE as i32 { - #[cfg(not(CURL_DISABLE_PROXY))] - let flag1: bool = ((*conn).bits).httpproxy() as i32 != 0 - && ((*conn).bits).tunnel_proxy() == 0; - #[cfg(CURL_DISABLE_PROXY)] - let flag1: bool = false; - if flag1 { - Curl_infof( - data, - b"Ignoring HTTP/2 prior knowledge due to proxy\0" as *const u8 - as *const libc::c_char, - ); - } else { - Curl_infof( - data, - b"HTTP/2 over clean TCP\0" as *const u8 as *const libc::c_char, - ); - (*conn).httpversion = 20 as i32 as u8; - result = Curl_http2_switched( - data, - 0 as *const libc::c_char, - 0 as i32 as size_t, - ); - if result as u64 != 0 { - return result; + 2 => {} + _ => { + #[cfg(USE_NGHTTP2)] + if (*data).state.httpwant as i32 + == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE as i32 + { + #[cfg(not(CURL_DISABLE_PROXY))] + let flag1: bool = ((*conn).bits).httpproxy() as i32 != 0 + && ((*conn).bits).tunnel_proxy() == 0; + #[cfg(CURL_DISABLE_PROXY)] + let flag1: bool = false; + if flag1 { + Curl_infof( + data, + b"Ignoring HTTP/2 prior knowledge due to proxy\0" as *const u8 + as *const libc::c_char, + ); + } else { + Curl_infof( + data, + b"HTTP/2 over clean TCP\0" as *const u8 as *const libc::c_char, + ); + (*conn).httpversion = 20 as i32 as u8; + result = Curl_http2_switched( + data, + 0 as *const libc::c_char, + 0 as i32 as size_t, + ); + if result as u64 != 0 { + return result; + } } } } } + } else { + result = Curl_http2_setup(data, conn); + if result as u64 != 0 { + return result; + } } + } + http = (*data).req.p.http; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !http.is_null() { } else { - result = Curl_http2_setup(data, conn); - if result as u64 != 0 { - return result; + __assert_fail( + b"http\0" as *const u8 as *const libc::c_char, + b"http.c\0" as *const u8 as *const libc::c_char, + 3079 as i32 as u32, + (*::std::mem::transmute::<&[u8; 48], &[libc::c_char; 48]>( + b"CURLcode Curl_http(struct Curl_easy *, _Bool *)\0", + )) + .as_ptr(), + ); + } + result = Curl_http_host(data, conn); + if result as u64 != 0 { + return result; + } + result = Curl_http_useragent(data); + if result as u64 != 0 { + return result; + } + Curl_http_method(data, conn, &mut request, &mut httpreq); + let mut pq: *mut libc::c_char = 0 as *mut libc::c_char; + if !((*data).state.up.query).is_null() { + pq = curl_maprintf( + b"%s?%s\0" as *const u8 as *const libc::c_char, + (*data).state.up.path, + (*data).state.up.query, + ); + if pq.is_null() { + return CURLE_OUT_OF_MEMORY; } } - } - http = (*data).req.p.http; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !http.is_null() { - } else { - __assert_fail( - b"http\0" as *const u8 as *const libc::c_char, - b"http.c\0" as *const u8 as *const libc::c_char, - 3079 as i32 as u32, - (*::std::mem::transmute::<&[u8; 48], &[libc::c_char; 48]>( - b"CURLcode Curl_http(struct Curl_easy *, _Bool *)\0", - )) - .as_ptr(), - ); - } - result = Curl_http_host(data, conn); - if result as u64 != 0 { - return result; - } - result = Curl_http_useragent(data); - if result as u64 != 0 { - return result; - } - Curl_http_method(data, conn, &mut request, &mut httpreq); - let mut pq: *mut libc::c_char = 0 as *mut libc::c_char; - if !((*data).state.up.query).is_null() { - pq = curl_maprintf( - b"%s?%s\0" as *const u8 as *const libc::c_char, - (*data).state.up.path, - (*data).state.up.query, - ); - if pq.is_null() { - return CURLE_OUT_OF_MEMORY; - } - } - result = Curl_http_output_auth( - data, - conn, - request, - httpreq, - if !pq.is_null() { - pq - } else { - (*data).state.up.path - }, - 0 as i32 != 0, - ); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(pq as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - pq as *mut libc::c_void, - 3101 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - if result as u64 != 0 { - return result; - } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")((*data).state.aptr.ref_0 as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.ref_0 as *mut libc::c_void, - 3106 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - (*data).state.aptr.ref_0 = 0 as *mut libc::c_char; - if !((*data).state.referer).is_null() - && (Curl_checkheaders(data, b"Referer\0" as *const u8 as *const libc::c_char)).is_null() - { - (*data).state.aptr.ref_0 = curl_maprintf( - b"Referer: %s\r\n\0" as *const u8 as *const libc::c_char, - (*data).state.referer, + result = Curl_http_output_auth( + data, + conn, + request, + httpreq, + if !pq.is_null() { + pq + } else { + (*data).state.up.path + }, + 0 as i32 != 0, ); - if ((*data).state.aptr.ref_0).is_null() { - return CURLE_OUT_OF_MEMORY; - } - } - if (Curl_checkheaders( - data, - b"Accept-Encoding\0" as *const u8 as *const libc::c_char, - )) - .is_null() - && !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null() - { #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.accept_encoding as *mut libc::c_void, - ); + Curl_cfree.expect("non-null function pointer")(pq as *mut libc::c_void); #[cfg(CURLDEBUG)] curl_dbg_free( - (*data).state.aptr.accept_encoding as *mut libc::c_void, - 3115 as i32, + pq as *mut libc::c_void, + 3101 as i32, b"http.c\0" as *const u8 as *const libc::c_char, ); - (*data).state.aptr.accept_encoding = 0 as *mut libc::c_char; - (*data).state.aptr.accept_encoding = curl_maprintf( - b"Accept-Encoding: %s\r\n\0" as *const u8 as *const libc::c_char, - (*data).set.str_0[STRING_ENCODING as i32 as usize], - ); - if ((*data).state.aptr.accept_encoding).is_null() { - return CURLE_OUT_OF_MEMORY; + if result as u64 != 0 { + return result; } - } else { #[cfg(not(CURLDEBUG))] Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.accept_encoding as *mut libc::c_void, + (*data).state.aptr.ref_0 as *mut libc::c_void, ); #[cfg(CURLDEBUG)] curl_dbg_free( - (*data).state.aptr.accept_encoding as *mut libc::c_void, - 3122 as i32, + (*data).state.aptr.ref_0 as *mut libc::c_void, + 3106 as i32, b"http.c\0" as *const u8 as *const libc::c_char, ); - (*data).state.aptr.accept_encoding = 0 as *mut libc::c_char; - } - // TODO 测试过了就把注释删咯 - match () { - #[cfg(HAVE_LIBZ)] - _ => { - result = Curl_transferencode(data); - if result as u64 != 0 { - return result; + (*data).state.aptr.ref_0 = 0 as *mut libc::c_char; + if !((*data).state.referer).is_null() + && (Curl_checkheaders(data, b"Referer\0" as *const u8 as *const libc::c_char)).is_null() + { + (*data).state.aptr.ref_0 = curl_maprintf( + b"Referer: %s\r\n\0" as *const u8 as *const libc::c_char, + (*data).state.referer, + ); + if ((*data).state.aptr.ref_0).is_null() { + return CURLE_OUT_OF_MEMORY; } } - #[cfg(not(HAVE_LIBZ))] - _ => {} - } - // if cfg!(HAVE_LIBZ) { - // result = Curl_transferencode(data); - // if result as u64 != 0 { - // return result; - // } - // } - result = Curl_http_body(data, conn, httpreq, &mut te); - if result as u64 != 0 { - return result; - } - p_accept = - if !(Curl_checkheaders(data, b"Accept\0" as *const u8 as *const libc::c_char)).is_null() { + if (Curl_checkheaders( + data, + b"Accept-Encoding\0" as *const u8 as *const libc::c_char, + )) + .is_null() + && !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null() + { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.accept_encoding as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.accept_encoding as *mut libc::c_void, + 3115 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).state.aptr.accept_encoding = 0 as *mut libc::c_char; + (*data).state.aptr.accept_encoding = curl_maprintf( + b"Accept-Encoding: %s\r\n\0" as *const u8 as *const libc::c_char, + (*data).set.str_0[STRING_ENCODING as i32 as usize], + ); + if ((*data).state.aptr.accept_encoding).is_null() { + return CURLE_OUT_OF_MEMORY; + } + } else { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.accept_encoding as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.accept_encoding as *mut libc::c_void, + 3122 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).state.aptr.accept_encoding = 0 as *mut libc::c_char; + } + // TODO 测试过了就把注释删咯 + match () { + #[cfg(HAVE_LIBZ)] + _ => { + result = Curl_transferencode(data); + if result as u64 != 0 { + return result; + } + } + #[cfg(not(HAVE_LIBZ))] + _ => {} + } + // if cfg!(HAVE_LIBZ) { + // result = Curl_transferencode(data); + // if result as u64 != 0 { + // return result; + // } + // } + result = Curl_http_body(data, conn, httpreq, &mut te); + if result as u64 != 0 { + return result; + } + p_accept = if !(Curl_checkheaders(data, b"Accept\0" as *const u8 as *const libc::c_char)) + .is_null() + { 0 as *const libc::c_char } else { b"Accept: */*\r\n\0" as *const u8 as *const libc::c_char }; - result = Curl_http_resume(data, conn, httpreq); - if result as u64 != 0 { - return result; - } - result = Curl_http_range(data, httpreq); - if result as u64 != 0 { - return result; - } - httpstring = get_http_string(data, conn); - Curl_dyn_init(&mut req, (1024 as i32 * 1024 as i32) as size_t); - Curl_dyn_reset(&mut (*data).state.headerb); - result = Curl_dyn_addf( - &mut req as *mut dynbuf, - b"%s \0" as *const u8 as *const libc::c_char, - request, - ); - if result as u64 == 0 { - result = Curl_http_target(data, conn, &mut req); - } - if result as u64 != 0 { - Curl_dyn_free(&mut req); - return result; - } - #[cfg(not(CURL_DISABLE_ALTSVC))] - if ((*conn).bits).altused() as i32 != 0 - && (Curl_checkheaders(data, b"Alt-Used\0" as *const u8 as *const libc::c_char)).is_null() - { - altused = curl_maprintf( - b"Alt-Used: %s:%d\r\n\0" as *const u8 as *const libc::c_char, - (*conn).conn_to_host.name, - (*conn).conn_to_port, + result = Curl_http_resume(data, conn, httpreq); + if result as u64 != 0 { + return result; + } + result = Curl_http_range(data, httpreq); + if result as u64 != 0 { + return result; + } + httpstring = get_http_string(data, conn); + Curl_dyn_init(&mut req, (1024 as i32 * 1024 as i32) as size_t); + Curl_dyn_reset(&mut (*data).state.headerb); + result = Curl_dyn_addf( + &mut req as *mut dynbuf, + b"%s \0" as *const u8 as *const libc::c_char, + request, ); - if altused.is_null() { + if result as u64 == 0 { + result = Curl_http_target(data, conn, &mut req); + } + if result as u64 != 0 { Curl_dyn_free(&mut req); - return CURLE_OUT_OF_MEMORY; + return result; } - } - #[cfg(not(CURL_DISABLE_PROXY))] - let flag2: bool = ((*conn).bits).httpproxy() as i32 != 0 - && ((*conn).bits).tunnel_proxy() == 0 - && (Curl_checkheaders( - data, - b"Proxy-Connection\0" as *const u8 as *const libc::c_char, - )) - .is_null() - && (Curl_checkProxyheaders( - data, - conn, - b"Proxy-Connection\0" as *const u8 as *const libc::c_char, - )) - .is_null(); - #[cfg(CURL_DISABLE_PROXY)] - let flag2: bool = false; - result = Curl_dyn_addf( - &mut req as *mut dynbuf, - b" HTTP/%s\r\n%s%s%s%s%s%s%s%s%s%s%s%s\0" as *const u8 as *const libc::c_char, - httpstring, - if !((*data).state.aptr.host).is_null() { - (*data).state.aptr.host as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !((*data).state.aptr.proxyuserpwd).is_null() { - (*data).state.aptr.proxyuserpwd as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !((*data).state.aptr.userpwd).is_null() { - (*data).state.aptr.userpwd as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if ((*data).state).use_range() as i32 != 0 && !((*data).state.aptr.rangeline).is_null() { - (*data).state.aptr.rangeline as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !((*data).set.str_0[STRING_USERAGENT as i32 as usize]).is_null() - && *(*data).set.str_0[STRING_USERAGENT as i32 as usize] as i32 != 0 - && !((*data).state.aptr.uagent).is_null() - { - (*data).state.aptr.uagent as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !p_accept.is_null() { - p_accept - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !((*data).state.aptr.te).is_null() { - (*data).state.aptr.te as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null() - && *(*data).set.str_0[STRING_ENCODING as i32 as usize] as i32 != 0 - && !((*data).state.aptr.accept_encoding).is_null() + #[cfg(not(CURL_DISABLE_ALTSVC))] + if ((*conn).bits).altused() as i32 != 0 + && (Curl_checkheaders(data, b"Alt-Used\0" as *const u8 as *const libc::c_char)) + .is_null() { - (*data).state.aptr.accept_encoding as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !((*data).state.referer).is_null() && !((*data).state.aptr.ref_0).is_null() { - (*data).state.aptr.ref_0 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if flag2 { - b"Proxy-Connection: Keep-Alive\r\n\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - te, - if !altused.is_null() { - altused as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - ); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")((*data).state.aptr.userpwd as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.userpwd as *mut libc::c_void, - 3224 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - (*data).state.aptr.userpwd = 0 as *mut libc::c_char; - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - 3225 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(altused as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - altused as *mut libc::c_void, - 3226 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - if result as u64 != 0 { - Curl_dyn_free(&mut req); - return result; - } - if (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 == 0 - && (*conn).httpversion as i32 != 20 as i32 - && (*data).state.httpwant as i32 == CURL_HTTP_VERSION_2_0 as i32 - { - result = Curl_http2_request_upgrade(&mut req, data); + altused = curl_maprintf( + b"Alt-Used: %s:%d\r\n\0" as *const u8 as *const libc::c_char, + (*conn).conn_to_host.name, + (*conn).conn_to_port, + ); + if altused.is_null() { + Curl_dyn_free(&mut req); + return CURLE_OUT_OF_MEMORY; + } + } + #[cfg(not(CURL_DISABLE_PROXY))] + let flag2: bool = ((*conn).bits).httpproxy() as i32 != 0 + && ((*conn).bits).tunnel_proxy() == 0 + && (Curl_checkheaders( + data, + b"Proxy-Connection\0" as *const u8 as *const libc::c_char, + )) + .is_null() + && (Curl_checkProxyheaders( + data, + conn, + b"Proxy-Connection\0" as *const u8 as *const libc::c_char, + )) + .is_null(); + #[cfg(CURL_DISABLE_PROXY)] + let flag2: bool = false; + result = Curl_dyn_addf( + &mut req as *mut dynbuf, + b" HTTP/%s\r\n%s%s%s%s%s%s%s%s%s%s%s%s\0" as *const u8 as *const libc::c_char, + httpstring, + if !((*data).state.aptr.host).is_null() { + (*data).state.aptr.host as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !((*data).state.aptr.proxyuserpwd).is_null() { + (*data).state.aptr.proxyuserpwd as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !((*data).state.aptr.userpwd).is_null() { + (*data).state.aptr.userpwd as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if ((*data).state).use_range() as i32 != 0 && !((*data).state.aptr.rangeline).is_null() + { + (*data).state.aptr.rangeline as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !((*data).set.str_0[STRING_USERAGENT as i32 as usize]).is_null() + && *(*data).set.str_0[STRING_USERAGENT as i32 as usize] as i32 != 0 + && !((*data).state.aptr.uagent).is_null() + { + (*data).state.aptr.uagent as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !p_accept.is_null() { + p_accept + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !((*data).state.aptr.te).is_null() { + (*data).state.aptr.te as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null() + && *(*data).set.str_0[STRING_ENCODING as i32 as usize] as i32 != 0 + && !((*data).state.aptr.accept_encoding).is_null() + { + (*data).state.aptr.accept_encoding as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !((*data).state.referer).is_null() && !((*data).state.aptr.ref_0).is_null() { + (*data).state.aptr.ref_0 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if flag2 { + b"Proxy-Connection: Keep-Alive\r\n\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + te, + if !altused.is_null() { + altused as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.userpwd as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.userpwd as *mut libc::c_void, + 3224 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).state.aptr.userpwd = 0 as *mut libc::c_char; + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + 3225 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(altused as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + altused as *mut libc::c_void, + 3226 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); if result as u64 != 0 { Curl_dyn_free(&mut req); return result; } - } - result = Curl_http_cookies(data, conn, &mut req); - if result as u64 == 0 { - result = Curl_add_timecondition(data, &mut req); - } - if result as u64 == 0 { - result = Curl_add_custom_headers(data, 0 as i32 != 0, &mut req); - } - if result as u64 == 0 { - (*http).postdata = 0 as *const libc::c_char; - if httpreq as u32 == HTTPREQ_GET as i32 as u32 - || httpreq as u32 == HTTPREQ_HEAD as i32 as u32 + if (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 == 0 + && (*conn).httpversion as i32 != 20 as i32 + && (*data).state.httpwant as i32 == CURL_HTTP_VERSION_2_0 as i32 { - Curl_pgrsSetUploadSize(data, 0 as i32 as curl_off_t); + result = Curl_http2_request_upgrade(&mut req, data); + if result as u64 != 0 { + Curl_dyn_free(&mut req); + return result; + } } - result = Curl_http_bodysend(data, conn, &mut req, httpreq); - } - if result as u64 != 0 { - Curl_dyn_free(&mut req); - return result; - } - if (*http).postsize > -(1 as i32) as i64 - && (*http).postsize <= (*data).req.writebytecount - && (*http).sending as u32 != HTTPSEND_REQUEST as i32 as u32 - { - (*data).req.set_upload_done(1 as i32 as bit); - } - if (*data).req.writebytecount != 0 { - Curl_pgrsSetUploadCounter(data, (*data).req.writebytecount); - if Curl_pgrsUpdate(data) != 0 { - result = CURLE_ABORTED_BY_CALLBACK; + result = Curl_http_cookies(data, conn, &mut req); + if result as u64 == 0 { + result = Curl_add_timecondition(data, &mut req); } - if (*http).postsize == 0 { - Curl_infof( - data, - b"upload completely sent off: %ld out of %ld bytes\0" as *const u8 - as *const libc::c_char, - (*data).req.writebytecount, - (*http).postsize, - ); + if result as u64 == 0 { + result = Curl_add_custom_headers(data, 0 as i32 != 0, &mut req); + } + if result as u64 == 0 { + (*http).postdata = 0 as *const libc::c_char; + if httpreq as u32 == HTTPREQ_GET as i32 as u32 + || httpreq as u32 == HTTPREQ_HEAD as i32 as u32 + { + Curl_pgrsSetUploadSize(data, 0 as i32 as curl_off_t); + } + result = Curl_http_bodysend(data, conn, &mut req, httpreq); + } + if result as u64 != 0 { + Curl_dyn_free(&mut req); + return result; + } + if (*http).postsize > -(1 as i32) as i64 + && (*http).postsize <= (*data).req.writebytecount + && (*http).sending as u32 != HTTPSEND_REQUEST as i32 as u32 + { (*data).req.set_upload_done(1 as i32 as bit); - (*data).req.keepon &= !((1 as i32) << 1 as i32); - (*data).req.exp100 = EXP100_SEND_DATA; - Curl_expire_done(data, EXPIRE_100_TIMEOUT); } + if (*data).req.writebytecount != 0 { + Curl_pgrsSetUploadCounter(data, (*data).req.writebytecount); + if Curl_pgrsUpdate(data) != 0 { + result = CURLE_ABORTED_BY_CALLBACK; + } + if (*http).postsize == 0 { + Curl_infof( + data, + b"upload completely sent off: %ld out of %ld bytes\0" as *const u8 + as *const libc::c_char, + (*data).req.writebytecount, + (*http).postsize, + ); + (*data).req.set_upload_done(1 as i32 as bit); + (*data).req.keepon &= !((1 as i32) << 1 as i32); + (*data).req.exp100 = EXP100_SEND_DATA; + Curl_expire_done(data, EXPIRE_100_TIMEOUT); + } + } + if (*conn).httpversion as i32 == 20 as i32 && ((*data).req).upload_chunky() as i32 != 0 { + (*data).req.set_upload_chunky(0 as i32 as bit); + } + return result; } - if (*conn).httpversion as i32 == 20 as i32 && ((*data).req).upload_chunky() as i32 != 0 { - (*data).req.set_upload_chunky(0 as i32 as bit); - } - return result; -} } extern "C" fn checkprefixmax( mut prefix: *const libc::c_char, mut buffer: *const libc::c_char, mut len: size_t, ) -> bool { - let mut ch: size_t = unsafe{if strlen(prefix) < len { - strlen(prefix) - } else { - len - }}; - return unsafe{curl_strnequal(prefix, buffer, ch) != 0}; + let mut ch: size_t = unsafe { + if strlen(prefix) < len { + strlen(prefix) + } else { + len + } + }; + return unsafe { curl_strnequal(prefix, buffer, ch) != 0 }; } extern "C" fn checkhttpprefix( mut data: *mut Curl_easy, mut s: *const libc::c_char, mut len: size_t, ) -> statusline { - let mut head: *mut curl_slist =unsafe{ (*data).set.http200aliases}; + let mut head: *mut curl_slist = unsafe { (*data).set.http200aliases }; let mut rc: statusline = STATUS_BAD; let mut onmatch: statusline = (if len >= 5 as i32 as u64 { STATUS_DONE as i32 @@ -5215,15 +5382,15 @@ extern "C" fn checkhttpprefix( STATUS_UNKNOWN as i32 }) as statusline; while !head.is_null() { - unsafe{ - if checkprefixmax((*head).data, s, len) { - rc = onmatch; - break; - } else { - head = (*head).next; + unsafe { + if checkprefixmax((*head).data, s, len) { + rc = onmatch; + break; + } else { + head = (*head).next; + } } } - } if rc as u32 != STATUS_DONE as i32 as u32 && checkprefixmax(b"HTTP/\0" as *const u8 as *const libc::c_char, s, len) as i32 != 0 { @@ -5254,513 +5421,525 @@ extern "C" fn checkprotoprefix( mut s: *const libc::c_char, mut len: size_t, ) -> statusline { - unsafe{ - #[cfg(not(CURL_DISABLE_RSTP))] - if (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 { - return checkrtspprefix(data, s, len); + unsafe { + #[cfg(not(CURL_DISABLE_RSTP))] + if (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 { + return checkrtspprefix(data, s, len); + } + return checkhttpprefix(data, s, len); } - return checkhttpprefix(data, s, len);} } #[no_mangle] pub extern "C" fn Curl_http_header( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut headp: *mut libc::c_char, -) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut k: *mut SingleRequest =unsafe{ &mut (*data).req}; - unsafe{ - #[cfg(not(CURL_DISABLE_PROXY))] - let flag1: bool = (*conn).httpversion as i32 == 10 as i32 - && ((*conn).bits).httpproxy() as i32 != 0 - && Curl_compareheader( - headp, - b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, - b"keep-alive\0" as *const u8 as *const libc::c_char, - ) as i32 - != 0; - #[cfg(CURL_DISABLE_PROXY)] - let flag1: bool = false; - #[cfg(not(CURL_DISABLE_PROXY))] - let flag2: bool = (*conn).httpversion as i32 == 11 as i32 - && ((*conn).bits).httpproxy() as i32 != 0 - && Curl_compareheader( - headp, - b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, - b"close\0" as *const u8 as *const libc::c_char, - ) as i32 - != 0; - #[cfg(CURL_DISABLE_PROXY)] - let flag2: bool = false; - #[cfg(not(CURL_DISABLE_COOKIES))] - let flag3: bool = !((*data).cookies).is_null() - && ((*data).state).cookie_engine() as i32 != 0 - && curl_strnequal( - b"Set-Cookie:\0" as *const u8 as *const libc::c_char, + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut headp: *mut libc::c_char, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut k: *mut SingleRequest = unsafe { &mut (*data).req }; + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let flag1: bool = (*conn).httpversion as i32 == 10 as i32 + && ((*conn).bits).httpproxy() as i32 != 0 + && Curl_compareheader( + headp, + b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, + b"keep-alive\0" as *const u8 as *const libc::c_char, + ) as i32 + != 0; + #[cfg(CURL_DISABLE_PROXY)] + let flag1: bool = false; + #[cfg(not(CURL_DISABLE_PROXY))] + let flag2: bool = (*conn).httpversion as i32 == 11 as i32 + && ((*conn).bits).httpproxy() as i32 != 0 + && Curl_compareheader( + headp, + b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, + b"close\0" as *const u8 as *const libc::c_char, + ) as i32 + != 0; + #[cfg(CURL_DISABLE_PROXY)] + let flag2: bool = false; + #[cfg(not(CURL_DISABLE_COOKIES))] + let flag3: bool = !((*data).cookies).is_null() + && ((*data).state).cookie_engine() as i32 != 0 + && curl_strnequal( + b"Set-Cookie:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Set-Cookie:\0" as *const u8 as *const libc::c_char), + ) != 0; + #[cfg(CURL_DISABLE_COOKIES)] + let flag3: bool = false; + #[cfg(USE_SPNEGO)] + let flag4: bool = curl_strnequal( + b"Persistent-Auth:\0" as *const u8 as *const libc::c_char, headp, - strlen(b"Set-Cookie:\0" as *const u8 as *const libc::c_char), + strlen(b"Persistent-Auth:\0" as *const u8 as *const libc::c_char), ) != 0; - #[cfg(CURL_DISABLE_COOKIES)] - let flag3: bool = false; - #[cfg(USE_SPNEGO)] - let flag4: bool = curl_strnequal( - b"Persistent-Auth:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Persistent-Auth:\0" as *const u8 as *const libc::c_char), - ) != 0; - #[cfg(not(USE_SPNEGO))] - let flag4: bool = false; - // let flag4: bool = if cfg!(USE_SPNEGO) { - // curl_strnequal( - // b"Persistent-Auth:\0" as *const u8 as *const libc::c_char, - // headp, - // strlen(b"Persistent-Auth:\0" as *const u8 as *const libc::c_char), - // ) != 0 - // } else { - // false - // }; - #[cfg(not(CURL_DISABLE_HSTS))] - let flag5: bool = !((*data).hsts).is_null() - && curl_strnequal( - b"Strict-Transport-Security:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Strict-Transport-Security:\0" as *const u8 as *const libc::c_char), - ) != 0 - && (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0; - #[cfg(CURL_DISABLE_HSTS)] - let flag5: bool = false; - #[cfg(all(not(CURL_DISABLE_ALTSVC), not(CURLDEBUG)))] - let flag6: bool = !((*data).asi).is_null() - && curl_strnequal( - b"Alt-Svc:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char), - ) != 0 - && ((*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 || 0 as i32 != 0); - - #[cfg(all(not(CURL_DISABLE_ALTSVC), CURLDEBUG))] - let flag6: bool = !((*data).asi).is_null() - && curl_strnequal( - b"Alt-Svc:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char), - ) != 0 - && ((*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 - || !(getenv(b"CURL_ALTSVC_HTTP\0" as *const u8 as *const libc::c_char)).is_null()); - #[cfg(CURL_DISABLE_ALTSVC)] - let flag6: bool = false; - - if (*k).http_bodyless() == 0 - && ((*data).set).ignorecl() == 0 - && curl_strnequal( - b"Content-Length:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char), - ) != 0 - { - let mut contentlength: curl_off_t = 0; - let mut offt: CURLofft = curlx_strtoofft( - headp.offset(strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char) as isize), - 0 as *mut *mut libc::c_char, - 10 as i32, - &mut contentlength, - ); - if offt as u32 == CURL_OFFT_OK as i32 as u32 { - (*k).size = contentlength; - (*k).maxdownload = (*k).size; - } else if offt as u32 == CURL_OFFT_FLOW as i32 as u32 { - if (*data).set.max_filesize != 0 { + #[cfg(not(USE_SPNEGO))] + let flag4: bool = false; + // let flag4: bool = if cfg!(USE_SPNEGO) { + // curl_strnequal( + // b"Persistent-Auth:\0" as *const u8 as *const libc::c_char, + // headp, + // strlen(b"Persistent-Auth:\0" as *const u8 as *const libc::c_char), + // ) != 0 + // } else { + // false + // }; + #[cfg(not(CURL_DISABLE_HSTS))] + let flag5: bool = !((*data).hsts).is_null() + && curl_strnequal( + b"Strict-Transport-Security:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Strict-Transport-Security:\0" as *const u8 as *const libc::c_char), + ) != 0 + && (*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0; + #[cfg(CURL_DISABLE_HSTS)] + let flag5: bool = false; + #[cfg(all(not(CURL_DISABLE_ALTSVC), not(CURLDEBUG)))] + let flag6: bool = !((*data).asi).is_null() + && curl_strnequal( + b"Alt-Svc:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char), + ) != 0 + && ((*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 || 0 as i32 != 0); + + #[cfg(all(not(CURL_DISABLE_ALTSVC), CURLDEBUG))] + let flag6: bool = !((*data).asi).is_null() + && curl_strnequal( + b"Alt-Svc:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char), + ) != 0 + && ((*(*conn).handler).flags & ((1 as i32) << 0 as i32) as u32 != 0 + || !(getenv(b"CURL_ALTSVC_HTTP\0" as *const u8 as *const libc::c_char)).is_null()); + #[cfg(CURL_DISABLE_ALTSVC)] + let flag6: bool = false; + + if (*k).http_bodyless() == 0 + && ((*data).set).ignorecl() == 0 + && curl_strnequal( + b"Content-Length:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char), + ) != 0 + { + let mut contentlength: curl_off_t = 0; + let mut offt: CURLofft = curlx_strtoofft( + headp.offset( + strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char) as isize, + ), + 0 as *mut *mut libc::c_char, + 10 as i32, + &mut contentlength, + ); + if offt as u32 == CURL_OFFT_OK as i32 as u32 { + (*k).size = contentlength; + (*k).maxdownload = (*k).size; + } else if offt as u32 == CURL_OFFT_FLOW as i32 as u32 { + if (*data).set.max_filesize != 0 { + Curl_failf( + data, + b"Maximum file size exceeded\0" as *const u8 as *const libc::c_char, + ); + return CURLE_FILESIZE_EXCEEDED; + } + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 2 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 2 as i32, + b"overflow content-length\0" as *const u8 as *const libc::c_char, + ); + Curl_infof( + data, + b"Overflow Content-Length: value!\0" as *const u8 as *const libc::c_char, + ); + } else { Curl_failf( data, - b"Maximum file size exceeded\0" as *const u8 as *const libc::c_char, + b"Invalid Content-Length: value\0" as *const u8 as *const libc::c_char, ); - return CURLE_FILESIZE_EXCEEDED; + return CURLE_WEIRD_SERVER_REPLY; + } + } else if curl_strnequal( + b"Content-Type:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), + ) != 0 + { + let mut contenttype: *mut libc::c_char = Curl_copy_header_value(headp); + if contenttype.is_null() { + return CURLE_OUT_OF_MEMORY; + } + if *contenttype == 0 { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(contenttype as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + contenttype as *mut libc::c_void, + 3445 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + } else { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).info.contenttype as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).info.contenttype as *mut libc::c_void, + 3447 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + (*data).info.contenttype = 0 as *mut libc::c_char; + (*data).info.contenttype = contenttype; } + } else if flag1 { #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 2 as i32); + Curl_conncontrol(conn, 0 as i32); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] Curl_conncontrol( conn, - 2 as i32, - b"overflow content-length\0" as *const u8 as *const libc::c_char, + 0 as i32, + b"Proxy-Connection keep-alive\0" as *const u8 as *const libc::c_char, ); Curl_infof( data, - b"Overflow Content-Length: value!\0" as *const u8 as *const libc::c_char, + b"HTTP/1.0 proxy connection set to keep alive!\0" as *const u8 + as *const libc::c_char, ); - } else { - Curl_failf( - data, - b"Invalid Content-Length: value\0" as *const u8 as *const libc::c_char, + } else if flag2 { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 1 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 1 as i32, + b"Proxy-Connection: asked to close after done\0" as *const u8 + as *const libc::c_char, ); - return CURLE_WEIRD_SERVER_REPLY; - } - } else if curl_strnequal( - b"Content-Type:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Content-Type:\0" as *const u8 as *const libc::c_char), - ) != 0 - { - let mut contenttype: *mut libc::c_char = Curl_copy_header_value(headp); - if contenttype.is_null() { - return CURLE_OUT_OF_MEMORY; - } - if *contenttype == 0 { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(contenttype as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - contenttype as *mut libc::c_void, - 3445 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, + Curl_infof( + data, + b"HTTP/1.1 proxy connection set close!\0" as *const u8 as *const libc::c_char, ); - } else { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).info.contenttype as *mut libc::c_void, + } else if (*conn).httpversion as i32 == 10 as i32 + && Curl_compareheader( + headp, + b"Connection:\0" as *const u8 as *const libc::c_char, + b"keep-alive\0" as *const u8 as *const libc::c_char, + ) as i32 + != 0 + { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 0 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 0 as i32, + b"Connection keep-alive\0" as *const u8 as *const libc::c_char, ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).info.contenttype as *mut libc::c_void, - 3447 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, + Curl_infof( + data, + b"HTTP/1.0 connection set to keep alive!\0" as *const u8 as *const libc::c_char, ); - (*data).info.contenttype = 0 as *mut libc::c_char; - (*data).info.contenttype = contenttype; - } - } else if flag1 { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 0 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 0 as i32, - b"Proxy-Connection keep-alive\0" as *const u8 as *const libc::c_char, - ); - Curl_infof( - data, - b"HTTP/1.0 proxy connection set to keep alive!\0" as *const u8 as *const libc::c_char, - ); - } else if flag2 { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 1 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 1 as i32, - b"Proxy-Connection: asked to close after done\0" as *const u8 as *const libc::c_char, - ); - Curl_infof( - data, - b"HTTP/1.1 proxy connection set close!\0" as *const u8 as *const libc::c_char, - ); - } else if (*conn).httpversion as i32 == 10 as i32 - && Curl_compareheader( + } else if Curl_compareheader( headp, b"Connection:\0" as *const u8 as *const libc::c_char, - b"keep-alive\0" as *const u8 as *const libc::c_char, - ) as i32 - != 0 - { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 0 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 0 as i32, - b"Connection keep-alive\0" as *const u8 as *const libc::c_char, - ); - Curl_infof( - data, - b"HTTP/1.0 connection set to keep alive!\0" as *const u8 as *const libc::c_char, - ); - } else if Curl_compareheader( - headp, - b"Connection:\0" as *const u8 as *const libc::c_char, - b"close\0" as *const u8 as *const libc::c_char, - ) { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 2 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 2 as i32, - b"Connection: close used\0" as *const u8 as *const libc::c_char, - ); - } else if (*k).http_bodyless() == 0 - && curl_strnequal( - b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char), - ) != 0 - { - result = Curl_build_unencoding_stack( - data, - headp.offset( - strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char) as isize, - ), - 1 as i32, - ); - if result as u64 != 0 { - return result; - } - if (*k).chunk() == 0 { + b"close\0" as *const u8 as *const libc::c_char, + ) { #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 1 as i32); + Curl_conncontrol(conn, 2 as i32); #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] Curl_conncontrol( conn, + 2 as i32, + b"Connection: close used\0" as *const u8 as *const libc::c_char, + ); + } else if (*k).http_bodyless() == 0 + && curl_strnequal( + b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char), + ) != 0 + { + result = Curl_build_unencoding_stack( + data, + headp.offset( + strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char) as isize, + ), 1 as i32, - b"HTTP/1.1 transfer-encoding without chunks\0" as *const u8 as *const libc::c_char, ); - (*k).set_ignore_cl(1 as i32 as bit); - } - } else if (*k).http_bodyless() == 0 - && curl_strnequal( - b"Content-Encoding:\0" as *const u8 as *const libc::c_char, + if result as u64 != 0 { + return result; + } + if (*k).chunk() == 0 { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 1 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 1 as i32, + b"HTTP/1.1 transfer-encoding without chunks\0" as *const u8 + as *const libc::c_char, + ); + (*k).set_ignore_cl(1 as i32 as bit); + } + } else if (*k).http_bodyless() == 0 + && curl_strnequal( + b"Content-Encoding:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Content-Encoding:\0" as *const u8 as *const libc::c_char), + ) != 0 + && !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null() + { + result = Curl_build_unencoding_stack( + data, + headp.offset( + strlen(b"Content-Encoding:\0" as *const u8 as *const libc::c_char) as isize, + ), + 0 as i32, + ); + if result as u64 != 0 { + return result; + } + } else if curl_strnequal( + b"Retry-After:\0" as *const u8 as *const libc::c_char, headp, - strlen(b"Content-Encoding:\0" as *const u8 as *const libc::c_char), + strlen(b"Retry-After:\0" as *const u8 as *const libc::c_char), ) != 0 - && !((*data).set.str_0[STRING_ENCODING as i32 as usize]).is_null() - { - result = Curl_build_unencoding_stack( - data, - headp.offset( - strlen(b"Content-Encoding:\0" as *const u8 as *const libc::c_char) as isize, - ), - 0 as i32, - ); - if result as u64 != 0 { - return result; - } - } else if curl_strnequal( - b"Retry-After:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Retry-After:\0" as *const u8 as *const libc::c_char), - ) != 0 - { - let mut retry_after: curl_off_t = 0 as i32 as curl_off_t; - let mut date: time_t = Curl_getdate_capped( - headp.offset(strlen(b"Retry-After:\0" as *const u8 as *const libc::c_char) as isize), - ); - if -(1 as i32) as i64 == date { - curlx_strtoofft( + { + let mut retry_after: curl_off_t = 0 as i32 as curl_off_t; + let mut date: time_t = Curl_getdate_capped( headp .offset(strlen(b"Retry-After:\0" as *const u8 as *const libc::c_char) as isize), - 0 as *mut *mut libc::c_char, - 10 as i32, - &mut retry_after, ); - } else { - retry_after = date - time(0 as *mut time_t); - } - (*data).info.retry_after = retry_after; - } else if (*k).http_bodyless() == 0 - && curl_strnequal( - b"Content-Range:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Content-Range:\0" as *const u8 as *const libc::c_char), - ) != 0 - { - let mut ptr: *mut libc::c_char = - headp.offset(strlen(b"Content-Range:\0" as *const u8 as *const libc::c_char) as isize); - while *ptr as i32 != 0 && Curl_isdigit(*ptr as u8 as i32) == 0 && *ptr as i32 != '*' as i32 + if -(1 as i32) as i64 == date { + curlx_strtoofft( + headp.offset( + strlen(b"Retry-After:\0" as *const u8 as *const libc::c_char) as isize, + ), + 0 as *mut *mut libc::c_char, + 10 as i32, + &mut retry_after, + ); + } else { + retry_after = date - time(0 as *mut time_t); + } + (*data).info.retry_after = retry_after; + } else if (*k).http_bodyless() == 0 + && curl_strnequal( + b"Content-Range:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Content-Range:\0" as *const u8 as *const libc::c_char), + ) != 0 { - ptr = ptr.offset(1); - } - if Curl_isdigit(*ptr as u8 as i32) != 0 { - if curlx_strtoofft( - ptr, - 0 as *mut *mut libc::c_char, - 10 as i32, - &mut (*k).offset, - ) as u64 - == 0 + let mut ptr: *mut libc::c_char = headp + .offset(strlen(b"Content-Range:\0" as *const u8 as *const libc::c_char) as isize); + while *ptr as i32 != 0 + && Curl_isdigit(*ptr as u8 as i32) == 0 + && *ptr as i32 != '*' as i32 { - if (*data).state.resume_from == (*k).offset { - (*k).set_content_range(1 as i32 as bit); - } + ptr = ptr.offset(1); } - } else { - (*data).state.resume_from = 0 as i32 as curl_off_t; - } - } else if flag3 { - let mut host: *const libc::c_char = if !((*data).state.aptr.cookiehost).is_null() { - (*data).state.aptr.cookiehost - } else { - (*conn).host.name - }; - let secure_context: bool = if (*(*conn).handler).protocol & ((1 as i32) << 1 as i32) as u32 - != 0 - || Curl_strcasecompare(b"localhost\0" as *const u8 as *const libc::c_char, host) != 0 - || strcmp(host, b"127.0.0.1\0" as *const u8 as *const libc::c_char) == 0 - || strcmp(host, b"[::1]\0" as *const u8 as *const libc::c_char) == 0 - { - 1 as i32 - } else { - 0 as i32 - } != 0; - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_add( - data, - (*data).cookies, - 1 as i32 != 0, - 0 as i32 != 0, - headp.offset(strlen(b"Set-Cookie:\0" as *const u8 as *const libc::c_char) as isize), - host, - (*data).state.up.path, - secure_context, - ); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } else if (*k).http_bodyless() == 0 - && curl_strnequal( - b"Last-Modified:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Last-Modified:\0" as *const u8 as *const libc::c_char), - ) != 0 - && ((*data).set.timecondition as u32 != 0 || ((*data).set).get_filetime() as i32 != 0) - { - (*k).timeofdoc = Curl_getdate_capped( - headp.offset(strlen(b"Last-Modified:\0" as *const u8 as *const libc::c_char) as isize), - ); - if ((*data).set).get_filetime() != 0 { - (*data).info.filetime = (*k).timeofdoc; - } - } else if curl_strnequal( - b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char), - ) != 0 - && 401 as i32 == (*k).httpcode - || curl_strnequal( - b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char, - headp, - strlen(b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char), - ) != 0 - && 407 as i32 == (*k).httpcode - { - let mut proxy: bool = if (*k).httpcode == 407 as i32 { - 1 as i32 - } else { - 0 as i32 - } != 0; - let mut auth: *mut libc::c_char = Curl_copy_header_value(headp); - if auth.is_null() { - return CURLE_OUT_OF_MEMORY; - } - result = Curl_http_input_auth(data, proxy, auth); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(auth as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - auth as *mut libc::c_void, - 3616 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); - if result as u64 != 0 { - return result; - } - } else if flag4 { - match () { - #[cfg(USE_SPNEGO)] - _ => { - let mut negdata: *mut negotiatedata = &mut (*conn).negotiate; - let mut authp: *mut auth = &mut (*data).state.authhost; - if (*authp).picked == (1 as i32 as u64) << 2 as i32 { - let mut persistentauth: *mut libc::c_char = Curl_copy_header_value(headp); - if persistentauth.is_null() { - return CURLE_OUT_OF_MEMORY; + if Curl_isdigit(*ptr as u8 as i32) != 0 { + if curlx_strtoofft( + ptr, + 0 as *mut *mut libc::c_char, + 10 as i32, + &mut (*k).offset, + ) as u64 + == 0 + { + if (*data).state.resume_from == (*k).offset { + (*k).set_content_range(1 as i32 as bit); } - (*negdata).set_noauthpersist( - (if curl_strnequal( - b"false\0" as *const u8 as *const libc::c_char, - persistentauth, - strlen(b"false\0" as *const u8 as *const libc::c_char), - ) != 0 - { - 1 as i32 - } else { - 0 as i32 - }) as bit, - ); - (*negdata).set_havenoauthpersist(1 as i32 as bit); - Curl_infof( - data, - b"Negotiate: noauthpersist -> %d, header part: %s\0" as *const u8 - as *const libc::c_char, - (*negdata).noauthpersist() as i32, - persistentauth, - ); - Curl_cfree.expect("non-null function pointer")( - persistentauth as *mut libc::c_void, - ); } + } else { + (*data).state.resume_from = 0 as i32 as curl_off_t; } - #[cfg(not(USE_SPNEGO))] - _ => {} - } - // let mut negdata: *mut negotiatedata = &mut (*conn).negotiate; - // let mut authp: *mut auth = &mut (*data).state.authhost; - // if (*authp).picked == (1 as i32 as u64) << 2 as i32 { - // let mut persistentauth: *mut libc::c_char = Curl_copy_header_value(headp); - // if persistentauth.is_null() { - // return CURLE_OUT_OF_MEMORY; - // } - // (*negdata) - // .set_noauthpersist( - // (if curl_strnequal( - // b"false\0" as *const u8 as *const libc::c_char, - // persistentauth, - // strlen(b"false\0" as *const u8 as *const libc::c_char), - // ) != 0 - // { - // 1 as i32 - // } else { - // 0 as i32 - // }) as bit, - // ); - // (*negdata).set_havenoauthpersist(1 as i32 as bit); - // Curl_infof( - // data, - // b"Negotiate: noauthpersist -> %d, header part: %s\0" as *const u8 - // as *const libc::c_char, - // (*negdata).noauthpersist() as i32, - // persistentauth, - // ); - // Curl_cfree - // .expect( - // "non-null function pointer", - // )(persistentauth as *mut libc::c_void); - // } - } else if (*k).httpcode >= 300 as i32 - && (*k).httpcode < 400 as i32 - && curl_strnequal( - b"Location:\0" as *const u8 as *const libc::c_char, + } else if flag3 { + let mut host: *const libc::c_char = if !((*data).state.aptr.cookiehost).is_null() { + (*data).state.aptr.cookiehost + } else { + (*conn).host.name + }; + let secure_context: bool = + if (*(*conn).handler).protocol & ((1 as i32) << 1 as i32) as u32 != 0 + || Curl_strcasecompare(b"localhost\0" as *const u8 as *const libc::c_char, host) + != 0 + || strcmp(host, b"127.0.0.1\0" as *const u8 as *const libc::c_char) == 0 + || strcmp(host, b"[::1]\0" as *const u8 as *const libc::c_char) == 0 + { + 1 as i32 + } else { + 0 as i32 + } != 0; + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + Curl_cookie_add( + data, + (*data).cookies, + 1 as i32 != 0, + 0 as i32 != 0, + headp.offset(strlen(b"Set-Cookie:\0" as *const u8 as *const libc::c_char) as isize), + host, + (*data).state.up.path, + secure_context, + ); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } else if (*k).http_bodyless() == 0 + && curl_strnequal( + b"Last-Modified:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Last-Modified:\0" as *const u8 as *const libc::c_char), + ) != 0 + && ((*data).set.timecondition as u32 != 0 || ((*data).set).get_filetime() as i32 != 0) + { + (*k).timeofdoc = + Curl_getdate_capped(headp.offset(strlen( + b"Last-Modified:\0" as *const u8 as *const libc::c_char, + ) as isize)); + if ((*data).set).get_filetime() != 0 { + (*data).info.filetime = (*k).timeofdoc; + } + } else if curl_strnequal( + b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char, headp, - strlen(b"Location:\0" as *const u8 as *const libc::c_char), + strlen(b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char), ) != 0 - && ((*data).req.location).is_null() - { - let mut location: *mut libc::c_char = Curl_copy_header_value(headp); - if location.is_null() { - return CURLE_OUT_OF_MEMORY; - } - if *location == 0 { + && 401 as i32 == (*k).httpcode + || curl_strnequal( + b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char), + ) != 0 + && 407 as i32 == (*k).httpcode + { + let mut proxy: bool = if (*k).httpcode == 407 as i32 { + 1 as i32 + } else { + 0 as i32 + } != 0; + let mut auth: *mut libc::c_char = Curl_copy_header_value(headp); + if auth.is_null() { + return CURLE_OUT_OF_MEMORY; + } + result = Curl_http_input_auth(data, proxy, auth); #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(location as *mut libc::c_void); + Curl_cfree.expect("non-null function pointer")(auth as *mut libc::c_void); #[cfg(CURLDEBUG)] curl_dbg_free( - location as *mut libc::c_void, - 3647 as i32, + auth as *mut libc::c_void, + 3616 as i32, b"http.c\0" as *const u8 as *const libc::c_char, ); - } else { - (*data).req.location = location; - if ((*data).set).http_follow_location() != 0 { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ((*data).req.newurl).is_null() { - } else { - __assert_fail( + if result as u64 != 0 { + return result; + } + } else if flag4 { + match () { + #[cfg(USE_SPNEGO)] + _ => { + let mut negdata: *mut negotiatedata = &mut (*conn).negotiate; + let mut authp: *mut auth = &mut (*data).state.authhost; + if (*authp).picked == (1 as i32 as u64) << 2 as i32 { + let mut persistentauth: *mut libc::c_char = Curl_copy_header_value(headp); + if persistentauth.is_null() { + return CURLE_OUT_OF_MEMORY; + } + (*negdata).set_noauthpersist( + (if curl_strnequal( + b"false\0" as *const u8 as *const libc::c_char, + persistentauth, + strlen(b"false\0" as *const u8 as *const libc::c_char), + ) != 0 + { + 1 as i32 + } else { + 0 as i32 + }) as bit, + ); + (*negdata).set_havenoauthpersist(1 as i32 as bit); + Curl_infof( + data, + b"Negotiate: noauthpersist -> %d, header part: %s\0" as *const u8 + as *const libc::c_char, + (*negdata).noauthpersist() as i32, + persistentauth, + ); + Curl_cfree.expect("non-null function pointer")( + persistentauth as *mut libc::c_void, + ); + } + } + #[cfg(not(USE_SPNEGO))] + _ => {} + } + // let mut negdata: *mut negotiatedata = &mut (*conn).negotiate; + // let mut authp: *mut auth = &mut (*data).state.authhost; + // if (*authp).picked == (1 as i32 as u64) << 2 as i32 { + // let mut persistentauth: *mut libc::c_char = Curl_copy_header_value(headp); + // if persistentauth.is_null() { + // return CURLE_OUT_OF_MEMORY; + // } + // (*negdata) + // .set_noauthpersist( + // (if curl_strnequal( + // b"false\0" as *const u8 as *const libc::c_char, + // persistentauth, + // strlen(b"false\0" as *const u8 as *const libc::c_char), + // ) != 0 + // { + // 1 as i32 + // } else { + // 0 as i32 + // }) as bit, + // ); + // (*negdata).set_havenoauthpersist(1 as i32 as bit); + // Curl_infof( + // data, + // b"Negotiate: noauthpersist -> %d, header part: %s\0" as *const u8 + // as *const libc::c_char, + // (*negdata).noauthpersist() as i32, + // persistentauth, + // ); + // Curl_cfree + // .expect( + // "non-null function pointer", + // )(persistentauth as *mut libc::c_void); + // } + } else if (*k).httpcode >= 300 as i32 + && (*k).httpcode < 400 as i32 + && curl_strnequal( + b"Location:\0" as *const u8 as *const libc::c_char, + headp, + strlen(b"Location:\0" as *const u8 as *const libc::c_char), + ) != 0 + && ((*data).req.location).is_null() + { + let mut location: *mut libc::c_char = Curl_copy_header_value(headp); + if location.is_null() { + return CURLE_OUT_OF_MEMORY; + } + if *location == 0 { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(location as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + location as *mut libc::c_void, + 3647 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + } else { + (*data).req.location = location; + if ((*data).set).http_follow_location() != 0 { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ((*data).req.newurl).is_null() { + } else { + __assert_fail( b"!data->req.newurl\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 3652 as i32 as u32, @@ -5772,92 +5951,94 @@ pub extern "C" fn Curl_http_header( )) .as_ptr(), ); - } - match () { - #[cfg(not(CURLDEBUG))] - _ => { - (*data).req.newurl = - Curl_cstrdup.expect("non-null function pointer")((*data).req.location); } - #[cfg(CURLDEBUG)] - _ => { - (*data).req.newurl = curl_dbg_strdup( - (*data).req.location, - 3653 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); + match () { + #[cfg(not(CURLDEBUG))] + _ => { + (*data).req.newurl = Curl_cstrdup.expect("non-null function pointer")( + (*data).req.location, + ); + } + #[cfg(CURLDEBUG)] + _ => { + (*data).req.newurl = curl_dbg_strdup( + (*data).req.location, + 3653 as i32, + b"http.c\0" as *const u8 as *const libc::c_char, + ); + } + } + if ((*data).req.newurl).is_null() { + return CURLE_OUT_OF_MEMORY; + } + result = http_perhapsrewind(data, conn); + if result as u64 != 0 { + return result; } - } - if ((*data).req.newurl).is_null() { - return CURLE_OUT_OF_MEMORY; - } - result = http_perhapsrewind(data, conn); - if result as u64 != 0 { - return result; } } - } - } else if flag5 { - match () { - #[cfg(not(CURL_DISABLE_HSTS))] - _ => { - let mut check: CURLcode = Curl_hsts_parse( - (*data).hsts, - (*data).state.up.hostname, - headp.offset(strlen( - b"Strict-Transport-Security:\0" as *const u8 as *const libc::c_char, - ) as isize), - ); - if check as u64 != 0 { - Curl_infof( - data, - b"Illegal STS header skipped\0" as *const u8 as *const libc::c_char, + } else if flag5 { + match () { + #[cfg(not(CURL_DISABLE_HSTS))] + _ => { + let mut check: CURLcode = Curl_hsts_parse( + (*data).hsts, + (*data).state.up.hostname, + headp.offset(strlen( + b"Strict-Transport-Security:\0" as *const u8 as *const libc::c_char, + ) as isize), ); - } else { - #[cfg(DEBUGBUILD)] - Curl_infof( + if check as u64 != 0 { + Curl_infof( + data, + b"Illegal STS header skipped\0" as *const u8 as *const libc::c_char, + ); + } else { + #[cfg(DEBUGBUILD)] + Curl_infof( + data, + b"Parsed STS header fine (%zu entries)\0" as *const u8 + as *const libc::c_char, + (*(*data).hsts).list.size, + ); + } + } + #[cfg(CURL_DISABLE_HSTS)] + _ => {} + } + } else if flag6 { + let mut id: alpnid = (if (*conn).httpversion as i32 == 20 as i32 { + ALPN_h2 as i32 + } else { + ALPN_h1 as i32 + }) as alpnid; + match () { + #[cfg(not(CURL_DISABLE_ALTSVC))] + _ => { + result = Curl_altsvc_parse( data, - b"Parsed STS header fine (%zu entries)\0" as *const u8 - as *const libc::c_char, - (*(*data).hsts).list.size, + (*data).asi, + headp.offset( + strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char) as isize + ), + id, + (*conn).host.name, + curlx_uitous((*conn).remote_port as u32), ); } + _ => {} } - #[cfg(CURL_DISABLE_HSTS)] - _ => {} - } - } else if flag6 { - let mut id: alpnid = (if (*conn).httpversion as i32 == 20 as i32 { - ALPN_h2 as i32 - } else { - ALPN_h1 as i32 - }) as alpnid; - match () { - #[cfg(not(CURL_DISABLE_ALTSVC))] - _ => { - result = Curl_altsvc_parse( - data, - (*data).asi, - headp - .offset(strlen(b"Alt-Svc:\0" as *const u8 as *const libc::c_char) as isize), - id, - (*conn).host.name, - curlx_uitous((*conn).remote_port as u32), - ); - } - _ => {} - } - if result as u64 != 0 { - return result; - } - } else if (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 { - result = Curl_rtsp_parseheader(data, headp); - if result as u64 != 0 { - return result; + if result as u64 != 0 { + return result; + } + } else if (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 { + result = Curl_rtsp_parseheader(data, headp); + if result as u64 != 0 { + return result; + } } } -} return CURLE_OK; } #[no_mangle] @@ -5865,77 +6046,78 @@ pub extern "C" fn Curl_http_statusline( mut data: *mut Curl_easy, mut conn: *mut connectdata, ) -> CURLcode { - let mut k: *mut SingleRequest =unsafe{ &mut (*data).req}; - unsafe{ - (*data).info.httpcode = (*k).httpcode; - (*data).info.httpversion = (*conn).httpversion as i32; - if (*data).state.httpversion == 0 - || (*data).state.httpversion as i32 > (*conn).httpversion as i32 - { - (*data).state.httpversion = (*conn).httpversion; - } - if (*data).state.resume_from != 0 - && (*data).state.httpreq as u32 == HTTPREQ_GET as i32 as u32 - && (*k).httpcode == 416 as i32 - { - (*k).set_ignorebody(1 as i32 as bit); - } - if (*conn).httpversion as i32 == 10 as i32 { - Curl_infof( - data, - b"HTTP 1.0, assume close after body\0" as *const u8 as *const libc::c_char, - ); - #[cfg(not(CURLDEBUG))] - Curl_conncontrol(conn, 1 as i32); - #[cfg(CURLDEBUG)] - Curl_conncontrol( - conn, - 1 as i32, - b"HTTP/1.0 close after body\0" as *const u8 as *const libc::c_char, - ); - } else if (*conn).httpversion as i32 == 20 as i32 - || (*k).upgr101 as u32 == UPGR101_REQUESTED as i32 as u32 && (*k).httpcode == 101 as i32 - { - #[cfg(DEBUGBUILD)] - Curl_infof( - data, - b"HTTP/2 found, allow multiplexing\0" as *const u8 as *const libc::c_char, - ); - (*(*conn).bundle).multiuse = 2 as i32; - } else if (*conn).httpversion as i32 >= 11 as i32 && ((*conn).bits).close() == 0 { - #[cfg(DEBUGBUILD)] - Curl_infof( - data, - b"HTTP 1.1 or later with persistent connection\0" as *const u8 as *const libc::c_char, - ); - } - (*k).set_http_bodyless( - ((*k).httpcode >= 100 as i32 && (*k).httpcode < 200 as i32) as i32 as bit, - ); - let mut current_block_25: u64; - match (*k).httpcode { - 304 => { - if (*data).set.timecondition as u64 != 0 { - (*data).info.set_timecond(1 as i32 as bit); - } - current_block_25 = 14741359113768901450; + let mut k: *mut SingleRequest = unsafe { &mut (*data).req }; + unsafe { + (*data).info.httpcode = (*k).httpcode; + (*data).info.httpversion = (*conn).httpversion as i32; + if (*data).state.httpversion == 0 + || (*data).state.httpversion as i32 > (*conn).httpversion as i32 + { + (*data).state.httpversion = (*conn).httpversion; + } + if (*data).state.resume_from != 0 + && (*data).state.httpreq as u32 == HTTPREQ_GET as i32 as u32 + && (*k).httpcode == 416 as i32 + { + (*k).set_ignorebody(1 as i32 as bit); } - 204 => { - current_block_25 = 14741359113768901450; + if (*conn).httpversion as i32 == 10 as i32 { + Curl_infof( + data, + b"HTTP 1.0, assume close after body\0" as *const u8 as *const libc::c_char, + ); + #[cfg(not(CURLDEBUG))] + Curl_conncontrol(conn, 1 as i32); + #[cfg(CURLDEBUG)] + Curl_conncontrol( + conn, + 1 as i32, + b"HTTP/1.0 close after body\0" as *const u8 as *const libc::c_char, + ); + } else if (*conn).httpversion as i32 == 20 as i32 + || (*k).upgr101 as u32 == UPGR101_REQUESTED as i32 as u32 && (*k).httpcode == 101 as i32 + { + #[cfg(DEBUGBUILD)] + Curl_infof( + data, + b"HTTP/2 found, allow multiplexing\0" as *const u8 as *const libc::c_char, + ); + (*(*conn).bundle).multiuse = 2 as i32; + } else if (*conn).httpversion as i32 >= 11 as i32 && ((*conn).bits).close() == 0 { + #[cfg(DEBUGBUILD)] + Curl_infof( + data, + b"HTTP 1.1 or later with persistent connection\0" as *const u8 + as *const libc::c_char, + ); } - _ => { - current_block_25 = 14763689060501151050; + (*k).set_http_bodyless( + ((*k).httpcode >= 100 as i32 && (*k).httpcode < 200 as i32) as i32 as bit, + ); + let mut current_block_25: u64; + match (*k).httpcode { + 304 => { + if (*data).set.timecondition as u64 != 0 { + (*data).info.set_timecond(1 as i32 as bit); + } + current_block_25 = 14741359113768901450; + } + 204 => { + current_block_25 = 14741359113768901450; + } + _ => { + current_block_25 = 14763689060501151050; + } } - } - match current_block_25 { - 14741359113768901450 => { - (*k).size = 0 as i32 as curl_off_t; - (*k).maxdownload = 0 as i32 as curl_off_t; - (*k).set_http_bodyless(1 as i32 as bit); + match current_block_25 { + 14741359113768901450 => { + (*k).size = 0 as i32 as curl_off_t; + (*k).maxdownload = 0 as i32 as curl_off_t; + (*k).set_http_bodyless(1 as i32 as bit); + } + _ => {} } - _ => {} } -} return CURLE_OK; } @@ -5950,286 +6132,289 @@ pub extern "C" fn Curl_http_readwrite_headers( mut stop_reading: *mut bool, ) -> CURLcode { let mut result: CURLcode = CURLE_OK; - let mut k: *mut SingleRequest =unsafe{ &mut (*data).req}; - let mut onread: ssize_t =unsafe{ *nread}; - let mut ostr: *mut libc::c_char = unsafe{(*k).str_0}; + let mut k: *mut SingleRequest = unsafe { &mut (*data).req }; + let mut onread: ssize_t = unsafe { *nread }; + let mut ostr: *mut libc::c_char = unsafe { (*k).str_0 }; let mut headp: *mut libc::c_char = 0 as *mut libc::c_char; let mut str_start: *mut libc::c_char = 0 as *mut libc::c_char; let mut end_ptr: *mut libc::c_char = 0 as *mut libc::c_char; - unsafe{ - /* header line within buffer loop */ - loop { - let mut rest_length: size_t = 0; - let mut full_length: size_t = 0; - let mut writetype: i32 = 0; - - /* str_start is start of line within buf */ - str_start = (*k).str_0; - - /* data is in network encoding so use 0x0a instead of '\n' */ - end_ptr = memchr(str_start as *const libc::c_void, 0xa as i32, *nread as u64) - as *mut libc::c_char; - if end_ptr.is_null() { - /* Not a complete header line within buffer, append the data to - the end of the headerbuff. */ - result = Curl_dyn_addn( - &mut (*data).state.headerb, - str_start as *const libc::c_void, - *nread as size_t, - ); - if result as u64 != 0 { - return result; - } - - if !((*k).headerline == 0) { - /* check if this looks like a protocol header */ - break; - } - let mut st: statusline = checkprotoprefix( - data, - conn, - Curl_dyn_ptr(&mut (*data).state.headerb), - Curl_dyn_len(&mut (*data).state.headerb), - ); - if !(st as u32 == STATUS_BAD as i32 as u32) { - break; - } - (*k).set_header(0 as i32 as bit); - (*k).badheader = HEADER_ALLBAD; - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 2 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 2 as i32, - b"bad HTTP: No end-of-message indicator\0" as *const u8 as *const libc::c_char, - ); - if ((*data).set).http09_allowed() == 0 { - Curl_failf( - data, - b"Received HTTP/0.9 when not allowed\0" as *const u8 as *const libc::c_char, + unsafe { + /* header line within buffer loop */ + loop { + let mut rest_length: size_t = 0; + let mut full_length: size_t = 0; + let mut writetype: i32 = 0; + + /* str_start is start of line within buf */ + str_start = (*k).str_0; + + /* data is in network encoding so use 0x0a instead of '\n' */ + end_ptr = memchr(str_start as *const libc::c_void, 0xa as i32, *nread as u64) + as *mut libc::c_char; + if end_ptr.is_null() { + /* Not a complete header line within buffer, append the data to + the end of the headerbuff. */ + result = Curl_dyn_addn( + &mut (*data).state.headerb, + str_start as *const libc::c_void, + *nread as size_t, ); - return CURLE_UNSUPPORTED_PROTOCOL; - } - break; - } else { - rest_length = (end_ptr.offset_from((*k).str_0) as i64 + 1 as i32 as i64) as size_t; - *nread -= rest_length as ssize_t; - (*k).str_0 = end_ptr.offset(1 as isize); - full_length = ((*k).str_0).offset_from(str_start) as i64 as size_t; - result = Curl_dyn_addn( - &mut (*data).state.headerb, - str_start as *const libc::c_void, - full_length, - ); - if result as u64 != 0 { - return result; - } - if (*k).headerline == 0 { - let mut st_0: statusline = checkprotoprefix( + if result as u64 != 0 { + return result; + } + + if !((*k).headerline == 0) { + /* check if this looks like a protocol header */ + break; + } + let mut st: statusline = checkprotoprefix( data, conn, Curl_dyn_ptr(&mut (*data).state.headerb), Curl_dyn_len(&mut (*data).state.headerb), ); - if st_0 as u32 == STATUS_BAD as i32 as u32 { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 2 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( + if !(st as u32 == STATUS_BAD as i32 as u32) { + break; + } + (*k).set_header(0 as i32 as bit); + (*k).badheader = HEADER_ALLBAD; + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 2 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 2 as i32, + b"bad HTTP: No end-of-message indicator\0" as *const u8 as *const libc::c_char, + ); + if ((*data).set).http09_allowed() == 0 { + Curl_failf( + data, + b"Received HTTP/0.9 when not allowed\0" as *const u8 as *const libc::c_char, + ); + return CURLE_UNSUPPORTED_PROTOCOL; + } + break; + } else { + rest_length = (end_ptr.offset_from((*k).str_0) as i64 + 1 as i32 as i64) as size_t; + *nread -= rest_length as ssize_t; + (*k).str_0 = end_ptr.offset(1 as isize); + full_length = ((*k).str_0).offset_from(str_start) as i64 as size_t; + result = Curl_dyn_addn( + &mut (*data).state.headerb, + str_start as *const libc::c_void, + full_length, + ); + if result as u64 != 0 { + return result; + } + if (*k).headerline == 0 { + let mut st_0: statusline = checkprotoprefix( + data, conn, - 2 as i32, - b"bad HTTP: No end-of-message indicator\0" as *const u8 - as *const libc::c_char, + Curl_dyn_ptr(&mut (*data).state.headerb), + Curl_dyn_len(&mut (*data).state.headerb), ); - if ((*data).set).http09_allowed() == 0 { - Curl_failf( - data, - b"Received HTTP/0.9 when not allowed\0" as *const u8 + if st_0 as u32 == STATUS_BAD as i32 as u32 { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 2 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 2 as i32, + b"bad HTTP: No end-of-message indicator\0" as *const u8 as *const libc::c_char, ); - return CURLE_UNSUPPORTED_PROTOCOL; - } - (*k).set_header(0 as i32 as bit); - if *nread != 0 { - (*k).badheader = HEADER_PARTHEADER; - } else { - (*k).badheader = HEADER_ALLBAD; - *nread = onread; - (*k).str_0 = ostr; - return CURLE_OK; + if ((*data).set).http09_allowed() == 0 { + Curl_failf( + data, + b"Received HTTP/0.9 when not allowed\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_UNSUPPORTED_PROTOCOL; + } + (*k).set_header(0 as i32 as bit); + if *nread != 0 { + (*k).badheader = HEADER_PARTHEADER; + } else { + (*k).badheader = HEADER_ALLBAD; + *nread = onread; + (*k).str_0 = ostr; + return CURLE_OK; + } + break; } - break; - } - } - headp = Curl_dyn_ptr(&mut (*data).state.headerb); - if 0xa as i32 == *headp as i32 || 0xd as i32 == *headp as i32 { - let mut headerlen: size_t = 0; - #[cfg(not(CURL_DOES_CONVERSIONS))] - if '\r' as i32 == *headp as i32 { - headp = headp.offset(1); } - #[cfg(not(CURL_DOES_CONVERSIONS))] - if '\n' as i32 == *headp as i32 { - headp = headp.offset(1); - } - if 100 as i32 <= (*k).httpcode && 199 as i32 >= (*k).httpcode { - match (*k).httpcode { - 100 => { - (*k).set_header(1 as i32 as bit); - (*k).headerline = 0 as i32; - if (*k).exp100 as u32 > EXP100_SEND_DATA as i32 as u32 { - (*k).exp100 = EXP100_SEND_DATA; - (*k).keepon |= (1 as i32) << 1 as i32; - Curl_expire_done(data, EXPIRE_100_TIMEOUT); - } - } - 101 => { - if (*k).upgr101 as u32 == UPGR101_REQUESTED as i32 as u32 { - Curl_infof( - data, - b"Received 101\0" as *const u8 as *const libc::c_char, - ); - (*k).upgr101 = UPGR101_RECEIVED; + headp = Curl_dyn_ptr(&mut (*data).state.headerb); + if 0xa as i32 == *headp as i32 || 0xd as i32 == *headp as i32 { + let mut headerlen: size_t = 0; + #[cfg(not(CURL_DOES_CONVERSIONS))] + if '\r' as i32 == *headp as i32 { + headp = headp.offset(1); + } + #[cfg(not(CURL_DOES_CONVERSIONS))] + if '\n' as i32 == *headp as i32 { + headp = headp.offset(1); + } + if 100 as i32 <= (*k).httpcode && 199 as i32 >= (*k).httpcode { + match (*k).httpcode { + 100 => { (*k).set_header(1 as i32 as bit); (*k).headerline = 0 as i32; - result = Curl_http2_switched(data, (*k).str_0, *nread as size_t); - if result as u64 != 0 { - return result; + if (*k).exp100 as u32 > EXP100_SEND_DATA as i32 as u32 { + (*k).exp100 = EXP100_SEND_DATA; + (*k).keepon |= (1 as i32) << 1 as i32; + Curl_expire_done(data, EXPIRE_100_TIMEOUT); } - *nread = 0 as i32 as ssize_t; - } else { - (*k).set_header(0 as i32 as bit); + } + 101 => { + if (*k).upgr101 as u32 == UPGR101_REQUESTED as i32 as u32 { + Curl_infof( + data, + b"Received 101\0" as *const u8 as *const libc::c_char, + ); + (*k).upgr101 = UPGR101_RECEIVED; + (*k).set_header(1 as i32 as bit); + (*k).headerline = 0 as i32; + result = + Curl_http2_switched(data, (*k).str_0, *nread as size_t); + if result as u64 != 0 { + return result; + } + *nread = 0 as i32 as ssize_t; + } else { + (*k).set_header(0 as i32 as bit); + } + } + _ => { + (*k).set_header(1 as i32 as bit); + (*k).headerline = 0 as i32; } } - _ => { - (*k).set_header(1 as i32 as bit); - (*k).headerline = 0 as i32; + } else { + (*k).set_header(0 as i32 as bit); + if (*k).size == -(1 as i32) as i64 + && (*k).chunk() == 0 + && ((*conn).bits).close() == 0 + && (*conn).httpversion as i32 == 11 as i32 + && (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 == 0 + && (*data).state.httpreq as u32 != HTTPREQ_HEAD as i32 as u32 + { + Curl_infof( + data, + b"no chunk, no close, no size. Assume close to signal end\0" + as *const u8 + as *const libc::c_char, + ); + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 2 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 2 as i32, + b"HTTP: No end-of-message indicator\0" as *const u8 + as *const libc::c_char, + ); } } - } else { - (*k).set_header(0 as i32 as bit); - if (*k).size == -(1 as i32) as i64 - && (*k).chunk() == 0 - && ((*conn).bits).close() == 0 - && (*conn).httpversion as i32 == 11 as i32 - && (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 == 0 - && (*data).state.httpreq as u32 != HTTPREQ_HEAD as i32 as u32 + #[cfg(USE_NTLM)] + if ((*conn).bits).close() as i32 != 0 + && ((*data).req.httpcode == 401 as i32 + && (*conn).http_ntlm_state as u32 == NTLMSTATE_TYPE2 as i32 as u32 + || (*data).req.httpcode == 407 as i32 + && (*conn).proxy_ntlm_state as u32 == NTLMSTATE_TYPE2 as i32 as u32) { Curl_infof( data, - b"no chunk, no close, no size. Assume close to signal end\0" - as *const u8 as *const libc::c_char, + b"Connection closure while negotiating auth (HTTP 1.0?)\0" as *const u8 + as *const libc::c_char, ); - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 2 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 2 as i32, - b"HTTP: No end-of-message indicator\0" as *const u8 + (*data).state.set_authproblem(1 as i32 as bit); + } + #[cfg(USE_SPNEGO)] + if ((*conn).bits).close() as i32 != 0 + && ((*data).req.httpcode == 401 as i32 + && (*conn).http_negotiate_state as u32 == GSS_AUTHRECV as i32 as u32 + || (*data).req.httpcode == 407 as i32 + && (*conn).proxy_negotiate_state as u32 + == GSS_AUTHRECV as i32 as u32) + { + Curl_infof( + data, + b"Connection closure while negotiating auth (HTTP 1.0?)\0" as *const u8 as *const libc::c_char, ); + let ref mut fresh89 = (*data).state; + (*fresh89).set_authproblem(1 as i32 as bit); } - } - #[cfg(USE_NTLM)] - if ((*conn).bits).close() as i32 != 0 - && ((*data).req.httpcode == 401 as i32 - && (*conn).http_ntlm_state as u32 == NTLMSTATE_TYPE2 as i32 as u32 - || (*data).req.httpcode == 407 as i32 - && (*conn).proxy_ntlm_state as u32 == NTLMSTATE_TYPE2 as i32 as u32) - { - Curl_infof( - data, - b"Connection closure while negotiating auth (HTTP 1.0?)\0" as *const u8 - as *const libc::c_char, - ); - (*data).state.set_authproblem(1 as i32 as bit); - } - #[cfg(USE_SPNEGO)] - if ((*conn).bits).close() as i32 != 0 - && ((*data).req.httpcode == 401 as i32 - && (*conn).http_negotiate_state as u32 == GSS_AUTHRECV as i32 as u32 - || (*data).req.httpcode == 407 as i32 - && (*conn).proxy_negotiate_state as u32 == GSS_AUTHRECV as i32 as u32) - { - Curl_infof( - data, - b"Connection closure while negotiating auth (HTTP 1.0?)\0" as *const u8 - as *const libc::c_char, - ); - let ref mut fresh89 = (*data).state; - (*fresh89).set_authproblem(1 as i32 as bit); - } - #[cfg(USE_SPNEGO)] - if (*conn).http_negotiate_state as u32 == GSS_AUTHDONE as i32 as u32 - && (*data).req.httpcode != 401 as i32 - { - (*conn).http_negotiate_state = GSS_AUTHSUCC; - } - #[cfg(USE_SPNEGO)] - if (*conn).proxy_negotiate_state as u32 == GSS_AUTHDONE as i32 as u32 - && (*data).req.httpcode != 407 as i32 - { - (*conn).proxy_negotiate_state = GSS_AUTHSUCC; - } - writetype = (1 as i32) << 1 as i32; - if ((*data).set).include_header() != 0 { - writetype |= (1 as i32) << 0 as i32; - } - headerlen = Curl_dyn_len(&mut (*data).state.headerb); - result = Curl_client_write( - data, - writetype, - Curl_dyn_ptr(&mut (*data).state.headerb), - headerlen, - ); - if result as u64 != 0 { - return result; - } - (*data).info.header_size += headerlen as i64; - (*data).req.headerbytecount += headerlen as i64; - if http_should_fail(data) { - Curl_failf( + #[cfg(USE_SPNEGO)] + if (*conn).http_negotiate_state as u32 == GSS_AUTHDONE as i32 as u32 + && (*data).req.httpcode != 401 as i32 + { + (*conn).http_negotiate_state = GSS_AUTHSUCC; + } + #[cfg(USE_SPNEGO)] + if (*conn).proxy_negotiate_state as u32 == GSS_AUTHDONE as i32 as u32 + && (*data).req.httpcode != 407 as i32 + { + (*conn).proxy_negotiate_state = GSS_AUTHSUCC; + } + writetype = (1 as i32) << 1 as i32; + if ((*data).set).include_header() != 0 { + writetype |= (1 as i32) << 0 as i32; + } + headerlen = Curl_dyn_len(&mut (*data).state.headerb); + result = Curl_client_write( data, - b"The requested URL returned error: %d\0" as *const u8 - as *const libc::c_char, - (*k).httpcode, + writetype, + Curl_dyn_ptr(&mut (*data).state.headerb), + headerlen, ); - return CURLE_HTTP_RETURNED_ERROR; - } - (*data).req.deductheadercount = - if 100 as i32 <= (*k).httpcode && 199 as i32 >= (*k).httpcode { - (*data).req.headerbytecount - } else { - 0 as i32 as i64 - }; - result = Curl_http_auth_act(data); - if result as u64 != 0 { - return result; - } - if (*k).httpcode >= 300 as i32 { - if ((*conn).bits).authneg() == 0 - && ((*conn).bits).close() == 0 - && ((*conn).bits).rewindaftersend() == 0 - { - match (*data).state.httpreq as u32 { - 4 | 1 | 2 | 3 => { - Curl_expire_done(data, EXPIRE_100_TIMEOUT); - if (*k).upload_done() == 0 { - if (*k).httpcode == 417 as i32 - && ((*data).state).expect100header() as i32 != 0 - { - Curl_infof( - data, - b"Got 417 while waiting for a 100\0" as *const u8 - as *const libc::c_char, - ); - (*data).state.set_disableexpect(1 as bit); - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ((*data).req.newurl).is_null() { - } else { - __assert_fail( + if result as u64 != 0 { + return result; + } + (*data).info.header_size += headerlen as i64; + (*data).req.headerbytecount += headerlen as i64; + if http_should_fail(data) { + Curl_failf( + data, + b"The requested URL returned error: %d\0" as *const u8 + as *const libc::c_char, + (*k).httpcode, + ); + return CURLE_HTTP_RETURNED_ERROR; + } + (*data).req.deductheadercount = + if 100 as i32 <= (*k).httpcode && 199 as i32 >= (*k).httpcode { + (*data).req.headerbytecount + } else { + 0 as i32 as i64 + }; + result = Curl_http_auth_act(data); + if result as u64 != 0 { + return result; + } + if (*k).httpcode >= 300 as i32 { + if ((*conn).bits).authneg() == 0 + && ((*conn).bits).close() == 0 + && ((*conn).bits).rewindaftersend() == 0 + { + match (*data).state.httpreq as u32 { + 4 | 1 | 2 | 3 => { + Curl_expire_done(data, EXPIRE_100_TIMEOUT); + if (*k).upload_done() == 0 { + if (*k).httpcode == 417 as i32 + && ((*data).state).expect100header() as i32 != 0 + { + Curl_infof( + data, + b"Got 417 while waiting for a 100\0" as *const u8 + as *const libc::c_char, + ); + (*data).state.set_disableexpect(1 as bit); + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ((*data).req.newurl).is_null() { + } else { + __assert_fail( b"!data->req.newurl\0" as *const u8 as *const libc::c_char, b"http.c\0" as *const u8 as *const libc::c_char, 4084 as i32 as u32, @@ -6241,321 +6426,328 @@ pub extern "C" fn Curl_http_readwrite_headers( )) .as_ptr(), ); - } - match () { - #[cfg(not(CURLDEBUG))] - _ => { - (*data).req.newurl = Curl_cstrdup - .expect("non-null function pointer")( - (*data).state.url, - ); } - #[cfg(CURLDEBUG)] - _ => { - (*data).req.newurl = curl_dbg_strdup( - (*data).state.url, - 4085 as i32, - b"http.c\0" as *const u8 as *const libc::c_char, - ); + match () { + #[cfg(not(CURLDEBUG))] + _ => { + (*data).req.newurl = Curl_cstrdup + .expect("non-null function pointer")( + (*data).state.url, + ); + } + #[cfg(CURLDEBUG)] + _ => { + (*data).req.newurl = curl_dbg_strdup( + (*data).state.url, + 4085 as i32, + b"http.c\0" as *const u8 + as *const libc::c_char, + ); + } + } + Curl_done_sending(data, k); + } else if ((*data).set).http_keep_sending_on_error() != 0 { + Curl_infof( + data, + b"HTTP error before end of send, keep sending\0" + as *const u8 + as *const libc::c_char, + ); + if (*k).exp100 as u32 > EXP100_SEND_DATA as i32 as u32 { + (*k).exp100 = EXP100_SEND_DATA; + (*k).keepon |= (1 as i32) << 1 as i32; + } + } else { + Curl_infof( + data, + b"HTTP error before end of send, stop sending\0" + as *const u8 + as *const libc::c_char, + ); + #[cfg(not(all( + DEBUGBUILD, + not(CURL_DISABLE_VERBOSE_STRINGS) + )))] + Curl_conncontrol(conn, 2 as i32); + #[cfg(all( + DEBUGBUILD, + not(CURL_DISABLE_VERBOSE_STRINGS) + ))] + Curl_conncontrol( + conn, + 2 as i32, + b"Stop sending data before everything sent\0" + as *const u8 + as *const libc::c_char, + ); + result = Curl_done_sending(data, k); + if result as u64 != 0 { + return result; + } + (*k).set_upload_done(1 as i32 as bit); + if ((*data).state).expect100header() != 0 { + (*k).exp100 = EXP100_FAILED; } - } - Curl_done_sending(data, k); - } else if ((*data).set).http_keep_sending_on_error() != 0 { - Curl_infof( - data, - b"HTTP error before end of send, keep sending\0" - as *const u8 - as *const libc::c_char, - ); - if (*k).exp100 as u32 > EXP100_SEND_DATA as i32 as u32 { - (*k).exp100 = EXP100_SEND_DATA; - (*k).keepon |= (1 as i32) << 1 as i32; - } - } else { - Curl_infof( - data, - b"HTTP error before end of send, stop sending\0" - as *const u8 - as *const libc::c_char, - ); - #[cfg(not(all( - DEBUGBUILD, - not(CURL_DISABLE_VERBOSE_STRINGS) - )))] - Curl_conncontrol(conn, 2 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 2 as i32, - b"Stop sending data before everything sent\0" - as *const u8 - as *const libc::c_char, - ); - result = Curl_done_sending(data, k); - if result as u64 != 0 { - return result; - } - (*k).set_upload_done(1 as i32 as bit); - if ((*data).state).expect100header() != 0 { - (*k).exp100 = EXP100_FAILED; } } } + _ => {} } - _ => {} + } + if ((*conn).bits).rewindaftersend() != 0 { + Curl_infof( + data, + b"Keep sending data to get tossed away!\0" as *const u8 + as *const libc::c_char, + ); + (*k).keepon |= (1 as i32) << 1 as i32; } } - if ((*conn).bits).rewindaftersend() != 0 { - Curl_infof( - data, - b"Keep sending data to get tossed away!\0" as *const u8 - as *const libc::c_char, - ); - (*k).keepon |= (1 as i32) << 1 as i32; - } - } - // 解决clippy错误 - if (*k).header() == 0 { - // TODO 待测试 - #[cfg(not(CURL_DISABLE_RSTP))] - let flag7: bool = ((*data).set).opt_no_body() != 0 - || (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 - && (*data).set.rtspreq as u32 == RTSPREQ_DESCRIBE as i32 as u32 - && (*k).size <= -(1 as i32) as i64; - #[cfg(CURL_DISABLE_RSTP)] - let flag7: bool = ((*data).set).opt_no_body() != 0; - // let flag7: bool = if cfg!(not(CURL_DISABLE_RSTP)) { - // ((*data).set).opt_no_body() != 0 - // || (*(*conn).handler).protocol - // & ((1 as i32) << 18 as i32) as u32 - // != 0 - // && (*data).set.rtspreq as u32 - // == RTSPREQ_DESCRIBE as i32 as u32 - // && (*k).size <= -(1 as i32) as i64 - // } else { - // ((*data).set).opt_no_body() != 0 - // }; - if flag7 { - *stop_reading = 1 as i32 != 0; - // } else if (*(*conn).handler).protocol - // & ((1 as i32) << 18 as i32) as u32 - // != 0 - // && (*data).set.rtspreq as u32 - // == RTSPREQ_DESCRIBE as i32 as u32 - // && (*k).size <= -(1 as i32) as i64 - // { - // *stop_reading = 1 as i32 != 0; - } else if (*k).chunk() != 0 { - let ref mut fresh89 = (*k).size; - *fresh89 = -(1 as i32) as curl_off_t; - (*k).maxdownload = *fresh89; - } - if -(1 as i32) as i64 != (*k).size { - Curl_pgrsSetDownloadSize(data, (*k).size); - (*k).maxdownload = (*k).size; + // 解决clippy错误 + if (*k).header() == 0 { + // TODO 待测试 + #[cfg(not(CURL_DISABLE_RSTP))] + let flag7: bool = ((*data).set).opt_no_body() != 0 + || (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 + && (*data).set.rtspreq as u32 == RTSPREQ_DESCRIBE as i32 as u32 + && (*k).size <= -(1 as i32) as i64; + #[cfg(CURL_DISABLE_RSTP)] + let flag7: bool = ((*data).set).opt_no_body() != 0; + // let flag7: bool = if cfg!(not(CURL_DISABLE_RSTP)) { + // ((*data).set).opt_no_body() != 0 + // || (*(*conn).handler).protocol + // & ((1 as i32) << 18 as i32) as u32 + // != 0 + // && (*data).set.rtspreq as u32 + // == RTSPREQ_DESCRIBE as i32 as u32 + // && (*k).size <= -(1 as i32) as i64 + // } else { + // ((*data).set).opt_no_body() != 0 + // }; + if flag7 { + *stop_reading = 1 as i32 != 0; + // } else if (*(*conn).handler).protocol + // & ((1 as i32) << 18 as i32) as u32 + // != 0 + // && (*data).set.rtspreq as u32 + // == RTSPREQ_DESCRIBE as i32 as u32 + // && (*k).size <= -(1 as i32) as i64 + // { + // *stop_reading = 1 as i32 != 0; + } else if (*k).chunk() != 0 { + let ref mut fresh89 = (*k).size; + *fresh89 = -(1 as i32) as curl_off_t; + (*k).maxdownload = *fresh89; + } + if -(1 as i32) as i64 != (*k).size { + Curl_pgrsSetDownloadSize(data, (*k).size); + (*k).maxdownload = (*k).size; + } + #[cfg(USE_NGHTTP2)] + let flag8: bool = 0 as i32 as i64 == (*k).maxdownload + && !((*(*conn).handler).protocol + & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32) as u32 + != 0 + && (*conn).httpversion as i32 == 20 as i32); + #[cfg(not(USE_NGHTTP2))] + let flag8: bool = 0 as i32 as i64 == (*k).maxdownload; + if flag8 { + *stop_reading = 1 as i32 != 0; + } + if *stop_reading { + (*k).keepon &= !((1 as i32) << 0 as i32); + } + Curl_debug(data, CURLINFO_HEADER_IN, str_start, headerlen); + break; + } else { + Curl_dyn_reset(&mut (*data).state.headerb); } - #[cfg(USE_NGHTTP2)] - let flag8: bool = 0 as i32 as i64 == (*k).maxdownload - && !((*(*conn).handler).protocol + } else { + let ref mut fresh90 = (*k).headerline; + let fresh91 = *fresh90; + *fresh90 = *fresh90 + 1; + if fresh91 == 0 { + let mut httpversion_major: i32 = 0; + let mut rtspversion_major: i32 = 0; + let mut nc: i32 = 0 as i32; + if (*(*conn).handler).protocol & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32) as u32 != 0 - && (*conn).httpversion as i32 == 20 as i32); - #[cfg(not(USE_NGHTTP2))] - let flag8: bool = 0 as i32 as i64 == (*k).maxdownload; - if flag8 { - *stop_reading = 1 as i32 != 0; - } - if *stop_reading { - (*k).keepon &= !((1 as i32) << 0 as i32); - } - Curl_debug(data, CURLINFO_HEADER_IN, str_start, headerlen); - break; - } else { - Curl_dyn_reset(&mut (*data).state.headerb); - } - } else { - let ref mut fresh90 = (*k).headerline; - let fresh91 = *fresh90; - *fresh90 = *fresh90 + 1; - if fresh91 == 0 { - let mut httpversion_major: i32 = 0; - let mut rtspversion_major: i32 = 0; - let mut nc: i32 = 0 as i32; - if (*(*conn).handler).protocol - & ((1 as i32) << 0 as i32 | (1 as i32) << 1 as i32) as u32 - != 0 - { - let mut separator: libc::c_char = 0; - let mut twoorthree: [libc::c_char; 2] = [0; 2]; - let mut httpversion: i32 = 0 as i32; - let mut digit4: libc::c_char = 0 as i32 as libc::c_char; - nc = sscanf( - headp, - b" HTTP/%1d.%1d%c%3d%c\0" as *const u8 as *const libc::c_char, - &mut httpversion_major as *mut i32, - &mut httpversion as *mut i32, - &mut separator as *mut libc::c_char, - &mut (*k).httpcode as *mut i32, - &mut digit4 as *mut libc::c_char, - ); - if nc == 1 as i32 - && httpversion_major >= 2 as i32 - && 2 as i32 - == sscanf( - headp, - b" HTTP/%1[23] %d\0" as *const u8 as *const libc::c_char, - twoorthree.as_mut_ptr(), - &mut (*k).httpcode as *mut i32, - ) { - (*conn).httpversion = 0 as i32 as u8; - nc = 4 as i32; - separator = ' ' as i32 as libc::c_char; - } else if Curl_isdigit(digit4 as u8 as i32) != 0 { - Curl_failf( - data, - b"Unsupported response code in HTTP response\0" as *const u8 - as *const libc::c_char, + let mut separator: libc::c_char = 0; + let mut twoorthree: [libc::c_char; 2] = [0; 2]; + let mut httpversion: i32 = 0 as i32; + let mut digit4: libc::c_char = 0 as i32 as libc::c_char; + nc = sscanf( + headp, + b" HTTP/%1d.%1d%c%3d%c\0" as *const u8 as *const libc::c_char, + &mut httpversion_major as *mut i32, + &mut httpversion as *mut i32, + &mut separator as *mut libc::c_char, + &mut (*k).httpcode as *mut i32, + &mut digit4 as *mut libc::c_char, ); - return CURLE_UNSUPPORTED_PROTOCOL; - } - if nc >= 4 as i32 && ' ' as i32 == separator as i32 { - httpversion += 10 as i32 * httpversion_major; - match httpversion { - 10 | 11 => { - (*conn).httpversion = httpversion as u8; - } - #[cfg(any(USE_NGHTTP2, USE_HYPER))] - 20 => { - (*conn).httpversion = httpversion as u8; + if nc == 1 as i32 + && httpversion_major >= 2 as i32 + && 2 as i32 + == sscanf( + headp, + b" HTTP/%1[23] %d\0" as *const u8 as *const libc::c_char, + twoorthree.as_mut_ptr(), + &mut (*k).httpcode as *mut i32, + ) + { + (*conn).httpversion = 0 as i32 as u8; + nc = 4 as i32; + separator = ' ' as i32 as libc::c_char; + } else if Curl_isdigit(digit4 as u8 as i32) != 0 { + Curl_failf( + data, + b"Unsupported response code in HTTP response\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_UNSUPPORTED_PROTOCOL; + } + if nc >= 4 as i32 && ' ' as i32 == separator as i32 { + httpversion += 10 as i32 * httpversion_major; + match httpversion { + 10 | 11 => { + (*conn).httpversion = httpversion as u8; + } + #[cfg(any(USE_NGHTTP2, USE_HYPER))] + 20 => { + (*conn).httpversion = httpversion as u8; + } + #[cfg(ENABLE_QUIC)] + 30 => { + (*conn).httpversion = httpversion as u8; + } + _ => { + Curl_failf( + data, + b"Unsupported HTTP version (%u.%d) in response\0" + as *const u8 + as *const libc::c_char, + httpversion / 10 as i32, + httpversion % 10 as i32, + ); + return CURLE_UNSUPPORTED_PROTOCOL; + } } - #[cfg(ENABLE_QUIC)] - 30 => { - (*conn).httpversion = httpversion as u8; + if (*k).upgr101 as u32 == UPGR101_RECEIVED as i32 as u32 { + if (*conn).httpversion as i32 != 20 as i32 { + Curl_infof( + data, + b"Lying server, not serving HTTP/2\0" as *const u8 + as *const libc::c_char, + ); + } } - _ => { - Curl_failf( + if ((*conn).httpversion as i32) < 20 as i32 { + (*(*conn).bundle).multiuse = -(1 as i32); + Curl_infof( data, - b"Unsupported HTTP version (%u.%d) in response\0" - as *const u8 + b"Mark bundle as not supporting multiuse\0" as *const u8 as *const libc::c_char, - httpversion / 10 as i32, - httpversion % 10 as i32, ); - return CURLE_UNSUPPORTED_PROTOCOL; } - } - if (*k).upgr101 as u32 == UPGR101_RECEIVED as i32 as u32 { - if (*conn).httpversion as i32 != 20 as i32 { - Curl_infof( + } else if nc == 0 { + nc = sscanf( + headp, + b" HTTP %3d\0" as *const u8 as *const libc::c_char, + &mut (*k).httpcode as *mut i32, + ); + (*conn).httpversion = 10 as i32 as u8; + if nc == 0 { + let mut check: statusline = checkhttpprefix( data, - b"Lying server, not serving HTTP/2\0" as *const u8 - as *const libc::c_char, + Curl_dyn_ptr(&mut (*data).state.headerb), + Curl_dyn_len(&mut (*data).state.headerb), ); + if check as u32 == STATUS_DONE as i32 as u32 { + nc = 1 as i32; + (*k).httpcode = 200 as i32; + (*conn).httpversion = 10 as i32 as u8; + } } - } - if ((*conn).httpversion as i32) < 20 as i32 { - (*(*conn).bundle).multiuse = -(1 as i32); - Curl_infof( + } else { + Curl_failf( data, - b"Mark bundle as not supporting multiuse\0" as *const u8 + b"Unsupported HTTP version in response\0" as *const u8 as *const libc::c_char, ); + return CURLE_UNSUPPORTED_PROTOCOL; } - } else if nc == 0 { + } else if (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 + != 0 + { + let mut separator_0: libc::c_char = 0; + let mut rtspversion: i32 = 0; nc = sscanf( headp, - b" HTTP %3d\0" as *const u8 as *const libc::c_char, + b" RTSP/%1d.%1d%c%3d\0" as *const u8 as *const libc::c_char, + &mut rtspversion_major as *mut i32, + &mut rtspversion as *mut i32, + &mut separator_0 as *mut libc::c_char, &mut (*k).httpcode as *mut i32, ); - (*conn).httpversion = 10 as i32 as u8; - if nc == 0 { - let mut check: statusline = checkhttpprefix( - data, - Curl_dyn_ptr(&mut (*data).state.headerb), - Curl_dyn_len(&mut (*data).state.headerb), - ); - if check as u32 == STATUS_DONE as i32 as u32 { - nc = 1 as i32; - (*k).httpcode = 200 as i32; - (*conn).httpversion = 10 as i32 as u8; - } + if nc == 4 as i32 && ' ' as i32 == separator_0 as i32 { + (*conn).httpversion = 11 as i32 as u8; + } else { + nc = 0 as i32; } - } else { - Curl_failf( - data, - b"Unsupported HTTP version in response\0" as *const u8 - as *const libc::c_char, - ); - return CURLE_UNSUPPORTED_PROTOCOL; } - } else if (*(*conn).handler).protocol & ((1 as i32) << 18 as i32) as u32 != 0 { - let mut separator_0: libc::c_char = 0; - let mut rtspversion: i32 = 0; - nc = sscanf( - headp, - b" RTSP/%1d.%1d%c%3d\0" as *const u8 as *const libc::c_char, - &mut rtspversion_major as *mut i32, - &mut rtspversion as *mut i32, - &mut separator_0 as *mut libc::c_char, - &mut (*k).httpcode as *mut i32, - ); - if nc == 4 as i32 && ' ' as i32 == separator_0 as i32 { - (*conn).httpversion = 11 as i32 as u8; + if nc != 0 { + result = Curl_http_statusline(data, conn); + if result as u64 != 0 { + return result; + } } else { - nc = 0 as i32; + (*k).set_header(0 as i32 as bit); + break; } } - if nc != 0 { - result = Curl_http_statusline(data, conn); - if result as u64 != 0 { - return result; - } - } else { - (*k).set_header(0 as i32 as bit); - break; + result = CURLE_OK as i32 as CURLcode; + if result as u64 != 0 { + return result; } + result = Curl_http_header(data, conn, headp); + if result as u64 != 0 { + return result; + } + writetype = (1 as i32) << 1 as i32; + if ((*data).set).include_header() != 0 { + writetype |= (1 as i32) << 0 as i32; + } + Curl_debug( + data, + CURLINFO_HEADER_IN, + headp, + Curl_dyn_len(&mut (*data).state.headerb), + ); + result = Curl_client_write( + data, + writetype, + headp, + Curl_dyn_len(&mut (*data).state.headerb), + ); + if result as u64 != 0 { + return result; + } + (*data).info.header_size = ((*data).info.header_size as u64) + .wrapping_add(Curl_dyn_len(&mut (*data).state.headerb)) + as curl_off_t as curl_off_t; + (*data).req.headerbytecount = ((*data).req.headerbytecount as u64) + .wrapping_add(Curl_dyn_len(&mut (*data).state.headerb)) + as curl_off_t + as curl_off_t; + Curl_dyn_reset(&mut (*data).state.headerb); } - result = CURLE_OK as i32 as CURLcode; - if result as u64 != 0 { - return result; - } - result = Curl_http_header(data, conn, headp); - if result as u64 != 0 { - return result; - } - writetype = (1 as i32) << 1 as i32; - if ((*data).set).include_header() != 0 { - writetype |= (1 as i32) << 0 as i32; - } - Curl_debug( - data, - CURLINFO_HEADER_IN, - headp, - Curl_dyn_len(&mut (*data).state.headerb), - ); - result = Curl_client_write( - data, - writetype, - headp, - Curl_dyn_len(&mut (*data).state.headerb), - ); - if result as u64 != 0 { - return result; + if !(*(*k).str_0 != 0) { + break; } - (*data).info.header_size = ((*data).info.header_size as u64) - .wrapping_add(Curl_dyn_len(&mut (*data).state.headerb)) - as curl_off_t as curl_off_t; - (*data).req.headerbytecount = ((*data).req.headerbytecount as u64) - .wrapping_add(Curl_dyn_len(&mut (*data).state.headerb)) - as curl_off_t as curl_off_t; - Curl_dyn_reset(&mut (*data).state.headerb); - } - if !(*(*k).str_0 != 0) { - break; } } } -} return CURLE_OK; } diff --git a/rust/rust_project/src/http_digest.rs b/rust/rust_project/src/http_digest.rs index 0429141..9925f5c 100644 --- a/rust/rust_project/src/http_digest.rs +++ b/rust/rust_project/src/http_digest.rs @@ -30,11 +30,11 @@ pub extern "C" fn Curl_input_digest( mut proxy: bool, mut header: *const libc::c_char, ) -> CURLcode { - /* rest of the *-authenticate: - header */ - let mut digest: *mut digestdata =unsafe { 0 as *mut digestdata}; - /* Point to the correct struct with this */ - unsafe { + /* rest of the *-authenticate: + header */ + let mut digest: *mut digestdata = unsafe { 0 as *mut digestdata }; + /* Point to the correct struct with this */ + unsafe { if proxy { digest = &mut (*data).state.proxydigest; } else { @@ -63,22 +63,22 @@ pub extern "C" fn Curl_output_digest( mut request: *const u8, mut uripath: *const u8, ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut path: *mut u8 =unsafe { 0 as *mut u8}; - let mut tmp: *mut libc::c_char =unsafe { 0 as *mut libc::c_char}; - let mut response: *mut libc::c_char =unsafe { 0 as *mut libc::c_char}; - let mut len: size_t = 0; - let mut have_chlg: bool = false; - /* Point to the address of the pointer that holds the string to send to the - server, which is for a plain host or for a HTTP proxy */ - let mut allocuserpwd: *mut *mut libc::c_char =unsafe { 0 as *mut *mut libc::c_char}; - /* Point to the name and password for this */ - let mut userp: *const libc::c_char =unsafe { 0 as *const libc::c_char}; - let mut passwdp: *const libc::c_char =unsafe { 0 as *const libc::c_char}; - /* Point to the correct struct with this */ - let mut digest: *mut digestdata = unsafe {0 as *mut digestdata}; - let mut authp: *mut auth =unsafe { 0 as *mut auth}; - unsafe { + let mut result: CURLcode = CURLE_OK; + let mut path: *mut u8 = unsafe { 0 as *mut u8 }; + let mut tmp: *mut libc::c_char = unsafe { 0 as *mut libc::c_char }; + let mut response: *mut libc::c_char = unsafe { 0 as *mut libc::c_char }; + let mut len: size_t = 0; + let mut have_chlg: bool = false; + /* Point to the address of the pointer that holds the string to send to the + server, which is for a plain host or for a HTTP proxy */ + let mut allocuserpwd: *mut *mut libc::c_char = unsafe { 0 as *mut *mut libc::c_char }; + /* Point to the name and password for this */ + let mut userp: *const libc::c_char = unsafe { 0 as *const libc::c_char }; + let mut passwdp: *const libc::c_char = unsafe { 0 as *const libc::c_char }; + /* Point to the correct struct with this */ + let mut digest: *mut digestdata = unsafe { 0 as *mut digestdata }; + let mut authp: *mut auth = unsafe { 0 as *mut auth }; + unsafe { if proxy { if cfg!(not(CURL_DISABLE_PROXY)) { digest = &mut (*data).state.proxydigest; diff --git a/rust/rust_project/src/http_ntlm.rs b/rust/rust_project/src/http_ntlm.rs index cff393e..2f639c7 100644 --- a/rust/rust_project/src/http_ntlm.rs +++ b/rust/rust_project/src/http_ntlm.rs @@ -23,28 +23,29 @@ pub extern "C" fn Curl_input_ntlm( mut header: *const libc::c_char, /* rest of the www-authenticate: header */ ) -> CURLcode { - /* point to the correct struct with this */ - let mut ntlm: *mut ntlmdata = 0 as *mut ntlmdata; - let mut state: *mut curlntlm = 0 as *mut curlntlm; - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = unsafe {(*data).conn}; - ntlm = if proxy as i32 != 0 { - unsafe {&mut (*conn).proxyntlm} - } else { - unsafe {&mut (*conn).ntlm} - }; - state = if proxy as i32 != 0 { - unsafe {&mut (*conn).proxy_ntlm_state} - } else { - unsafe {&mut (*conn).http_ntlm_state} - }; - if unsafe {curl_strnequal( + /* point to the correct struct with this */ + let mut ntlm: *mut ntlmdata = 0 as *mut ntlmdata; + let mut state: *mut curlntlm = 0 as *mut curlntlm; + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + ntlm = if proxy as i32 != 0 { + unsafe { &mut (*conn).proxyntlm } + } else { + unsafe { &mut (*conn).ntlm } + }; + state = if proxy as i32 != 0 { + unsafe { &mut (*conn).proxy_ntlm_state } + } else { + unsafe { &mut (*conn).http_ntlm_state } + }; + if unsafe { + curl_strnequal( b"NTLM\0" as *const u8 as *const libc::c_char, header, strlen(b"NTLM\0" as *const u8 as *const libc::c_char), - ) != 0} - { - unsafe { + ) != 0 + } { + unsafe { header = header.offset(strlen(b"NTLM\0" as *const u8 as *const libc::c_char) as isize); while *header as i32 != 0 && Curl_isspace(*header as i32) != 0 { header = header.offset(1); @@ -102,33 +103,32 @@ pub extern "C" fn Curl_input_ntlm( } *state = NTLMSTATE_TYPE1; } - } } - return result; - + } + return result; } #[no_mangle] pub extern "C" fn Curl_output_ntlm(mut data: *mut Curl_easy, mut proxy: bool) -> CURLcode { - let mut base64: *mut libc::c_char = 0 as *mut libc::c_char; - let mut len: size_t = 0 as size_t; - let mut result: CURLcode = CURLE_OK; - let mut ntlmmsg: bufref = bufref { - dtor: None, - ptr: 0 as *const u8, - len: 0, - #[cfg(CURLDEBUG)] - signature: 0, - }; - let mut allocuserpwd: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; - let mut userp: *const libc::c_char = 0 as *const libc::c_char; - let mut passwdp: *const libc::c_char = 0 as *const libc::c_char; - let mut service: *const libc::c_char = 0 as *const libc::c_char; - let mut hostname: *const libc::c_char = 0 as *const libc::c_char; - let mut ntlm: *mut ntlmdata = 0 as *mut ntlmdata; - let mut state: *mut curlntlm = 0 as *mut curlntlm; - let mut authp: *mut auth = 0 as *mut auth; - let mut conn: *mut connectdata = unsafe {(*data).conn}; - unsafe { + let mut base64: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: size_t = 0 as size_t; + let mut result: CURLcode = CURLE_OK; + let mut ntlmmsg: bufref = bufref { + dtor: None, + ptr: 0 as *const u8, + len: 0, + #[cfg(CURLDEBUG)] + signature: 0, + }; + let mut allocuserpwd: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut userp: *const libc::c_char = 0 as *const libc::c_char; + let mut passwdp: *const libc::c_char = 0 as *const libc::c_char; + let mut service: *const libc::c_char = 0 as *const libc::c_char; + let mut hostname: *const libc::c_char = 0 as *const libc::c_char; + let mut ntlm: *mut ntlmdata = 0 as *mut ntlmdata; + let mut state: *mut curlntlm = 0 as *mut curlntlm; + let mut authp: *mut auth = 0 as *mut auth; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + unsafe { #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] if !conn.is_null() { } else { @@ -156,8 +156,8 @@ pub extern "C" fn Curl_output_ntlm(mut data: *mut Curl_easy, mut proxy: bool) -> ); } } - if proxy { - unsafe { + if proxy { + unsafe { match () { #[cfg(not(CURL_DISABLE_PROXY))] _ => { @@ -180,31 +180,37 @@ pub extern "C" fn Curl_output_ntlm(mut data: *mut Curl_easy, mut proxy: bool) -> return CURLE_NOT_BUILT_IN; } } - } - } else { - allocuserpwd =unsafe { &mut (*data).state.aptr.userpwd}; - userp = unsafe {(*data).state.aptr.user}; - passwdp = unsafe {(*data).state.aptr.passwd}; - service = unsafe {if !((*data).set.str_0[STRING_SERVICE_NAME as usize]).is_null() { + } + } else { + allocuserpwd = unsafe { &mut (*data).state.aptr.userpwd }; + userp = unsafe { (*data).state.aptr.user }; + passwdp = unsafe { (*data).state.aptr.passwd }; + service = unsafe { + if !((*data).set.str_0[STRING_SERVICE_NAME as usize]).is_null() { (*data).set.str_0[STRING_SERVICE_NAME as usize] as *const libc::c_char } else { b"HTTP\0" as *const u8 as *const libc::c_char - }}; - hostname = unsafe {(*conn).host.name}; - ntlm = unsafe {&mut (*conn).ntlm}; - state = unsafe {&mut (*conn).http_ntlm_state}; - authp =unsafe { &mut (*data).state.authhost}; - } - unsafe {(*authp).set_done(0 as bit);} - if userp.is_null() { - userp = b"\0" as *const u8 as *const libc::c_char; - } - if passwdp.is_null() { - passwdp = b"\0" as *const u8 as *const libc::c_char; - } - unsafe { Curl_bufref_init(&mut ntlmmsg);} - let mut current_block_61: u64; - unsafe { + } + }; + hostname = unsafe { (*conn).host.name }; + ntlm = unsafe { &mut (*conn).ntlm }; + state = unsafe { &mut (*conn).http_ntlm_state }; + authp = unsafe { &mut (*data).state.authhost }; + } + unsafe { + (*authp).set_done(0 as bit); + } + if userp.is_null() { + userp = b"\0" as *const u8 as *const libc::c_char; + } + if passwdp.is_null() { + passwdp = b"\0" as *const u8 as *const libc::c_char; + } + unsafe { + Curl_bufref_init(&mut ntlmmsg); + } + let mut current_block_61: u64; + unsafe { match *state as u32 { 2 => { /* We already received the type-2 message, create a type-3 message */ @@ -350,9 +356,9 @@ pub extern "C" fn Curl_output_ntlm(mut data: *mut Curl_easy, mut proxy: bool) -> } _ => {} } - Curl_bufref_free(&mut ntlmmsg);} - return result; - + Curl_bufref_free(&mut ntlmmsg); + } + return result; } #[no_mangle] pub extern "C" fn Curl_http_auth_cleanup_ntlm(mut conn: *mut connectdata) { diff --git a/rust/rust_project/src/http_proxy.rs b/rust/rust_project/src/http_proxy.rs index 28b4e28..e196b13 100755 --- a/rust/rust_project/src/http_proxy.rs +++ b/rust/rust_project/src/http_proxy.rs @@ -12,788 +12,803 @@ * Create: 2022-10-31 * Description: http proxy ******************************************************************************/ - use ::libc; - use rust_ffi::src::ffi_alias::type_alias::*; - use rust_ffi::src::ffi_fun::fun_call::*; - use rust_ffi::src::ffi_struct::struct_define::*; - // use rust_fun::src::macro_fun::*; - // use crate::src::vtls::vtls::*; - // use crate::src::http::*; - - // TODO 调用的几个http.c里的函数有hyper版本,有可能需要用条件编译再加几行 - - /* - * Perform SSL initialization for HTTPS proxy. Sets - * proxy_ssl_connected connection bit when complete. Can be - * called multiple times. - */ - - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - extern "C" fn https_proxy_connect(mut data: *mut Curl_easy, mut sockindex: i32) -> CURLcode { - if cfg!(USE_SSL) { - let mut conn: *mut connectdata = unsafe {(*data).conn}; - let mut result: CURLcode = CURLE_OK; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe {(*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32} { - } else { - unsafe { - __assert_fail( - b"conn->http_proxy.proxytype == CURLPROXY_HTTPS\0" as *const u8 - as *const libc::c_char, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 60 as u32, - (*::std::mem::transmute::<&[u8; 54], &[libc::c_char; 54]>( - b"CURLcode https_proxy_connect(struct Curl_easy *, int)\0", - )) - .as_ptr(), - );} - } - if unsafe {!(*conn).bits.proxy_ssl_connected[sockindex as usize]} { - /* perform SSL initialization for this socket */ - result =unsafe { Curl_ssl_connect_nonblocking( - data, - conn, - 1 as i32 != 0, - sockindex, - &mut *((*conn).bits.proxy_ssl_connected) - .as_mut_ptr() - .offset(sockindex as isize), - )}; - if result as u64 != 0 { - /* a failed connection is marked for closure to prevent (bad) re-use or - similar */ - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - unsafe {Curl_conncontrol( - conn, - 1 as i32, - b"TLS handshake failed\0" as *const u8 as *const libc::c_char, - );} - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - unsafe {Curl_conncontrol(conn, 1 as i32);} - } - } - return result; - } else { - return CURLE_NOT_BUILT_IN; - } - - } - - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - #[no_mangle] - pub extern "C" fn Curl_proxy_connect(mut data: *mut Curl_easy, mut sockindex: i32) -> CURLcode { - let mut conn: *mut connectdata = unsafe {(*data).conn}; - if unsafe {(*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32} { - let result: CURLcode = https_proxy_connect(data, sockindex); - if result as u64 != 0 { - return result; - } - if unsafe {!(*conn).bits.proxy_ssl_connected[sockindex as usize]} { - return result; /* wait for HTTPS proxy SSL initialization to complete */ - } - } - if unsafe {((*conn).bits).tunnel_proxy() as i32 != 0 && ((*conn).bits).httpproxy() as i32 != 0} { - if cfg!(not(CURL_DISABLE_PROXY)) { - /* for [protocol] tunneled through HTTP proxy */ - let mut hostname: *const libc::c_char = 0 as *const libc::c_char; - let mut remote_port: i32 = 0; - let mut result_0: CURLcode = CURLE_OK; - /* We want "seamless" operations through HTTP proxy tunnel */ - - /* for the secondary socket (FTP), use the "connect to host" - * but ignore the "connect to port" (use the secondary port) - */ - if unsafe {((*conn).bits).conn_to_host() != 0} { - hostname =unsafe { (*conn).conn_to_host.name}; - } else if sockindex == 1 as i32 { - hostname = unsafe {(*conn).secondaryhostname}; - } else { - hostname = unsafe {(*conn).host.name}; - } - if sockindex == 1 as i32 { - remote_port = unsafe {(*conn).secondary_port as i32}; - } else if unsafe {((*conn).bits).conn_to_port() != 0 }{ - remote_port = unsafe {(*conn).conn_to_port}; - } else { - remote_port = unsafe {(*conn).remote_port}; - } - result_0 = Curl_proxyCONNECT(data, sockindex, hostname, remote_port); - if CURLE_OK as u32 != result_0 as u32 { - return result_0; - } - #[cfg(not(CURLDEBUG))] - unsafe {Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - );} - #[cfg(CURLDEBUG)] - unsafe {curl_dbg_free( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - 120 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - );} - // let ref mut fresh0 = (*data).state.aptr.proxyuserpwd; - unsafe {(*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char;} - } else { - return CURLE_NOT_BUILT_IN; - } - } - /* no HTTP tunnel proxy, just return */ - return CURLE_OK; - - } - - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - #[no_mangle] - pub extern "C" fn Curl_connect_complete(mut conn: *mut connectdata) -> bool { - unsafe { - return ((*conn).connect_state).is_null() - || (*(*conn).connect_state).tunnel_state as u32 >= TUNNEL_COMPLETE as u32; - } - } - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - #[no_mangle] - pub extern "C" fn Curl_connect_ongoing(mut conn: *mut connectdata) -> bool { - unsafe { - return !((*conn).connect_state).is_null() - && (*(*conn).connect_state).tunnel_state as u32 <= TUNNEL_COMPLETE as u32; - } - } - /* when we've sent a CONNECT to a proxy, we should rather either wait for the - socket to become readable to be able to get the response headers or if - we're still sending the request, wait for write. */ - - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - #[no_mangle] - pub extern "C" fn Curl_connect_getsock(mut conn: *mut connectdata) -> i32 { - let mut http: *mut HTTP = 0 as *mut HTTP; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !conn.is_null() { - } else { - unsafe {__assert_fail( - b"conn\0" as *const u8 as *const libc::c_char, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 147 as u32, - (*::std::mem::transmute::<&[u8; 47], &[libc::c_char; 47]>( - b"int Curl_connect_getsock(struct connectdata *)\0", - )) - .as_ptr(), - );} - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe {!((*conn).connect_state).is_null()} { - } else { - unsafe {__assert_fail( - b"conn->connect_state\0" as *const u8 as *const libc::c_char, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 148 as u32, - (*::std::mem::transmute::<&[u8; 47], &[libc::c_char; 47]>( - b"int Curl_connect_getsock(struct connectdata *)\0", - )) - .as_ptr(), - );} - } - http =unsafe { &mut (*(*conn).connect_state).http_proxy}; - if unsafe {(*http).sending as u32 == HTTPSEND_REQUEST as u32} { - return (1 as i32) << 16 as i32 + 0 as i32; - } - return (1 as i32) << 0 as i32; - - } - - - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - extern "C" fn connect_init(mut data: *mut Curl_easy, mut reinit: bool) -> CURLcode { - unsafe { - let mut s: *mut http_connect_state = 0 as *mut http_connect_state; - let mut conn: *mut connectdata = (*data).conn; - if !reinit { - let mut result: CURLcode = CURLE_OK; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ((*conn).connect_state).is_null() { - } else { - __assert_fail( - b"!conn->connect_state\0" as *const u8 as *const libc::c_char, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 163 as u32, - (*::std::mem::transmute::<&[u8; 49], &[libc::c_char; 49]>( - b"CURLcode connect_init(struct Curl_easy *, _Bool)\0", - )) - .as_ptr(), - ); - } - /* we might need the upload buffer for streaming a partial request */ - result = Curl_get_upload_buffer(data); - if result as u64 != 0 { - return result; - } - #[cfg(not(CURLDEBUG))] - let news: *mut http_connect_state = Curl_ccalloc.expect("non-null function pointer")( - 1 as size_t, - ::std::mem::size_of::() as u64, - ) as *mut http_connect_state; - #[cfg(CURLDEBUG)] - let news: *mut http_connect_state = curl_dbg_calloc( - 1 as size_t, - ::std::mem::size_of::() as u64, - 169 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ) as *mut http_connect_state; - s = news; - if s.is_null() { - return CURLE_OUT_OF_MEMORY; - } - Curl_infof( - data, - b"allocate connect buffer!\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh1 = (*conn).connect_state; - (*conn).connect_state = s; - Curl_dyn_init(&mut (*s).rcvbuf, 16384 as size_t); - // let ref mut fresh2 = (*s).prot_save; - (*s).prot_save = (*data).req.p.http; - // let ref mut fresh3 = (*data).req.p.http; - (*data).req.p.http = &mut (*s).http_proxy; - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 0 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 0 as i32, - b"HTTP proxy CONNECT\0" as *const u8 as *const libc::c_char, - ); - /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the - * member conn->proto.http; we want [protocol] through HTTP and we have - * to change the member temporarily for connecting to the HTTP - * proxy. After Curl_proxyCONNECT we have to set back the member to the - * original pointer - * - * This function might be called several times in the multi interface case - * if the proxy's CONNECT response is not instant. - */ - } else { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !((*conn).connect_state).is_null() { - } else { - __assert_fail( - b"conn->connect_state\0" as *const u8 as *const libc::c_char, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - 190 as u32, - (*::std::mem::transmute::<&[u8; 49], &[libc::c_char; 49]>( - b"CURLcode connect_init(struct Curl_easy *, _Bool)\0", - )) - .as_ptr(), - ); - } - s = (*conn).connect_state; - Curl_dyn_reset(&mut (*s).rcvbuf); - } - (*s).tunnel_state = TUNNEL_INIT; - (*s).keepon = KEEPON_CONNECT; - (*s).cl = 0 as curl_off_t; - (*s).set_close_connection(0 as bit); - return CURLE_OK; - } - } - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - extern "C" fn connect_done(mut data: *mut Curl_easy) { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut s: *mut http_connect_state = (*conn).connect_state; - if (*s).tunnel_state as u32 != TUNNEL_EXIT as u32 { - (*s).tunnel_state = TUNNEL_EXIT; - Curl_dyn_free(&mut (*s).rcvbuf); - Curl_dyn_free(&mut (*s).req); - // let ref mut fresh4 = (*data).req.p.http; - (*data).req.p.http = (*s).prot_save; - // let ref mut fresh5 = (*s).prot_save; - /* retore the protocol pointer */ - (*s).prot_save = 0 as *mut HTTP; - Curl_infof( - data, - b"CONNECT phase completed!\0" as *const u8 as *const libc::c_char, - ); - } - } - } - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - extern "C" fn CONNECT_host( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut hostname: *const libc::c_char, - mut remote_port: i32, - mut connecthostp: *mut *mut libc::c_char, - mut hostp: *mut *mut libc::c_char, - ) -> CURLcode { - let mut hostheader: *mut libc::c_char = unsafe {0 as *mut libc::c_char}; /* for CONNECT */ - let mut host: *mut libc::c_char =unsafe { 0 as *mut libc::c_char}; /* Host: */ - let mut ipv6_ip: bool = unsafe {((*conn).bits).ipv6_ip() != 0}; - /* the hostname may be different */ - unsafe { - if hostname != (*conn).host.name as *const libc::c_char { - ipv6_ip = !(strchr(hostname, ':' as i32)).is_null(); - } - /* host:port with IPv6 support */ - hostheader = curl_maprintf( - b"%s%s%s:%d\0" as *const u8 as *const libc::c_char, - if ipv6_ip as i32 != 0 { - b"[\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - hostname, - if ipv6_ip as i32 != 0 { - b"]\0" as *const u8 as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - remote_port, - ); - if hostheader.is_null() { - return CURLE_OUT_OF_MEMORY; - } - if (Curl_checkProxyheaders(data, conn, b"Host\0" as *const u8 as *const libc::c_char)) - .is_null() - { - host = curl_maprintf( - b"Host: %s\r\n\0" as *const u8 as *const libc::c_char, - hostheader, - ); - if host.is_null() { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - hostheader as *mut libc::c_void, - 240 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - return CURLE_OUT_OF_MEMORY; - } - } - *connecthostp = hostheader; - *hostp = host; - return CURLE_OK; - } - } - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP), not(USE_HYPER)))] - extern "C" fn CONNECT( - mut data: *mut Curl_easy, - mut sockindex: i32, - mut hostname: *const libc::c_char, - mut remote_port: i32, - ) -> CURLcode { - let mut subversion: i32 = 0 as i32; - let mut k: *mut SingleRequest = unsafe {&mut (*data).req}; - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata =unsafe { (*data).conn}; - let mut tunnelsocket: curl_socket_t = unsafe {(*conn).sock[sockindex as usize]}; - let mut s: *mut http_connect_state =unsafe { (*conn).connect_state}; - let mut http: *mut HTTP =unsafe { (*data).req.p.http}; - let mut linep: *mut libc::c_char = 0 as *mut libc::c_char; - let mut perline: size_t = 0; - unsafe { - if Curl_connect_complete(conn) { - return CURLE_OK; /* CONNECT is already completed */ - } - // let ref mut fresh6 = (*conn).bits; - ((*conn).bits).set_proxy_connect_closed(0 as bit); - loop { - let mut check: timediff_t = 0; - if TUNNEL_INIT as u32 == (*s).tunnel_state as u32 { - /* BEGIN CONNECT PHASE */ - let mut req: *mut dynbuf = &mut (*s).req; - let mut hostheader: *mut libc::c_char = 0 as *mut libc::c_char; - let mut host: *mut libc::c_char = 0 as *mut libc::c_char; - Curl_infof( - data, - b"Establish HTTP proxy tunnel to %s:%d\0" as *const u8 as *const libc::c_char, - hostname, - remote_port, - ); - /* This only happens if we've looped here due to authentication - reasons, and we don't really use the newly cloned URL here - then. Just free() it. */ - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).req.newurl as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).req.newurl as *mut libc::c_void, - 287 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh7 = (*data).req.newurl; - (*data).req.newurl = 0 as *mut libc::c_char; - /* initialize send-buffer */ - Curl_dyn_init(req, (1024 as i32 * 1024 as i32) as size_t); - /* Setup the proxy-authorization header, if any */ - result = CONNECT_host( - data, - conn, - hostname, - remote_port, - &mut hostheader, - &mut host, - ); - if result as u64 != 0 { - return result; - } - result = Curl_http_output_auth( - data, - conn, - b"CONNECT\0" as *const u8 as *const libc::c_char, - HTTPREQ_GET, - hostheader, - 1 as i32 != 0, - ); - if result as u64 == 0 { - let mut httpv: *const libc::c_char = - if (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTP_1_0 as u32 { - b"1.0\0" as *const u8 as *const libc::c_char - } else { - b"1.1\0" as *const u8 as *const libc::c_char - }; - result = Curl_dyn_addf( - req, - b"CONNECT %s HTTP/%s\r\n%s%s\0" as *const u8 as *const libc::c_char, - hostheader, /* Host: */ - httpv, /* Proxy-Authorization */ - if !host.is_null() { - host as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - if !((*data).state.aptr.proxyuserpwd).is_null() { - (*data).state.aptr.proxyuserpwd as *const libc::c_char - } else { - b"\0" as *const u8 as *const libc::c_char - }, - ); - if result as u64 == 0 - && (Curl_checkProxyheaders( - data, - conn, - b"User-Agent\0" as *const u8 as *const libc::c_char, - )) - .is_null() - && !((*data).set.str_0[STRING_USERAGENT as usize]).is_null() - { - result = Curl_dyn_addf( - req, - b"User-Agent: %s\r\n\0" as *const u8 as *const libc::c_char, - (*data).set.str_0[STRING_USERAGENT as usize], - ); - } - if result as u64 == 0 - && (Curl_checkProxyheaders( - data, - conn, - b"Proxy-Connection\0" as *const u8 as *const libc::c_char, - )) - .is_null() - { - /* CRLF terminate the request */ - result = Curl_dyn_add( - req, - b"Proxy-Connection: Keep-Alive\r\n\0" as *const u8 - as *const libc::c_char, - ); - } - if result as u64 == 0 { - /* Send the connect request to the proxy */ - result = Curl_add_custom_headers(data, 1 as i32 != 0, req); - } - if result as u64 == 0 { - result = Curl_dyn_add(req, b"\r\n\0" as *const u8 as *const libc::c_char); - } - if result as u64 == 0 { - result = Curl_buffer_send( - req, - data, - &mut (*data).info.request_size, - 0 as curl_off_t, - sockindex, - ); - } - if result as u64 != 0 { - Curl_failf( - data, - b"Failed sending CONNECT to proxy\0" as *const u8 - as *const libc::c_char, - ); - } - } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(host as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - host as *mut libc::c_void, - 340 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - hostheader as *mut libc::c_void, - 341 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - if result as u64 != 0 { - return result; - } - (*s).tunnel_state = TUNNEL_CONNECT; /* END CONNECT PHASE */ - } - check = Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0); - if check <= 0 as i64 { - Curl_failf( - data, - b"Proxy CONNECT aborted due to timeout\0" as *const u8 as *const libc::c_char, - ); - return CURLE_OPERATION_TIMEDOUT; - } - if !Curl_conn_data_pending(conn, sockindex) && (*http).sending as u64 == 0 { - return CURLE_OK; /* return so we'll be called again polling-style */ - } - /* at this point, the tunnel_connecting phase is over. */ - if (*http).sending as u32 == HTTPSEND_REQUEST as u32 { - if (*s).nsend == 0 { - let mut fillcount: size_t = 0; - // let ref mut fresh8 = (*k).upload_fromhere; - (*k).upload_fromhere = (*data).state.ulbuf; - result = Curl_fillreadbuffer( - data, - (*data).set.upload_buffer_size as size_t, - &mut fillcount, - ); - if result as u64 != 0 { - return result; - } - (*s).nsend = fillcount; - } - if (*s).nsend != 0 { - let mut bytes_written: ssize_t = 0; /* write to socket (send away data) */ - result = Curl_write( - data, - (*conn).writesockfd, /* socket to send to */ - (*k).upload_fromhere as *const libc::c_void, /* buffer pointer */ - (*s).nsend, /* buffer size */ - &mut bytes_written, /* actually sent */ - ); - if result as u64 == 0 { - /* send to debug callback! */ - result = Curl_debug( - data, - CURLINFO_HEADER_OUT, - (*k).upload_fromhere, - bytes_written as size_t, - ) as CURLcode; - } - // let ref mut fresh9 = (*s).nsend; - (*s).nsend = - ((*s).nsend as u64).wrapping_sub(bytes_written as u64) as size_t as size_t; - // let ref mut fresh10 = (*k).upload_fromhere; - (*k).upload_fromhere = ((*k).upload_fromhere).offset(bytes_written as isize); - return result; - } - (*http).sending = HTTPSEND_NADA; - /* if nothing left to send, continue */ - } - /* READING RESPONSE PHASE */ - let mut error: i32 = 0 as i32; - while (*s).keepon as u64 != 0 { - let mut gotbytes: ssize_t = 0; - let mut byte: libc::c_char = 0; - /* Read one byte at a time to avoid a race condition. Wait at most one - second before looping to ensure continuous pgrsUpdates. */ - result = Curl_read(data, tunnelsocket, &mut byte, 1 as size_t, &mut gotbytes); - if result as u32 == CURLE_AGAIN as u32 { - /* socket buffer drained, return */ - return CURLE_OK; - } - if Curl_pgrsUpdate(data) != 0 { - return CURLE_ABORTED_BY_CALLBACK; - } - if result as u64 != 0 { - (*s).keepon = KEEPON_DONE; - break; - } else if gotbytes <= 0 as i64 { - if (*data).set.proxyauth != 0 - && (*data).state.authproxy.avail != 0 - && !((*data).state.aptr.proxyuserpwd).is_null() - { - /* proxy auth was requested and there was proxy auth available, - then deem this as "mere" proxy disconnect */ - // let ref mut fresh11 = (*conn).bits; - ((*conn).bits).set_proxy_connect_closed(1 as bit); - Curl_infof( - data, - b"Proxy CONNECT connection closed\0" as *const u8 - as *const libc::c_char, - ); - } else { - error = 1 as i32; - Curl_failf( - data, - b"Proxy CONNECT aborted\0" as *const u8 as *const libc::c_char, - ); - } - (*s).keepon = KEEPON_DONE; - break; - } else if (*s).keepon as u32 == KEEPON_IGNORE as u32 { - /* This means we are currently ignoring a response-body */ - if (*s).cl != 0 { - // let ref mut fresh12 = (*s).cl; - /* A Content-Length based body: simply count down the counter - and make sure to break out of the loop when we're done! */ - (*s).cl -= 1; - if !((*s).cl <= 0 as i64) { - continue; - } - (*s).keepon = KEEPON_DONE; - (*s).tunnel_state = TUNNEL_COMPLETE; - break; - } else { - /* chunked-encoded body, so we need to do the chunked dance - properly to know when the end of the body is reached */ - let mut r: CHUNKcode = CHUNKE_OK; - let mut extra: CURLcode = CURLE_OK; - let mut tookcareof: ssize_t = 0 as ssize_t; - /* now parse the chunked piece of data so that we can - properly tell when the stream ends */ - r = Curl_httpchunk_read( - data, - &mut byte, - 1 as ssize_t, - &mut tookcareof, - &mut extra, - ); - if r as i32 == CHUNKE_STOP as i32 { - /* we're done reading chunks! */ - Curl_infof( - data, - b"chunk reading DONE\0" as *const u8 as *const libc::c_char, - ); - (*s).keepon = KEEPON_DONE; - /* we did the full CONNECT treatment, go COMPLETE */ - (*s).tunnel_state = TUNNEL_COMPLETE; - } - } - } else { - if Curl_dyn_addn( - &mut (*s).rcvbuf, - &mut byte as *mut libc::c_char as *const libc::c_void, - 1 as size_t, - ) as u64 - != 0 - { - Curl_failf( - data, - b"CONNECT response too large!\0" as *const u8 as *const libc::c_char, - ); - return CURLE_RECV_ERROR; - } - /* if this is not the end of a header line then continue */ - if byte as i32 != 0xa as i32 { - continue; - } - linep = Curl_dyn_ptr(&mut (*s).rcvbuf); - perline = Curl_dyn_len(&mut (*s).rcvbuf); /* amount of bytes in this line */ - /* convert from the network encoding */ - result = CURLE_OK as CURLcode; - /* Curl_convert_from_network calls failf if unsuccessful */ - if result as u64 != 0 { - return result; - } - /* output debug if that is requested */ - Curl_debug(data, CURLINFO_HEADER_IN, linep, perline); - if ((*data).set).suppress_connect_headers() == 0 { - /* send the header to the callback */ - let mut writetype: i32 = (1 as i32) << 1 as i32; - if ((*data).set).include_header() != 0 { - writetype |= (1 as i32) << 0 as i32; - } - result = Curl_client_write(data, writetype, linep, perline); - if result as u64 != 0 { - return result; - } - } - // let ref mut fresh13 = (*data).info.header_size; - (*data).info.header_size += perline as i64; - /* Newlines are CRLF, so the CR is ignored as the line isn't - really terminated until the LF comes. Treat a following CR - as end-of-headers as well.*/ - if '\r' as i32 == *linep.offset(0 as isize) as i32 - || '\n' as i32 == *linep.offset(0 as isize) as i32 - { - /* end of response-headers from the proxy */ - if 407 as i32 == (*k).httpcode && ((*data).state).authproblem() == 0 { - /* If we get a 407 response code with content length - when we have no auth problem, we must ignore the - whole response-body */ - (*s).keepon = KEEPON_IGNORE; - if (*s).cl != 0 { - Curl_infof( - data, - b"Ignore %ld bytes of response-body\0" as *const u8 - as *const libc::c_char, - (*s).cl, - ); - /* We set ignorebody true here since the chunked decoder - function will acknowledge that. Pay attention so that this is - cleared again when this function returns! */ - } else if (*s).chunked_encoding() != 0 { - let mut r_0: CHUNKcode = CHUNKE_OK; - let mut extra_0: CURLcode = CURLE_OK; - Curl_infof( - data, - b"Ignore chunked response-body\0" as *const u8 - as *const libc::c_char, - ); - (*k).set_ignorebody(1 as bit); - if *linep.offset(1 as isize) as i32 == '\n' as i32 { - /* this can only be a LF if the letter at index 0 was a CR */ - linep = linep.offset(1); - } - /* now parse the chunked piece of data so that we can properly - tell when the stream ends */ - r_0 = Curl_httpchunk_read( - data, - linep.offset(1 as isize), - 1 as ssize_t, - &mut gotbytes, - &mut extra_0, - ); - if r_0 as i32 == CHUNKE_STOP as i32 { - /* we're done reading chunks! */ - Curl_infof( - data, - b"chunk reading DONE\0" as *const u8 as *const libc::c_char, - ); - (*s).keepon = KEEPON_DONE; - /* we did the full CONNECT treatment, go to COMPLETE */ - (*s).tunnel_state = TUNNEL_COMPLETE; - } - } else { - /* without content-length or chunked encoding, we - can't keep the connection alive since the close is - the end signal so we bail out at once instead */ - (*s).keepon = KEEPON_DONE; - } - } else { - (*s).keepon = KEEPON_DONE; - } - if (*s).keepon as u32 == KEEPON_DONE as u32 && (*s).cl == 0 { - /* we did the full CONNECT treatment, go to COMPLETE */ - (*s).tunnel_state = TUNNEL_COMPLETE; - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if (*s).keepon as u32 == KEEPON_IGNORE as u32 - || (*s).keepon as u32 == KEEPON_DONE as u32 - { - } else { - __assert_fail( +use ::libc; +use rust_ffi::src::ffi_alias::type_alias::*; +use rust_ffi::src::ffi_fun::fun_call::*; +use rust_ffi::src::ffi_struct::struct_define::*; +// use rust_fun::src::macro_fun::*; +// use crate::src::vtls::vtls::*; +// use crate::src::http::*; + +// TODO 调用的几个http.c里的函数有hyper版本,有可能需要用条件编译再加几行 + +/* + * Perform SSL initialization for HTTPS proxy. Sets + * proxy_ssl_connected connection bit when complete. Can be + * called multiple times. + */ + +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +extern "C" fn https_proxy_connect(mut data: *mut Curl_easy, mut sockindex: i32) -> CURLcode { + if cfg!(USE_SSL) { + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut result: CURLcode = CURLE_OK; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if unsafe { (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32 } { + } else { + unsafe { + __assert_fail( + b"conn->http_proxy.proxytype == CURLPROXY_HTTPS\0" as *const u8 + as *const libc::c_char, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + 60 as u32, + (*::std::mem::transmute::<&[u8; 54], &[libc::c_char; 54]>( + b"CURLcode https_proxy_connect(struct Curl_easy *, int)\0", + )) + .as_ptr(), + ); + } + } + if unsafe { !(*conn).bits.proxy_ssl_connected[sockindex as usize] } { + /* perform SSL initialization for this socket */ + result = unsafe { + Curl_ssl_connect_nonblocking( + data, + conn, + 1 as i32 != 0, + sockindex, + &mut *((*conn).bits.proxy_ssl_connected) + .as_mut_ptr() + .offset(sockindex as isize), + ) + }; + if result as u64 != 0 { + /* a failed connection is marked for closure to prevent (bad) re-use or + similar */ + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + unsafe { + Curl_conncontrol( + conn, + 1 as i32, + b"TLS handshake failed\0" as *const u8 as *const libc::c_char, + ); + } + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + unsafe { + Curl_conncontrol(conn, 1 as i32); + } + } + } + return result; + } else { + return CURLE_NOT_BUILT_IN; + } +} + +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +#[no_mangle] +pub extern "C" fn Curl_proxy_connect(mut data: *mut Curl_easy, mut sockindex: i32) -> CURLcode { + let mut conn: *mut connectdata = unsafe { (*data).conn }; + if unsafe { (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTPS as u32 } { + let result: CURLcode = https_proxy_connect(data, sockindex); + if result as u64 != 0 { + return result; + } + if unsafe { !(*conn).bits.proxy_ssl_connected[sockindex as usize] } { + return result; /* wait for HTTPS proxy SSL initialization to complete */ + } + } + if unsafe { + ((*conn).bits).tunnel_proxy() as i32 != 0 && ((*conn).bits).httpproxy() as i32 != 0 + } { + if cfg!(not(CURL_DISABLE_PROXY)) { + /* for [protocol] tunneled through HTTP proxy */ + let mut hostname: *const libc::c_char = 0 as *const libc::c_char; + let mut remote_port: i32 = 0; + let mut result_0: CURLcode = CURLE_OK; + /* We want "seamless" operations through HTTP proxy tunnel */ + + /* for the secondary socket (FTP), use the "connect to host" + * but ignore the "connect to port" (use the secondary port) + */ + if unsafe { ((*conn).bits).conn_to_host() != 0 } { + hostname = unsafe { (*conn).conn_to_host.name }; + } else if sockindex == 1 as i32 { + hostname = unsafe { (*conn).secondaryhostname }; + } else { + hostname = unsafe { (*conn).host.name }; + } + if sockindex == 1 as i32 { + remote_port = unsafe { (*conn).secondary_port as i32 }; + } else if unsafe { ((*conn).bits).conn_to_port() != 0 } { + remote_port = unsafe { (*conn).conn_to_port }; + } else { + remote_port = unsafe { (*conn).remote_port }; + } + result_0 = Curl_proxyCONNECT(data, sockindex, hostname, remote_port); + if CURLE_OK as u32 != result_0 as u32 { + return result_0; + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + ); + } + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + 120 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + } + // let ref mut fresh0 = (*data).state.aptr.proxyuserpwd; + unsafe { + (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; + } + } else { + return CURLE_NOT_BUILT_IN; + } + } + /* no HTTP tunnel proxy, just return */ + return CURLE_OK; +} + +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +#[no_mangle] +pub extern "C" fn Curl_connect_complete(mut conn: *mut connectdata) -> bool { + unsafe { + return ((*conn).connect_state).is_null() + || (*(*conn).connect_state).tunnel_state as u32 >= TUNNEL_COMPLETE as u32; + } +} +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +#[no_mangle] +pub extern "C" fn Curl_connect_ongoing(mut conn: *mut connectdata) -> bool { + unsafe { + return !((*conn).connect_state).is_null() + && (*(*conn).connect_state).tunnel_state as u32 <= TUNNEL_COMPLETE as u32; + } +} +/* when we've sent a CONNECT to a proxy, we should rather either wait for the +socket to become readable to be able to get the response headers or if +we're still sending the request, wait for write. */ + +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +#[no_mangle] +pub extern "C" fn Curl_connect_getsock(mut conn: *mut connectdata) -> i32 { + let mut http: *mut HTTP = 0 as *mut HTTP; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !conn.is_null() { + } else { + unsafe { + __assert_fail( + b"conn\0" as *const u8 as *const libc::c_char, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + 147 as u32, + (*::std::mem::transmute::<&[u8; 47], &[libc::c_char; 47]>( + b"int Curl_connect_getsock(struct connectdata *)\0", + )) + .as_ptr(), + ); + } + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if unsafe { !((*conn).connect_state).is_null() } { + } else { + unsafe { + __assert_fail( + b"conn->connect_state\0" as *const u8 as *const libc::c_char, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + 148 as u32, + (*::std::mem::transmute::<&[u8; 47], &[libc::c_char; 47]>( + b"int Curl_connect_getsock(struct connectdata *)\0", + )) + .as_ptr(), + ); + } + } + http = unsafe { &mut (*(*conn).connect_state).http_proxy }; + if unsafe { (*http).sending as u32 == HTTPSEND_REQUEST as u32 } { + return (1 as i32) << 16 as i32 + 0 as i32; + } + return (1 as i32) << 0 as i32; +} + +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +extern "C" fn connect_init(mut data: *mut Curl_easy, mut reinit: bool) -> CURLcode { + unsafe { + let mut s: *mut http_connect_state = 0 as *mut http_connect_state; + let mut conn: *mut connectdata = (*data).conn; + if !reinit { + let mut result: CURLcode = CURLE_OK; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ((*conn).connect_state).is_null() { + } else { + __assert_fail( + b"!conn->connect_state\0" as *const u8 as *const libc::c_char, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + 163 as u32, + (*::std::mem::transmute::<&[u8; 49], &[libc::c_char; 49]>( + b"CURLcode connect_init(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), + ); + } + /* we might need the upload buffer for streaming a partial request */ + result = Curl_get_upload_buffer(data); + if result as u64 != 0 { + return result; + } + #[cfg(not(CURLDEBUG))] + let news: *mut http_connect_state = Curl_ccalloc.expect("non-null function pointer")( + 1 as size_t, + ::std::mem::size_of::() as u64, + ) as *mut http_connect_state; + #[cfg(CURLDEBUG)] + let news: *mut http_connect_state = curl_dbg_calloc( + 1 as size_t, + ::std::mem::size_of::() as u64, + 169 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ) as *mut http_connect_state; + s = news; + if s.is_null() { + return CURLE_OUT_OF_MEMORY; + } + Curl_infof( + data, + b"allocate connect buffer!\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh1 = (*conn).connect_state; + (*conn).connect_state = s; + Curl_dyn_init(&mut (*s).rcvbuf, 16384 as size_t); + // let ref mut fresh2 = (*s).prot_save; + (*s).prot_save = (*data).req.p.http; + // let ref mut fresh3 = (*data).req.p.http; + (*data).req.p.http = &mut (*s).http_proxy; + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 0 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 0 as i32, + b"HTTP proxy CONNECT\0" as *const u8 as *const libc::c_char, + ); + /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the + * member conn->proto.http; we want [protocol] through HTTP and we have + * to change the member temporarily for connecting to the HTTP + * proxy. After Curl_proxyCONNECT we have to set back the member to the + * original pointer + * + * This function might be called several times in the multi interface case + * if the proxy's CONNECT response is not instant. + */ + } else { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !((*conn).connect_state).is_null() { + } else { + __assert_fail( + b"conn->connect_state\0" as *const u8 as *const libc::c_char, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + 190 as u32, + (*::std::mem::transmute::<&[u8; 49], &[libc::c_char; 49]>( + b"CURLcode connect_init(struct Curl_easy *, _Bool)\0", + )) + .as_ptr(), + ); + } + s = (*conn).connect_state; + Curl_dyn_reset(&mut (*s).rcvbuf); + } + (*s).tunnel_state = TUNNEL_INIT; + (*s).keepon = KEEPON_CONNECT; + (*s).cl = 0 as curl_off_t; + (*s).set_close_connection(0 as bit); + return CURLE_OK; + } +} +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +extern "C" fn connect_done(mut data: *mut Curl_easy) { + unsafe { + let mut conn: *mut connectdata = (*data).conn; + let mut s: *mut http_connect_state = (*conn).connect_state; + if (*s).tunnel_state as u32 != TUNNEL_EXIT as u32 { + (*s).tunnel_state = TUNNEL_EXIT; + Curl_dyn_free(&mut (*s).rcvbuf); + Curl_dyn_free(&mut (*s).req); + // let ref mut fresh4 = (*data).req.p.http; + (*data).req.p.http = (*s).prot_save; + // let ref mut fresh5 = (*s).prot_save; + /* retore the protocol pointer */ + (*s).prot_save = 0 as *mut HTTP; + Curl_infof( + data, + b"CONNECT phase completed!\0" as *const u8 as *const libc::c_char, + ); + } + } +} +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +extern "C" fn CONNECT_host( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut hostname: *const libc::c_char, + mut remote_port: i32, + mut connecthostp: *mut *mut libc::c_char, + mut hostp: *mut *mut libc::c_char, +) -> CURLcode { + let mut hostheader: *mut libc::c_char = unsafe { 0 as *mut libc::c_char }; /* for CONNECT */ + let mut host: *mut libc::c_char = unsafe { 0 as *mut libc::c_char }; /* Host: */ + let mut ipv6_ip: bool = unsafe { ((*conn).bits).ipv6_ip() != 0 }; + /* the hostname may be different */ + unsafe { + if hostname != (*conn).host.name as *const libc::c_char { + ipv6_ip = !(strchr(hostname, ':' as i32)).is_null(); + } + /* host:port with IPv6 support */ + hostheader = curl_maprintf( + b"%s%s%s:%d\0" as *const u8 as *const libc::c_char, + if ipv6_ip as i32 != 0 { + b"[\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + hostname, + if ipv6_ip as i32 != 0 { + b"]\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + remote_port, + ); + if hostheader.is_null() { + return CURLE_OUT_OF_MEMORY; + } + if (Curl_checkProxyheaders(data, conn, b"Host\0" as *const u8 as *const libc::c_char)) + .is_null() + { + host = curl_maprintf( + b"Host: %s\r\n\0" as *const u8 as *const libc::c_char, + hostheader, + ); + if host.is_null() { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + hostheader as *mut libc::c_void, + 240 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OUT_OF_MEMORY; + } + } + *connecthostp = hostheader; + *hostp = host; + return CURLE_OK; + } +} +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP), not(USE_HYPER)))] +extern "C" fn CONNECT( + mut data: *mut Curl_easy, + mut sockindex: i32, + mut hostname: *const libc::c_char, + mut remote_port: i32, +) -> CURLcode { + let mut subversion: i32 = 0 as i32; + let mut k: *mut SingleRequest = unsafe { &mut (*data).req }; + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut tunnelsocket: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; + let mut s: *mut http_connect_state = unsafe { (*conn).connect_state }; + let mut http: *mut HTTP = unsafe { (*data).req.p.http }; + let mut linep: *mut libc::c_char = 0 as *mut libc::c_char; + let mut perline: size_t = 0; + unsafe { + if Curl_connect_complete(conn) { + return CURLE_OK; /* CONNECT is already completed */ + } + // let ref mut fresh6 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(0 as bit); + loop { + let mut check: timediff_t = 0; + if TUNNEL_INIT as u32 == (*s).tunnel_state as u32 { + /* BEGIN CONNECT PHASE */ + let mut req: *mut dynbuf = &mut (*s).req; + let mut hostheader: *mut libc::c_char = 0 as *mut libc::c_char; + let mut host: *mut libc::c_char = 0 as *mut libc::c_char; + Curl_infof( + data, + b"Establish HTTP proxy tunnel to %s:%d\0" as *const u8 as *const libc::c_char, + hostname, + remote_port, + ); + /* This only happens if we've looped here due to authentication + reasons, and we don't really use the newly cloned URL here + then. Just free() it. */ + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).req.newurl as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).req.newurl as *mut libc::c_void, + 287 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh7 = (*data).req.newurl; + (*data).req.newurl = 0 as *mut libc::c_char; + /* initialize send-buffer */ + Curl_dyn_init(req, (1024 as i32 * 1024 as i32) as size_t); + /* Setup the proxy-authorization header, if any */ + result = CONNECT_host( + data, + conn, + hostname, + remote_port, + &mut hostheader, + &mut host, + ); + if result as u64 != 0 { + return result; + } + result = Curl_http_output_auth( + data, + conn, + b"CONNECT\0" as *const u8 as *const libc::c_char, + HTTPREQ_GET, + hostheader, + 1 as i32 != 0, + ); + if result as u64 == 0 { + let mut httpv: *const libc::c_char = + if (*conn).http_proxy.proxytype as u32 == CURLPROXY_HTTP_1_0 as u32 { + b"1.0\0" as *const u8 as *const libc::c_char + } else { + b"1.1\0" as *const u8 as *const libc::c_char + }; + result = Curl_dyn_addf( + req, + b"CONNECT %s HTTP/%s\r\n%s%s\0" as *const u8 as *const libc::c_char, + hostheader, /* Host: */ + httpv, /* Proxy-Authorization */ + if !host.is_null() { + host as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !((*data).state.aptr.proxyuserpwd).is_null() { + (*data).state.aptr.proxyuserpwd as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + if result as u64 == 0 + && (Curl_checkProxyheaders( + data, + conn, + b"User-Agent\0" as *const u8 as *const libc::c_char, + )) + .is_null() + && !((*data).set.str_0[STRING_USERAGENT as usize]).is_null() + { + result = Curl_dyn_addf( + req, + b"User-Agent: %s\r\n\0" as *const u8 as *const libc::c_char, + (*data).set.str_0[STRING_USERAGENT as usize], + ); + } + if result as u64 == 0 + && (Curl_checkProxyheaders( + data, + conn, + b"Proxy-Connection\0" as *const u8 as *const libc::c_char, + )) + .is_null() + { + /* CRLF terminate the request */ + result = Curl_dyn_add( + req, + b"Proxy-Connection: Keep-Alive\r\n\0" as *const u8 + as *const libc::c_char, + ); + } + if result as u64 == 0 { + /* Send the connect request to the proxy */ + result = Curl_add_custom_headers(data, 1 as i32 != 0, req); + } + if result as u64 == 0 { + result = Curl_dyn_add(req, b"\r\n\0" as *const u8 as *const libc::c_char); + } + if result as u64 == 0 { + result = Curl_buffer_send( + req, + data, + &mut (*data).info.request_size, + 0 as curl_off_t, + sockindex, + ); + } + if result as u64 != 0 { + Curl_failf( + data, + b"Failed sending CONNECT to proxy\0" as *const u8 + as *const libc::c_char, + ); + } + } + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(host as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + host as *mut libc::c_void, + 340 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + hostheader as *mut libc::c_void, + 341 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + if result as u64 != 0 { + return result; + } + (*s).tunnel_state = TUNNEL_CONNECT; /* END CONNECT PHASE */ + } + check = Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0); + if check <= 0 as i64 { + Curl_failf( + data, + b"Proxy CONNECT aborted due to timeout\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OPERATION_TIMEDOUT; + } + if !Curl_conn_data_pending(conn, sockindex) && (*http).sending as u64 == 0 { + return CURLE_OK; /* return so we'll be called again polling-style */ + } + /* at this point, the tunnel_connecting phase is over. */ + if (*http).sending as u32 == HTTPSEND_REQUEST as u32 { + if (*s).nsend == 0 { + let mut fillcount: size_t = 0; + // let ref mut fresh8 = (*k).upload_fromhere; + (*k).upload_fromhere = (*data).state.ulbuf; + result = Curl_fillreadbuffer( + data, + (*data).set.upload_buffer_size as size_t, + &mut fillcount, + ); + if result as u64 != 0 { + return result; + } + (*s).nsend = fillcount; + } + if (*s).nsend != 0 { + let mut bytes_written: ssize_t = 0; /* write to socket (send away data) */ + result = Curl_write( + data, + (*conn).writesockfd, /* socket to send to */ + (*k).upload_fromhere as *const libc::c_void, /* buffer pointer */ + (*s).nsend, /* buffer size */ + &mut bytes_written, /* actually sent */ + ); + if result as u64 == 0 { + /* send to debug callback! */ + result = Curl_debug( + data, + CURLINFO_HEADER_OUT, + (*k).upload_fromhere, + bytes_written as size_t, + ) as CURLcode; + } + // let ref mut fresh9 = (*s).nsend; + (*s).nsend = + ((*s).nsend as u64).wrapping_sub(bytes_written as u64) as size_t as size_t; + // let ref mut fresh10 = (*k).upload_fromhere; + (*k).upload_fromhere = ((*k).upload_fromhere).offset(bytes_written as isize); + return result; + } + (*http).sending = HTTPSEND_NADA; + /* if nothing left to send, continue */ + } + /* READING RESPONSE PHASE */ + let mut error: i32 = 0 as i32; + while (*s).keepon as u64 != 0 { + let mut gotbytes: ssize_t = 0; + let mut byte: libc::c_char = 0; + /* Read one byte at a time to avoid a race condition. Wait at most one + second before looping to ensure continuous pgrsUpdates. */ + result = Curl_read(data, tunnelsocket, &mut byte, 1 as size_t, &mut gotbytes); + if result as u32 == CURLE_AGAIN as u32 { + /* socket buffer drained, return */ + return CURLE_OK; + } + if Curl_pgrsUpdate(data) != 0 { + return CURLE_ABORTED_BY_CALLBACK; + } + if result as u64 != 0 { + (*s).keepon = KEEPON_DONE; + break; + } else if gotbytes <= 0 as i64 { + if (*data).set.proxyauth != 0 + && (*data).state.authproxy.avail != 0 + && !((*data).state.aptr.proxyuserpwd).is_null() + { + /* proxy auth was requested and there was proxy auth available, + then deem this as "mere" proxy disconnect */ + // let ref mut fresh11 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(1 as bit); + Curl_infof( + data, + b"Proxy CONNECT connection closed\0" as *const u8 + as *const libc::c_char, + ); + } else { + error = 1 as i32; + Curl_failf( + data, + b"Proxy CONNECT aborted\0" as *const u8 as *const libc::c_char, + ); + } + (*s).keepon = KEEPON_DONE; + break; + } else if (*s).keepon as u32 == KEEPON_IGNORE as u32 { + /* This means we are currently ignoring a response-body */ + if (*s).cl != 0 { + // let ref mut fresh12 = (*s).cl; + /* A Content-Length based body: simply count down the counter + and make sure to break out of the loop when we're done! */ + (*s).cl -= 1; + if !((*s).cl <= 0 as i64) { + continue; + } + (*s).keepon = KEEPON_DONE; + (*s).tunnel_state = TUNNEL_COMPLETE; + break; + } else { + /* chunked-encoded body, so we need to do the chunked dance + properly to know when the end of the body is reached */ + let mut r: CHUNKcode = CHUNKE_OK; + let mut extra: CURLcode = CURLE_OK; + let mut tookcareof: ssize_t = 0 as ssize_t; + /* now parse the chunked piece of data so that we can + properly tell when the stream ends */ + r = Curl_httpchunk_read( + data, + &mut byte, + 1 as ssize_t, + &mut tookcareof, + &mut extra, + ); + if r as i32 == CHUNKE_STOP as i32 { + /* we're done reading chunks! */ + Curl_infof( + data, + b"chunk reading DONE\0" as *const u8 as *const libc::c_char, + ); + (*s).keepon = KEEPON_DONE; + /* we did the full CONNECT treatment, go COMPLETE */ + (*s).tunnel_state = TUNNEL_COMPLETE; + } + } + } else { + if Curl_dyn_addn( + &mut (*s).rcvbuf, + &mut byte as *mut libc::c_char as *const libc::c_void, + 1 as size_t, + ) as u64 + != 0 + { + Curl_failf( + data, + b"CONNECT response too large!\0" as *const u8 as *const libc::c_char, + ); + return CURLE_RECV_ERROR; + } + /* if this is not the end of a header line then continue */ + if byte as i32 != 0xa as i32 { + continue; + } + linep = Curl_dyn_ptr(&mut (*s).rcvbuf); + perline = Curl_dyn_len(&mut (*s).rcvbuf); /* amount of bytes in this line */ + /* convert from the network encoding */ + result = CURLE_OK as CURLcode; + /* Curl_convert_from_network calls failf if unsuccessful */ + if result as u64 != 0 { + return result; + } + /* output debug if that is requested */ + Curl_debug(data, CURLINFO_HEADER_IN, linep, perline); + if ((*data).set).suppress_connect_headers() == 0 { + /* send the header to the callback */ + let mut writetype: i32 = (1 as i32) << 1 as i32; + if ((*data).set).include_header() != 0 { + writetype |= (1 as i32) << 0 as i32; + } + result = Curl_client_write(data, writetype, linep, perline); + if result as u64 != 0 { + return result; + } + } + // let ref mut fresh13 = (*data).info.header_size; + (*data).info.header_size += perline as i64; + /* Newlines are CRLF, so the CR is ignored as the line isn't + really terminated until the LF comes. Treat a following CR + as end-of-headers as well.*/ + if '\r' as i32 == *linep.offset(0 as isize) as i32 + || '\n' as i32 == *linep.offset(0 as isize) as i32 + { + /* end of response-headers from the proxy */ + if 407 as i32 == (*k).httpcode && ((*data).state).authproblem() == 0 { + /* If we get a 407 response code with content length + when we have no auth problem, we must ignore the + whole response-body */ + (*s).keepon = KEEPON_IGNORE; + if (*s).cl != 0 { + Curl_infof( + data, + b"Ignore %ld bytes of response-body\0" as *const u8 + as *const libc::c_char, + (*s).cl, + ); + /* We set ignorebody true here since the chunked decoder + function will acknowledge that. Pay attention so that this is + cleared again when this function returns! */ + } else if (*s).chunked_encoding() != 0 { + let mut r_0: CHUNKcode = CHUNKE_OK; + let mut extra_0: CURLcode = CURLE_OK; + Curl_infof( + data, + b"Ignore chunked response-body\0" as *const u8 + as *const libc::c_char, + ); + (*k).set_ignorebody(1 as bit); + if *linep.offset(1 as isize) as i32 == '\n' as i32 { + /* this can only be a LF if the letter at index 0 was a CR */ + linep = linep.offset(1); + } + /* now parse the chunked piece of data so that we can properly + tell when the stream ends */ + r_0 = Curl_httpchunk_read( + data, + linep.offset(1 as isize), + 1 as ssize_t, + &mut gotbytes, + &mut extra_0, + ); + if r_0 as i32 == CHUNKE_STOP as i32 { + /* we're done reading chunks! */ + Curl_infof( + data, + b"chunk reading DONE\0" as *const u8 as *const libc::c_char, + ); + (*s).keepon = KEEPON_DONE; + /* we did the full CONNECT treatment, go to COMPLETE */ + (*s).tunnel_state = TUNNEL_COMPLETE; + } + } else { + /* without content-length or chunked encoding, we + can't keep the connection alive since the close is + the end signal so we bail out at once instead */ + (*s).keepon = KEEPON_DONE; + } + } else { + (*s).keepon = KEEPON_DONE; + } + if (*s).keepon as u32 == KEEPON_DONE as u32 && (*s).cl == 0 { + /* we did the full CONNECT treatment, go to COMPLETE */ + (*s).tunnel_state = TUNNEL_COMPLETE; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if (*s).keepon as u32 == KEEPON_IGNORE as u32 + || (*s).keepon as u32 == KEEPON_DONE as u32 + { + } else { + __assert_fail( b"s->keepon == KEEPON_IGNORE || s->keepon == KEEPON_DONE\0" as *const u8 as *const libc::c_char, b"http_proxy.c\0" as *const u8 as *const libc::c_char, @@ -803,835 +818,834 @@ )) .as_ptr(), ); - } - } else { - if curl_strnequal( - b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char, - linep, - strlen(b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char), - ) != 0 - && 401 as i32 == (*k).httpcode - || curl_strnequal( - b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char, - linep, - strlen( - b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char, - ), - ) != 0 - && 407 as i32 == (*k).httpcode - { - let mut proxy: bool = if (*k).httpcode == 407 as i32 { - 1 as i32 - } else { - 0 as i32 - } != 0; - let mut auth: *mut libc::c_char = Curl_copy_header_value(linep); - if auth.is_null() { - return CURLE_OUT_OF_MEMORY; - } - result = Curl_http_input_auth(data, proxy, auth); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - auth as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - auth as *mut libc::c_void, - 571 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - if result as u64 != 0 { - return result; - } - } else if curl_strnequal( - b"Content-Length:\0" as *const u8 as *const libc::c_char, - linep, - strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char), - ) != 0 - { - if (*k).httpcode / 100 as i32 == 2 as i32 { - /* A client MUST ignore any Content-Length or Transfer-Encoding - header fields received in a successful response to CONNECT. - "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ - Curl_infof( - data, - b"Ignoring Content-Length in CONNECT %03d response\0" - as *const u8 - as *const libc::c_char, - (*k).httpcode, - ); - } else { - curlx_strtoofft( - linep.offset(strlen( - b"Content-Length:\0" as *const u8 as *const libc::c_char, - ) as isize), - 0 as *mut *mut libc::c_char, - 10 as i32, - &mut (*s).cl, - ); - } - } else if Curl_compareheader( - linep, - b"Connection:\0" as *const u8 as *const libc::c_char, - b"close\0" as *const u8 as *const libc::c_char, - ) { - (*s).set_close_connection(1 as bit); - } else if curl_strnequal( - b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, - linep, - strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char), - ) != 0 - { - if (*k).httpcode / 100 as i32 == 2 as i32 { - /* A client MUST ignore any Content-Length or Transfer-Encoding - header fields received in a successful response to CONNECT. - "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ - Curl_infof( - data, - b"Ignoring Transfer-Encoding in CONNECT %03d response\0" - as *const u8 - as *const libc::c_char, - (*k).httpcode, - ); - } else if Curl_compareheader( - linep, - b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, - b"chunked\0" as *const u8 as *const libc::c_char, - ) { - Curl_infof( - data, - b"CONNECT responded chunked\0" as *const u8 - as *const libc::c_char, - ); /* init our chunky engine */ - (*s).set_chunked_encoding(1 as i32 as bit); - Curl_httpchunk_init(data); - } - } else if Curl_compareheader( - linep, - b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, - b"close\0" as *const u8 as *const libc::c_char, - ) { - (*s).set_close_connection(1 as i32 as bit); - } else if 2 as i32 - == sscanf( - linep, - b"HTTP/1.%d %d\0" as *const u8 as *const libc::c_char, - &mut subversion as *mut i32, - &mut (*k).httpcode as *mut i32, - ) - { - /* store the HTTP code from the proxy */ - (*data).info.httpproxycode = (*k).httpcode; - } - Curl_dyn_reset(&mut (*s).rcvbuf); - } /* while there's buffer left and loop is requested */ - } - } - if Curl_pgrsUpdate(data) != 0 { - return CURLE_ABORTED_BY_CALLBACK; - } - if error != 0 { - return CURLE_RECV_ERROR; - } - if (*data).info.httpproxycode / 100 as i32 != 2 as i32 { - /* Deal with the possibly already received authenticate - headers. 'newurl' is set to a new URL if we must loop. */ - result = Curl_http_auth_act(data); - if result as u64 != 0 { - return result; - } - if ((*conn).bits).close() != 0 { - /* the connection has been marked for closure, most likely in the - Curl_http_auth_act() function and thus we can kill it at once - below */ - (*s).set_close_connection(1 as bit); - } - } - if (*s).close_connection() as i32 != 0 && !((*data).req.newurl).is_null() { - /* Connection closed by server. Don't use it anymore */ - Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); - (*conn).sock[sockindex as usize] = -(1 as i32); - break; - } else { - if !((*data).req.newurl).is_null() - && TUNNEL_COMPLETE as u32 == (*s).tunnel_state as u32 - { - connect_init(data, 1 as i32 != 0); - } - if ((*data).req.newurl).is_null() { - break; - } - } /* END READING RESPONSE PHASE */ - } - /* If we are supposed to continue and request a new URL, which basically - * means the HTTP authentication is still going on so if the tunnel - * is complete we start over in INIT state */ - if (*data).info.httpproxycode / 100 as i32 != 2 as i32 { - if (*s).close_connection() as i32 != 0 && !((*data).req.newurl).is_null() { - // let ref mut fresh14 = (*conn).bits; - ((*conn).bits).set_proxy_connect_closed(1 as bit); - Curl_infof( - data, - b"Connect me again please\0" as *const u8 as *const libc::c_char, - ); - connect_done(data); - } else { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).req.newurl as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).req.newurl as *mut libc::c_void, - 663 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh15 = (*data).req.newurl; - (*data).req.newurl = 0 as *mut libc::c_char; - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - Curl_conncontrol(conn, 2 as i32); - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - Curl_conncontrol( - conn, - 2 as i32, - b"proxy CONNECT failure\0" as *const u8 as *const libc::c_char, - ); - Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); - (*conn).sock[sockindex as usize] = -(1 as i32); - } - (*s).tunnel_state = TUNNEL_INIT; /* to back to init state */ - if ((*conn).bits).proxy_connect_closed() != 0 { - /* this is not an error, just part of the connection negotiation */ - return CURLE_OK; - } - Curl_dyn_free(&mut (*s).rcvbuf); - Curl_failf( - data, - b"Received HTTP code %d from proxy after CONNECT\0" as *const u8 - as *const libc::c_char, - (*data).req.httpcode, - ); - return CURLE_RECV_ERROR; - } - (*s).tunnel_state = TUNNEL_COMPLETE; - /* If a proxy-authorization header was used for the proxy, then we should - make sure that it isn't accidentally used for the document request - after we've connected. So let's free and clear it here. */ - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - ); - #[cfg(CURLDEBUG)] - curl_dbg_free( - (*data).state.aptr.proxyuserpwd as *mut libc::c_void, - 688 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh16 = (*data).state.aptr.proxyuserpwd; - (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; - // let ref mut fresh17 = (*data).state.aptr.proxyuserpwd; - (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; - // let ref mut fresh18 = (*data).state.authproxy; - ((*data).state.authproxy).set_done(1 as bit); - // let ref mut fresh19 = (*data).state.authproxy; - ((*data).state.authproxy).set_multipass(0 as bit); - Curl_infof( - data, - b"Proxy replied %d to CONNECT request\0" as *const u8 as *const libc::c_char, - (*data).info.httpproxycode, - ); - // let ref mut fresh20 = (*data).req; - ((*data).req).set_ignorebody(0 as bit); /* put it (back) to non-ignore state */ - // let ref mut fresh21 = (*conn).bits; - ((*conn).bits).set_rewindaftersend(0 as bit); /* make sure this isn't set for the - document request */ - Curl_dyn_free(&mut (*s).rcvbuf); - return CURLE_OK; - } - } - /* The Hyper version of CONNECT */ - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP), USE_HYPER))] - extern "C" fn CONNECT( - mut data: *mut Curl_easy, - mut sockindex: i32, - mut hostname: *const libc::c_char, - mut remote_port: i32, - ) -> CURLcode { - let mut current_block: u64; - let mut conn: *mut connectdata =unsafe { (*data).conn}; - let mut h: *mut hyptransfer =unsafe { &mut (*data).hyp}; - let mut tunnelsocket: curl_socket_t = unsafe {(*conn).sock[sockindex as usize]}; - let mut s: *mut http_connect_state = unsafe {(*conn).connect_state}; - let mut result: CURLcode = CURLE_OUT_OF_MEMORY; - let mut io: *mut hyper_io =unsafe { 0 as *mut hyper_io}; - let mut req: *mut hyper_request =unsafe { 0 as *mut hyper_request}; - let mut headers: *mut hyper_headers = unsafe {0 as *mut hyper_headers}; - let mut options: *mut hyper_clientconn_options = unsafe {0 as *mut hyper_clientconn_options}; - let mut handshake: *mut hyper_task =unsafe { 0 as *mut hyper_task}; - let mut task: *mut hyper_task =unsafe { 0 as *mut hyper_task}; /* for the handshake */ - let mut sendtask: *mut hyper_task =unsafe { 0 as *mut hyper_task}; /* for the send */ - let mut client: *mut hyper_clientconn =unsafe { 0 as *mut hyper_clientconn}; - let mut hypererr: *mut hyper_error =unsafe { 0 as *mut hyper_error}; - let mut hostheader: *mut libc::c_char =unsafe { 0 as *mut libc::c_char}; /* for CONNECT */ - let mut host: *mut libc::c_char = unsafe {0 as *mut libc::c_char}; /* Host: */ - unsafe { - if Curl_connect_complete(conn) { - return CURLE_OK; /* CONNECT is already completed */ - } - // let ref mut fresh6 = (*conn).bits; - ((*conn).bits).set_proxy_connect_closed(0 as bit); - 's_65: loop { - match (*s).tunnel_state as u32 { - 0 => { - /* BEGIN CONNECT PHASE */ - io = hyper_io_new(); - if io.is_null() { - Curl_failf( - data, - b"Couldn't create hyper IO\0" as *const u8 as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - /* tell Hyper how to read/write network data */ - hyper_io_set_userdata(io, data as *mut libc::c_void); - hyper_io_set_read( - io, - Some( - Curl_hyper_recv - as unsafe extern "C" fn( - *mut libc::c_void, - *mut hyper_context, - *mut uint8_t, - size_t, - ) - -> size_t, - ), - ); - hyper_io_set_write( - io, - Some( - Curl_hyper_send - as unsafe extern "C" fn( - *mut libc::c_void, - *mut hyper_context, - *const uint8_t, - size_t, - ) - -> size_t, - ), - ); - (*conn).sockfd = tunnelsocket; - (*data).state.hconnect = 1 as i32 != 0; - /* create an executor to poll futures */ - if ((*h).exec).is_null() { - // let ref mut fresh7 = (*h).exec; - (*h).exec = hyper_executor_new(); - if ((*h).exec).is_null() { - Curl_failf( - data, - b"Couldn't create hyper executor\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } - } - options = hyper_clientconn_options_new(); - if options.is_null() { - Curl_failf( - data, - b"Couldn't create hyper client options\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - hyper_clientconn_options_exec(options, (*h).exec); - /* "Both the `io` and the `options` are consumed in this function - call" */ - handshake = hyper_clientconn_handshake(io, options); /* ownership passed on */ - if handshake.is_null() { - Curl_failf( - data, - b"Couldn't create hyper client handshake\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - io = 0 as *mut hyper_io; - options = 0 as *mut hyper_clientconn_options; - if HYPERE_OK as u32 - != hyper_executor_push((*h).exec, handshake) as u32 - { - Curl_failf( - data, - b"Couldn't hyper_executor_push the handshake\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - handshake = 0 as *mut hyper_task; - task = hyper_executor_poll((*h).exec); - if task.is_null() { - Curl_failf( - data, - b"Couldn't hyper_executor_poll the handshake\0" - as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - client = hyper_task_value(task) as *mut hyper_clientconn; - hyper_task_free(task); - req = hyper_request_new(); - if req.is_null() { - Curl_failf( - data, - b"Couldn't hyper_request_new\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else if hyper_request_set_method( - req, - b"CONNECT\0" as *const u8 as *const libc::c_char - as *mut uint8_t, - strlen( - b"CONNECT\0" as *const u8 as *const libc::c_char, - ), - ) as u64 - != 0 - { - Curl_failf( - data, - b"error setting method\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - result = CONNECT_host( - data, - conn, - hostname, - remote_port, - &mut hostheader, - &mut host, - ); - if result as u64 != 0 { - current_block = 14523688961733284890; - break; - } - if hyper_request_set_uri( - req, - hostheader as *mut uint8_t, - strlen(hostheader), - ) as u64 - != 0 - { - Curl_failf( - data, - b"error setting path\0" as *const u8 - as *const libc::c_char, - ); - result = CURLE_OUT_OF_MEMORY; - } - /* Setup the proxy-authorization header, if any */ - result = Curl_http_output_auth( - data, - conn, - b"CONNECT\0" as *const u8 as *const libc::c_char, - HTTPREQ_GET, - hostheader, - 1 as i32 != 0, - ); - if result as u64 != 0 { - current_block = 14523688961733284890; - break; - } - Curl_cfree.expect("non-null function pointer")( - hostheader as *mut libc::c_void, - ); - hostheader = 0 as *mut libc::c_char; - /* default is 1.1 */ - if (*conn).http_proxy.proxytype as u32 - == CURLPROXY_HTTP_1_0 as u32 - && HYPERE_OK as u32 - != hyper_request_set_version(req, 10 as i32) - as u32 - { - Curl_failf( - data, - b"error setting HTTP version\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - headers = hyper_request_headers(req); - if headers.is_null() { - Curl_failf( - data, - b"hyper_request_headers\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else { - if !host.is_null() - && Curl_hyper_header(data, headers, host) - as u32 - != 0 - { - current_block = 14523688961733284890; - break; - } - Curl_cfree.expect("non-null function pointer")( - host as *mut libc::c_void, - ); - host = 0 as *mut libc::c_char; - if !((*data).state.aptr.proxyuserpwd).is_null() - && Curl_hyper_header( - data, - headers, - (*data).state.aptr.proxyuserpwd, - ) - as u32 - != 0 - { - current_block = 14523688961733284890; - break; - } - if (Curl_checkProxyheaders( - data, - conn, - b"User-Agent\0" as *const u8 - as *const libc::c_char, - )) - .is_null() - && !((*data).set.str_0 - [STRING_USERAGENT as usize]) - .is_null() - { - let mut ua: dynbuf = dynbuf { - bufr: 0 as *mut libc::c_char, - leng: 0, - allc: 0, - toobig: 0, - }; - Curl_dyn_init( - &mut ua, - (1024 as i32 * 1024 as i32) as size_t, - ); - result = Curl_dyn_addf( - &mut ua as *mut dynbuf, - b"User-Agent: %s\r\n\0" as *const u8 - as *const libc::c_char, - (*data).set.str_0 - [STRING_USERAGENT as i32 as usize], - ); - if result as u64 != 0 { - current_block = 14523688961733284890; - break; - } - if Curl_hyper_header( - data, - headers, - Curl_dyn_ptr(&mut ua), - ) - as u64 - != 0 - { - current_block = 14523688961733284890; - break; - } - Curl_dyn_free(&mut ua); - } - if (Curl_checkProxyheaders( - data, - conn, - b"Proxy-Connection\0" as *const u8 - as *const libc::c_char, - )) - .is_null() - && Curl_hyper_header( - data, - headers, - b"Proxy-Connection: Keep-Alive\0" - as *const u8 - as *const libc::c_char, - ) - as u32 - != 0 - { - current_block = 14523688961733284890; - break; - } - if Curl_add_custom_headers( - data, - 1 as i32 != 0, - headers as *mut libc::c_void, - ) - as u64 - != 0 - { - current_block = 14523688961733284890; - break; - } - sendtask = hyper_clientconn_send(client, req); - if sendtask.is_null() { - Curl_failf( - data, - b"hyper_clientconn_send\0" as *const u8 - as *const libc::c_char, - ); - current_block = 14523688961733284890; - break; - } else if HYPERE_OK as u32 - != hyper_executor_push((*h).exec, sendtask) - as u32 - { - Curl_failf( + } + } else { + if curl_strnequal( + b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char, + linep, + strlen(b"WWW-Authenticate:\0" as *const u8 as *const libc::c_char), + ) != 0 + && 401 as i32 == (*k).httpcode + || curl_strnequal( + b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char, + linep, + strlen( + b"Proxy-authenticate:\0" as *const u8 as *const libc::c_char, + ), + ) != 0 + && 407 as i32 == (*k).httpcode + { + let mut proxy: bool = if (*k).httpcode == 407 as i32 { + 1 as i32 + } else { + 0 as i32 + } != 0; + let mut auth: *mut libc::c_char = Curl_copy_header_value(linep); + if auth.is_null() { + return CURLE_OUT_OF_MEMORY; + } + result = Curl_http_input_auth(data, proxy, auth); + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + auth as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + auth as *mut libc::c_void, + 571 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + if result as u64 != 0 { + return result; + } + } else if curl_strnequal( + b"Content-Length:\0" as *const u8 as *const libc::c_char, + linep, + strlen(b"Content-Length:\0" as *const u8 as *const libc::c_char), + ) != 0 + { + if (*k).httpcode / 100 as i32 == 2 as i32 { + /* A client MUST ignore any Content-Length or Transfer-Encoding + header fields received in a successful response to CONNECT. + "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ + Curl_infof( + data, + b"Ignoring Content-Length in CONNECT %03d response\0" + as *const u8 + as *const libc::c_char, + (*k).httpcode, + ); + } else { + curlx_strtoofft( + linep.offset(strlen( + b"Content-Length:\0" as *const u8 as *const libc::c_char, + ) as isize), + 0 as *mut *mut libc::c_char, + 10 as i32, + &mut (*s).cl, + ); + } + } else if Curl_compareheader( + linep, + b"Connection:\0" as *const u8 as *const libc::c_char, + b"close\0" as *const u8 as *const libc::c_char, + ) { + (*s).set_close_connection(1 as bit); + } else if curl_strnequal( + b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, + linep, + strlen(b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char), + ) != 0 + { + if (*k).httpcode / 100 as i32 == 2 as i32 { + /* A client MUST ignore any Content-Length or Transfer-Encoding + header fields received in a successful response to CONNECT. + "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ + Curl_infof( + data, + b"Ignoring Transfer-Encoding in CONNECT %03d response\0" + as *const u8 + as *const libc::c_char, + (*k).httpcode, + ); + } else if Curl_compareheader( + linep, + b"Transfer-Encoding:\0" as *const u8 as *const libc::c_char, + b"chunked\0" as *const u8 as *const libc::c_char, + ) { + Curl_infof( + data, + b"CONNECT responded chunked\0" as *const u8 + as *const libc::c_char, + ); /* init our chunky engine */ + (*s).set_chunked_encoding(1 as i32 as bit); + Curl_httpchunk_init(data); + } + } else if Curl_compareheader( + linep, + b"Proxy-Connection:\0" as *const u8 as *const libc::c_char, + b"close\0" as *const u8 as *const libc::c_char, + ) { + (*s).set_close_connection(1 as i32 as bit); + } else if 2 as i32 + == sscanf( + linep, + b"HTTP/1.%d %d\0" as *const u8 as *const libc::c_char, + &mut subversion as *mut i32, + &mut (*k).httpcode as *mut i32, + ) + { + /* store the HTTP code from the proxy */ + (*data).info.httpproxycode = (*k).httpcode; + } + Curl_dyn_reset(&mut (*s).rcvbuf); + } /* while there's buffer left and loop is requested */ + } + } + if Curl_pgrsUpdate(data) != 0 { + return CURLE_ABORTED_BY_CALLBACK; + } + if error != 0 { + return CURLE_RECV_ERROR; + } + if (*data).info.httpproxycode / 100 as i32 != 2 as i32 { + /* Deal with the possibly already received authenticate + headers. 'newurl' is set to a new URL if we must loop. */ + result = Curl_http_auth_act(data); + if result as u64 != 0 { + return result; + } + if ((*conn).bits).close() != 0 { + /* the connection has been marked for closure, most likely in the + Curl_http_auth_act() function and thus we can kill it at once + below */ + (*s).set_close_connection(1 as bit); + } + } + if (*s).close_connection() as i32 != 0 && !((*data).req.newurl).is_null() { + /* Connection closed by server. Don't use it anymore */ + Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); + (*conn).sock[sockindex as usize] = -(1 as i32); + break; + } else { + if !((*data).req.newurl).is_null() + && TUNNEL_COMPLETE as u32 == (*s).tunnel_state as u32 + { + connect_init(data, 1 as i32 != 0); + } + if ((*data).req.newurl).is_null() { + break; + } + } /* END READING RESPONSE PHASE */ + } + /* If we are supposed to continue and request a new URL, which basically + * means the HTTP authentication is still going on so if the tunnel + * is complete we start over in INIT state */ + if (*data).info.httpproxycode / 100 as i32 != 2 as i32 { + if (*s).close_connection() as i32 != 0 && !((*data).req.newurl).is_null() { + // let ref mut fresh14 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(1 as bit); + Curl_infof( + data, + b"Connect me again please\0" as *const u8 as *const libc::c_char, + ); + connect_done(data); + } else { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).req.newurl as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).req.newurl as *mut libc::c_void, + 663 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh15 = (*data).req.newurl; + (*data).req.newurl = 0 as *mut libc::c_char; + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + Curl_conncontrol(conn, 2 as i32); + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + Curl_conncontrol( + conn, + 2 as i32, + b"proxy CONNECT failure\0" as *const u8 as *const libc::c_char, + ); + Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); + (*conn).sock[sockindex as usize] = -(1 as i32); + } + (*s).tunnel_state = TUNNEL_INIT; /* to back to init state */ + if ((*conn).bits).proxy_connect_closed() != 0 { + /* this is not an error, just part of the connection negotiation */ + return CURLE_OK; + } + Curl_dyn_free(&mut (*s).rcvbuf); + Curl_failf( + data, + b"Received HTTP code %d from proxy after CONNECT\0" as *const u8 + as *const libc::c_char, + (*data).req.httpcode, + ); + return CURLE_RECV_ERROR; + } + (*s).tunnel_state = TUNNEL_COMPLETE; + /* If a proxy-authorization header was used for the proxy, then we should + make sure that it isn't accidentally used for the document request + after we've connected. So let's free and clear it here. */ + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + ); + #[cfg(CURLDEBUG)] + curl_dbg_free( + (*data).state.aptr.proxyuserpwd as *mut libc::c_void, + 688 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh16 = (*data).state.aptr.proxyuserpwd; + (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; + // let ref mut fresh17 = (*data).state.aptr.proxyuserpwd; + (*data).state.aptr.proxyuserpwd = 0 as *mut libc::c_char; + // let ref mut fresh18 = (*data).state.authproxy; + ((*data).state.authproxy).set_done(1 as bit); + // let ref mut fresh19 = (*data).state.authproxy; + ((*data).state.authproxy).set_multipass(0 as bit); + Curl_infof( + data, + b"Proxy replied %d to CONNECT request\0" as *const u8 as *const libc::c_char, + (*data).info.httpproxycode, + ); + // let ref mut fresh20 = (*data).req; + ((*data).req).set_ignorebody(0 as bit); /* put it (back) to non-ignore state */ + // let ref mut fresh21 = (*conn).bits; + ((*conn).bits).set_rewindaftersend(0 as bit); /* make sure this isn't set for the + document request */ + Curl_dyn_free(&mut (*s).rcvbuf); + return CURLE_OK; + } +} +/* The Hyper version of CONNECT */ +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP), USE_HYPER))] +extern "C" fn CONNECT( + mut data: *mut Curl_easy, + mut sockindex: i32, + mut hostname: *const libc::c_char, + mut remote_port: i32, +) -> CURLcode { + let mut current_block: u64; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut h: *mut hyptransfer = unsafe { &mut (*data).hyp }; + let mut tunnelsocket: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; + let mut s: *mut http_connect_state = unsafe { (*conn).connect_state }; + let mut result: CURLcode = CURLE_OUT_OF_MEMORY; + let mut io: *mut hyper_io = unsafe { 0 as *mut hyper_io }; + let mut req: *mut hyper_request = unsafe { 0 as *mut hyper_request }; + let mut headers: *mut hyper_headers = unsafe { 0 as *mut hyper_headers }; + let mut options: *mut hyper_clientconn_options = unsafe { 0 as *mut hyper_clientconn_options }; + let mut handshake: *mut hyper_task = unsafe { 0 as *mut hyper_task }; + let mut task: *mut hyper_task = unsafe { 0 as *mut hyper_task }; /* for the handshake */ + let mut sendtask: *mut hyper_task = unsafe { 0 as *mut hyper_task }; /* for the send */ + let mut client: *mut hyper_clientconn = unsafe { 0 as *mut hyper_clientconn }; + let mut hypererr: *mut hyper_error = unsafe { 0 as *mut hyper_error }; + let mut hostheader: *mut libc::c_char = unsafe { 0 as *mut libc::c_char }; /* for CONNECT */ + let mut host: *mut libc::c_char = unsafe { 0 as *mut libc::c_char }; /* Host: */ + unsafe { + if Curl_connect_complete(conn) { + return CURLE_OK; /* CONNECT is already completed */ + } + // let ref mut fresh6 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(0 as bit); + 's_65: loop { + match (*s).tunnel_state as u32 { + 0 => { + /* BEGIN CONNECT PHASE */ + io = hyper_io_new(); + if io.is_null() { + Curl_failf( + data, + b"Couldn't create hyper IO\0" as *const u8 as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else { + /* tell Hyper how to read/write network data */ + hyper_io_set_userdata(io, data as *mut libc::c_void); + hyper_io_set_read( + io, + Some( + Curl_hyper_recv + as unsafe extern "C" fn( + *mut libc::c_void, + *mut hyper_context, + *mut uint8_t, + size_t, + ) + -> size_t, + ), + ); + hyper_io_set_write( + io, + Some( + Curl_hyper_send + as unsafe extern "C" fn( + *mut libc::c_void, + *mut hyper_context, + *const uint8_t, + size_t, + ) + -> size_t, + ), + ); + (*conn).sockfd = tunnelsocket; + (*data).state.hconnect = 1 as i32 != 0; + /* create an executor to poll futures */ + if ((*h).exec).is_null() { + // let ref mut fresh7 = (*h).exec; + (*h).exec = hyper_executor_new(); + if ((*h).exec).is_null() { + Curl_failf( + data, + b"Couldn't create hyper executor\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } + } + options = hyper_clientconn_options_new(); + if options.is_null() { + Curl_failf( + data, + b"Couldn't create hyper client options\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else { + hyper_clientconn_options_exec(options, (*h).exec); + /* "Both the `io` and the `options` are consumed in this function + call" */ + handshake = hyper_clientconn_handshake(io, options); /* ownership passed on */ + if handshake.is_null() { + Curl_failf( + data, + b"Couldn't create hyper client handshake\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else { + io = 0 as *mut hyper_io; + options = 0 as *mut hyper_clientconn_options; + if HYPERE_OK as u32 + != hyper_executor_push((*h).exec, handshake) as u32 + { + Curl_failf( + data, + b"Couldn't hyper_executor_push the handshake\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else { + handshake = 0 as *mut hyper_task; + task = hyper_executor_poll((*h).exec); + if task.is_null() { + Curl_failf( + data, + b"Couldn't hyper_executor_poll the handshake\0" + as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else { + client = hyper_task_value(task) as *mut hyper_clientconn; + hyper_task_free(task); + req = hyper_request_new(); + if req.is_null() { + Curl_failf( + data, + b"Couldn't hyper_request_new\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else if hyper_request_set_method( + req, + b"CONNECT\0" as *const u8 as *const libc::c_char + as *mut uint8_t, + strlen( + b"CONNECT\0" as *const u8 as *const libc::c_char, + ), + ) as u64 + != 0 + { + Curl_failf( + data, + b"error setting method\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else { + result = CONNECT_host( + data, + conn, + hostname, + remote_port, + &mut hostheader, + &mut host, + ); + if result as u64 != 0 { + current_block = 14523688961733284890; + break; + } + if hyper_request_set_uri( + req, + hostheader as *mut uint8_t, + strlen(hostheader), + ) as u64 + != 0 + { + Curl_failf( + data, + b"error setting path\0" as *const u8 + as *const libc::c_char, + ); + result = CURLE_OUT_OF_MEMORY; + } + /* Setup the proxy-authorization header, if any */ + result = Curl_http_output_auth( + data, + conn, + b"CONNECT\0" as *const u8 as *const libc::c_char, + HTTPREQ_GET, + hostheader, + 1 as i32 != 0, + ); + if result as u64 != 0 { + current_block = 14523688961733284890; + break; + } + Curl_cfree.expect("non-null function pointer")( + hostheader as *mut libc::c_void, + ); + hostheader = 0 as *mut libc::c_char; + /* default is 1.1 */ + if (*conn).http_proxy.proxytype as u32 + == CURLPROXY_HTTP_1_0 as u32 + && HYPERE_OK as u32 + != hyper_request_set_version(req, 10 as i32) + as u32 + { + Curl_failf( + data, + b"error setting HTTP version\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else { + headers = hyper_request_headers(req); + if headers.is_null() { + Curl_failf( + data, + b"hyper_request_headers\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else { + if !host.is_null() + && Curl_hyper_header(data, headers, host) + as u32 + != 0 + { + current_block = 14523688961733284890; + break; + } + Curl_cfree.expect("non-null function pointer")( + host as *mut libc::c_void, + ); + host = 0 as *mut libc::c_char; + if !((*data).state.aptr.proxyuserpwd).is_null() + && Curl_hyper_header( + data, + headers, + (*data).state.aptr.proxyuserpwd, + ) + as u32 + != 0 + { + current_block = 14523688961733284890; + break; + } + if (Curl_checkProxyheaders( + data, + conn, + b"User-Agent\0" as *const u8 + as *const libc::c_char, + )) + .is_null() + && !((*data).set.str_0 + [STRING_USERAGENT as usize]) + .is_null() + { + let mut ua: dynbuf = dynbuf { + bufr: 0 as *mut libc::c_char, + leng: 0, + allc: 0, + toobig: 0, + }; + Curl_dyn_init( + &mut ua, + (1024 as i32 * 1024 as i32) as size_t, + ); + result = Curl_dyn_addf( + &mut ua as *mut dynbuf, + b"User-Agent: %s\r\n\0" as *const u8 + as *const libc::c_char, + (*data).set.str_0 + [STRING_USERAGENT as i32 as usize], + ); + if result as u64 != 0 { + current_block = 14523688961733284890; + break; + } + if Curl_hyper_header( + data, + headers, + Curl_dyn_ptr(&mut ua), + ) + as u64 + != 0 + { + current_block = 14523688961733284890; + break; + } + Curl_dyn_free(&mut ua); + } + if (Curl_checkProxyheaders( + data, + conn, + b"Proxy-Connection\0" as *const u8 + as *const libc::c_char, + )) + .is_null() + && Curl_hyper_header( + data, + headers, + b"Proxy-Connection: Keep-Alive\0" + as *const u8 + as *const libc::c_char, + ) + as u32 + != 0 + { + current_block = 14523688961733284890; + break; + } + if Curl_add_custom_headers( + data, + 1 as i32 != 0, + headers as *mut libc::c_void, + ) + as u64 + != 0 + { + current_block = 14523688961733284890; + break; + } + sendtask = hyper_clientconn_send(client, req); + if sendtask.is_null() { + Curl_failf( + data, + b"hyper_clientconn_send\0" as *const u8 + as *const libc::c_char, + ); + current_block = 14523688961733284890; + break; + } else if HYPERE_OK as u32 + != hyper_executor_push((*h).exec, sendtask) + as u32 + { + Curl_failf( data, b"Couldn't hyper_executor_push the send\0" as *const u8 as *const libc::c_char, ); - current_block = 14523688961733284890; - break; - } else { - hyper_clientconn_free(client); - loop { - task = hyper_executor_poll((*h).exec); - if !task.is_null() { - let mut error: bool = - hyper_task_type(task) as u32 - == HYPER_TASK_ERROR as u32; - if error { - hypererr = - hyper_task_value(task) - as *mut hyper_error; - } - hyper_task_free(task); - if error { - current_block = - 14523688961733284890; - break 's_65; - } - } - if task.is_null() { - break; - } - } - (*s).tunnel_state = TUNNEL_CONNECT; - } - } - } - } - } - } - } - } - } - current_block = 2945622622075328793; - } - 1 => { - current_block = 2945622622075328793; - } - _ => { - current_block = 1841672684692190573; - } - } - match current_block { - 2945622622075328793 => { - let mut didwhat: i32 = 0; - let mut done: bool = 0 as i32 != 0; - result = Curl_hyper_stream( - data, - conn, - &mut didwhat, - &mut done, - 0x1 as i32 | 0x2 as i32, - ); - if result as u64 != 0 { - current_block = 14523688961733284890; - break; - } - if done { - (*s).tunnel_state = TUNNEL_COMPLETE; - if !((*h).exec).is_null() { - hyper_executor_free((*h).exec); - // let ref mut fresh8 = (*h).exec; - (*h).exec = 0 as *const hyper_executor; - } - if !((*h).read_waker).is_null() { - hyper_waker_free((*h).read_waker); - // let ref mut fresh9 = (*h).read_waker; - (*h).read_waker = 0 as *mut hyper_waker; - } - if !((*h).write_waker).is_null() { - hyper_waker_free((*h).write_waker); - // let ref mut fresh10 = (*h).write_waker; - (*h).write_waker = 0 as *mut hyper_waker; - } - } - } - _ => {} - } - if ((*data).req.newurl).is_null() { - current_block = 14027225908442187354; - break; - } - } - match current_block { - 14027225908442187354 => { - result = CURLE_OK; - if (*s).tunnel_state as u32 == TUNNEL_COMPLETE as u32 { - (*data).info.httpproxycode = (*data).req.httpcode; - if (*data).info.httpproxycode / 100 as i32 != 2 as i32 { - if ((*conn).bits).close() as i32 != 0 && !((*data).req.newurl).is_null() { - // let ref mut fresh11 = (*conn).bits; - ((*conn).bits).set_proxy_connect_closed(1 as bit); - Curl_infof( - data, - b"Connect me again please\0" as *const u8 as *const libc::c_char, - ); - connect_done(data); - } else { - Curl_cfree.expect("non-null function pointer")( - (*data).req.newurl as *mut libc::c_void, - ); - // let ref mut fresh12 = (*data).req.newurl; - (*data).req.newurl = 0 as *mut libc::c_char; - Curl_conncontrol(conn, 2 as i32); - Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); - (*conn).sock[sockindex as usize] = -(1 as i32); - } - (*s).tunnel_state = TUNNEL_INIT; - if ((*conn).bits).proxy_connect_closed() == 0 { - Curl_failf( - data, - b"Received HTTP code %d from proxy after CONNECT\0" as *const u8 - as *const libc::c_char, - (*data).req.httpcode, - ); - result = CURLE_RECV_ERROR; - } - } - } - } - _ => {} - } - Curl_cfree.expect("non-null function pointer")(host as *mut libc::c_void); - Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); - if !io.is_null() { - hyper_io_free(io); - } - if !options.is_null() { - hyper_clientconn_options_free(options); - } - if !handshake.is_null() { - hyper_task_free(handshake); - } - if !hypererr.is_null() { - let mut errbuf: [uint8_t; 256] = [0; 256]; - let mut errlen: size_t = hyper_error_print( - hypererr, - errbuf.as_mut_ptr(), - ::std::mem::size_of::<[uint8_t; 256]>() as u64, - ); - Curl_failf( - data, - b"Hyper: %.*s\0" as *const u8 as *const libc::c_char, - errlen as i32, - errbuf.as_mut_ptr(), - ); - hyper_error_free(hypererr); - } - return result; - } - } - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - #[no_mangle] - pub extern "C" fn Curl_connect_free(mut data: *mut Curl_easy) { - let mut conn: *mut connectdata = unsafe {(*data).conn}; - let mut s: *mut http_connect_state =unsafe { (*conn).connect_state}; - unsafe { - if !s.is_null() { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(s as *mut libc::c_void); - #[cfg(CURLDEBUG)] - curl_dbg_free( - s as *mut libc::c_void, - 968 as i32, - b"http_proxy.c\0" as *const u8 as *const libc::c_char, - ); - // let ref mut fresh22 = (*conn).connect_state; - (*conn).connect_state = 0 as *mut http_connect_state; - } - } - } - #[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] - #[no_mangle] - pub extern "C" fn Curl_proxyCONNECT( - mut data: *mut Curl_easy, - mut sockindex: i32, - mut hostname: *const libc::c_char, - mut remote_port: i32, - ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut conn: *mut connectdata = unsafe {(*data).conn}; - unsafe { - if ((*conn).connect_state).is_null() { - result = connect_init(data, 0 as i32 != 0); - if result as u64 != 0 { - return result; - } - } - result = CONNECT(data, sockindex, hostname, remote_port); - if result as u32 != 0 || Curl_connect_complete(conn) as i32 != 0 { - connect_done(data); - } - return result; - } - } - - /* - * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This - * function will issue the necessary commands to get a seamless tunnel through - * this proxy. After that, the socket can be used just as a normal socket. - */ - #[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] - #[no_mangle] - pub extern "C" fn Curl_proxyCONNECT( - mut data: *mut Curl_easy, - mut sockindex: i32, - mut hostname: *const libc::c_char, - mut remote_port: i32, - ) -> CURLcode { - unsafe { - return CURLE_NOT_BUILT_IN; - } - } - #[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] - #[no_mangle] - pub extern "C" fn Curl_proxy_connect(mut data: *mut Curl_easy, mut sockindex: i32) -> CURLcode { - unsafe { - return CURLE_OK; - } - } - #[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] - #[no_mangle] - pub extern "C" fn Curl_connect_ongoing(mut conn: *mut connectdata) -> bool { - unsafe { - return false; - } - } - #[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] - #[no_mangle] - pub extern "C" fn Curl_connect_free(mut data: *mut Curl_easy) {} - \ No newline at end of file + current_block = 14523688961733284890; + break; + } else { + hyper_clientconn_free(client); + loop { + task = hyper_executor_poll((*h).exec); + if !task.is_null() { + let mut error: bool = + hyper_task_type(task) as u32 + == HYPER_TASK_ERROR as u32; + if error { + hypererr = + hyper_task_value(task) + as *mut hyper_error; + } + hyper_task_free(task); + if error { + current_block = + 14523688961733284890; + break 's_65; + } + } + if task.is_null() { + break; + } + } + (*s).tunnel_state = TUNNEL_CONNECT; + } + } + } + } + } + } + } + } + } + current_block = 2945622622075328793; + } + 1 => { + current_block = 2945622622075328793; + } + _ => { + current_block = 1841672684692190573; + } + } + match current_block { + 2945622622075328793 => { + let mut didwhat: i32 = 0; + let mut done: bool = 0 as i32 != 0; + result = Curl_hyper_stream( + data, + conn, + &mut didwhat, + &mut done, + 0x1 as i32 | 0x2 as i32, + ); + if result as u64 != 0 { + current_block = 14523688961733284890; + break; + } + if done { + (*s).tunnel_state = TUNNEL_COMPLETE; + if !((*h).exec).is_null() { + hyper_executor_free((*h).exec); + // let ref mut fresh8 = (*h).exec; + (*h).exec = 0 as *const hyper_executor; + } + if !((*h).read_waker).is_null() { + hyper_waker_free((*h).read_waker); + // let ref mut fresh9 = (*h).read_waker; + (*h).read_waker = 0 as *mut hyper_waker; + } + if !((*h).write_waker).is_null() { + hyper_waker_free((*h).write_waker); + // let ref mut fresh10 = (*h).write_waker; + (*h).write_waker = 0 as *mut hyper_waker; + } + } + } + _ => {} + } + if ((*data).req.newurl).is_null() { + current_block = 14027225908442187354; + break; + } + } + match current_block { + 14027225908442187354 => { + result = CURLE_OK; + if (*s).tunnel_state as u32 == TUNNEL_COMPLETE as u32 { + (*data).info.httpproxycode = (*data).req.httpcode; + if (*data).info.httpproxycode / 100 as i32 != 2 as i32 { + if ((*conn).bits).close() as i32 != 0 && !((*data).req.newurl).is_null() { + // let ref mut fresh11 = (*conn).bits; + ((*conn).bits).set_proxy_connect_closed(1 as bit); + Curl_infof( + data, + b"Connect me again please\0" as *const u8 as *const libc::c_char, + ); + connect_done(data); + } else { + Curl_cfree.expect("non-null function pointer")( + (*data).req.newurl as *mut libc::c_void, + ); + // let ref mut fresh12 = (*data).req.newurl; + (*data).req.newurl = 0 as *mut libc::c_char; + Curl_conncontrol(conn, 2 as i32); + Curl_closesocket(data, conn, (*conn).sock[sockindex as usize]); + (*conn).sock[sockindex as usize] = -(1 as i32); + } + (*s).tunnel_state = TUNNEL_INIT; + if ((*conn).bits).proxy_connect_closed() == 0 { + Curl_failf( + data, + b"Received HTTP code %d from proxy after CONNECT\0" as *const u8 + as *const libc::c_char, + (*data).req.httpcode, + ); + result = CURLE_RECV_ERROR; + } + } + } + } + _ => {} + } + Curl_cfree.expect("non-null function pointer")(host as *mut libc::c_void); + Curl_cfree.expect("non-null function pointer")(hostheader as *mut libc::c_void); + if !io.is_null() { + hyper_io_free(io); + } + if !options.is_null() { + hyper_clientconn_options_free(options); + } + if !handshake.is_null() { + hyper_task_free(handshake); + } + if !hypererr.is_null() { + let mut errbuf: [uint8_t; 256] = [0; 256]; + let mut errlen: size_t = hyper_error_print( + hypererr, + errbuf.as_mut_ptr(), + ::std::mem::size_of::<[uint8_t; 256]>() as u64, + ); + Curl_failf( + data, + b"Hyper: %.*s\0" as *const u8 as *const libc::c_char, + errlen as i32, + errbuf.as_mut_ptr(), + ); + hyper_error_free(hypererr); + } + return result; + } +} +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +#[no_mangle] +pub extern "C" fn Curl_connect_free(mut data: *mut Curl_easy) { + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut s: *mut http_connect_state = unsafe { (*conn).connect_state }; + unsafe { + if !s.is_null() { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(s as *mut libc::c_void); + #[cfg(CURLDEBUG)] + curl_dbg_free( + s as *mut libc::c_void, + 968 as i32, + b"http_proxy.c\0" as *const u8 as *const libc::c_char, + ); + // let ref mut fresh22 = (*conn).connect_state; + (*conn).connect_state = 0 as *mut http_connect_state; + } + } +} +#[cfg(all(not(CURL_DISABLE_PROXY), not(CURL_DISABLE_HTTP)))] +#[no_mangle] +pub extern "C" fn Curl_proxyCONNECT( + mut data: *mut Curl_easy, + mut sockindex: i32, + mut hostname: *const libc::c_char, + mut remote_port: i32, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + unsafe { + if ((*conn).connect_state).is_null() { + result = connect_init(data, 0 as i32 != 0); + if result as u64 != 0 { + return result; + } + } + result = CONNECT(data, sockindex, hostname, remote_port); + if result as u32 != 0 || Curl_connect_complete(conn) as i32 != 0 { + connect_done(data); + } + return result; + } +} + +/* + * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This + * function will issue the necessary commands to get a seamless tunnel through + * this proxy. After that, the socket can be used just as a normal socket. + */ +#[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] +#[no_mangle] +pub extern "C" fn Curl_proxyCONNECT( + mut data: *mut Curl_easy, + mut sockindex: i32, + mut hostname: *const libc::c_char, + mut remote_port: i32, +) -> CURLcode { + unsafe { + return CURLE_NOT_BUILT_IN; + } +} +#[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] +#[no_mangle] +pub extern "C" fn Curl_proxy_connect(mut data: *mut Curl_easy, mut sockindex: i32) -> CURLcode { + unsafe { + return CURLE_OK; + } +} +#[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] +#[no_mangle] +pub extern "C" fn Curl_connect_ongoing(mut conn: *mut connectdata) -> bool { + unsafe { + return false; + } +} +#[cfg(any(CURL_DISABLE_PROXY, CURL_DISABLE_HTTP))] +#[no_mangle] +pub extern "C" fn Curl_connect_free(mut data: *mut Curl_easy) {} diff --git a/rust/rust_project/src/vtls/gtls.rs b/rust/rust_project/src/vtls/gtls.rs index c9bb782..33a504d 100644 --- a/rust/rust_project/src/vtls/gtls.rs +++ b/rust/rust_project/src/vtls/gtls.rs @@ -24,41 +24,44 @@ extern "C" fn gtls_push( mut buf: *const libc::c_void, mut len: size_t, ) -> ssize_t { - let mut sock: curl_socket_t =unsafe{ *(s as *mut curl_socket_t)}; - #[cfg(not(CURLDEBUG))] - let mut ret: ssize_t =unsafe{ send(sock, buf, len, MSG_NOSIGNAL as i32)}; + let mut sock: curl_socket_t = unsafe { *(s as *mut curl_socket_t) }; + #[cfg(not(CURLDEBUG))] + let mut ret: ssize_t = unsafe { send(sock, buf, len, MSG_NOSIGNAL as i32) }; - #[cfg(CURLDEBUG)] - let mut ret: ssize_t =unsafe{ curl_dbg_send( + #[cfg(CURLDEBUG)] + let mut ret: ssize_t = unsafe { + curl_dbg_send( sock, buf, len, MSG_NOSIGNAL as i32, 86 as i32, b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - )}; - return ret; - + ) + }; + return ret; } extern "C" fn gtls_pull( mut s: *mut libc::c_void, mut buf: *mut libc::c_void, mut len: size_t, ) -> ssize_t { - let mut sock: curl_socket_t =unsafe{ *(s as *mut curl_socket_t)}; - #[cfg(not(CURLDEBUG))] - let mut ret: ssize_t =unsafe{ recv(sock, buf, len, 0 as i32)}; + let mut sock: curl_socket_t = unsafe { *(s as *mut curl_socket_t) }; + #[cfg(not(CURLDEBUG))] + let mut ret: ssize_t = unsafe { recv(sock, buf, len, 0 as i32) }; - #[cfg(CURLDEBUG)] - let mut ret: ssize_t =unsafe{ curl_dbg_recv( + #[cfg(CURLDEBUG)] + let mut ret: ssize_t = unsafe { + curl_dbg_recv( sock, buf, len, 0 as i32, 93 as i32, b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - )}; - return ret; + ) + }; + return ret; } extern "C" fn gtls_push_ssl( mut s: *mut libc::c_void, @@ -87,18 +90,22 @@ extern "C" fn gtls_pull_ssl( * situation under control! */ extern "C" fn gtls_init() -> i32 { - let mut ret: i32 = 1 as i32; - if unsafe{ !gtls_inited} { - ret =unsafe{ if gnutls_global_init() != 0 { + let mut ret: i32 = 1 as i32; + if unsafe { !gtls_inited } { + ret = unsafe { + if gnutls_global_init() != 0 { 0 as i32 } else { 1 as i32 - }}; + } + }; - // #[cfg(GTLSDEBUG)] - unsafe{ gtls_inited = 1 as i32 != 0;} + // #[cfg(GTLSDEBUG)] + unsafe { + gtls_inited = 1 as i32 != 0; } - return ret; + } + return ret; } extern "C" fn gtls_cleanup() { @@ -111,26 +118,27 @@ extern "C" fn gtls_cleanup() { } #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] extern "C" fn showtime(mut data: *mut Curl_easy, mut text: *const libc::c_char, mut stamp: time_t) { - let mut buffer: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *const libc::c_char, - }; - let mut tm: *const tm = &mut buffer; - let mut str: [libc::c_char; 96] = [0; 96]; - let mut result: CURLcode =unsafe{ Curl_gmtime(stamp, &mut buffer)}; - if result as u64 != 0 { - return; - } - unsafe{ curl_msnprintf( + let mut buffer: tm = tm { + tm_sec: 0, + tm_min: 0, + tm_hour: 0, + tm_mday: 0, + tm_mon: 0, + tm_year: 0, + tm_wday: 0, + tm_yday: 0, + tm_isdst: 0, + tm_gmtoff: 0, + tm_zone: 0 as *const libc::c_char, + }; + let mut tm: *const tm = &mut buffer; + let mut str: [libc::c_char; 96] = [0; 96]; + let mut result: CURLcode = unsafe { Curl_gmtime(stamp, &mut buffer) }; + if result as u64 != 0 { + return; + } + unsafe { + curl_msnprintf( str.as_mut_ptr(), ::std::mem::size_of::<[libc::c_char; 96]>() as u64, b" %s: %s, %02d %s %4d %02d:%02d:%02d GMT\0" as *const u8 as *const libc::c_char, @@ -151,20 +159,22 @@ extern "C" fn showtime(mut data: *mut Curl_easy, mut text: *const libc::c_char, data, b"%s\0" as *const u8 as *const libc::c_char, str.as_mut_ptr(), - );} - + ); + } } extern "C" fn load_file(mut file: *const libc::c_char) -> gnutls_datum_t { - let mut f: *mut FILE = 0 as *mut FILE; - let mut loaded_file: gnutls_datum_t =unsafe{ { + let mut f: *mut FILE = 0 as *mut FILE; + let mut loaded_file: gnutls_datum_t = unsafe { + { gnutls_datum_t { data: 0 as *mut u8, size: 0 as u32, } - }}; - let mut filelen: i64 = 0; - let mut ptr: *mut libc::c_void = 0 as *mut libc::c_void; - unsafe{ + } + }; + let mut filelen: i64 = 0; + let mut ptr: *mut libc::c_void = 0 as *mut libc::c_void; + unsafe { match () { #[cfg(not(CURLDEBUG))] _ => { @@ -234,17 +244,20 @@ extern "C" fn load_file(mut file: *const libc::c_char) -> gnutls_datum_t { break 'out; } } - #[cfg(not(CURLDEBUG))] - unsafe{ fclose(f);} + #[cfg(not(CURLDEBUG))] + unsafe { + fclose(f); + } - #[cfg(CURLDEBUG)] - unsafe{ curl_dbg_fclose( + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_fclose( f, 186 as i32, b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - );} - return loaded_file; - + ); + } + return loaded_file; } extern "C" fn unload_file(mut data: gnutls_datum_t) { unsafe { @@ -268,13 +281,13 @@ extern "C" fn handshake( mut duringconnect: bool, mut nonblocking: bool, ) -> CURLcode { - - let mut connssl: *mut ssl_connect_data =unsafe{ - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; - let mut session: gnutls_session_t =unsafe{ (*backend).session}; - let mut sockfd: curl_socket_t =unsafe{ (*conn).sock[sockindex as usize]}; - unsafe{ + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut session: gnutls_session_t = unsafe { (*backend).session }; + let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; + unsafe { loop { let mut timeout_ms: timediff_t = 0; let mut rc: i32 = 0; @@ -410,7 +423,7 @@ extern "C" fn set_ssl_version_min_max( mut prioritylist: *mut *const libc::c_char, mut tls13support: *const libc::c_char, ) -> CURLcode { - unsafe{ + unsafe { let mut conn: *mut connectdata = (*data).conn; #[cfg(not(CURL_DISABLE_PROXY))] let mut ssl_version: i64 = if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 @@ -1640,28 +1653,32 @@ extern "C" fn pkp_pin_peer_pubkey( mut cert: gnutls_x509_crt_t, mut pinnedpubkey: *const libc::c_char, ) -> CURLcode { - /* Scratch */ - let mut len1: size_t = 0 as size_t; - let mut len2: size_t = 0 as size_t; - let mut buff1: *mut u8 = 0 as *mut u8; - let mut key: gnutls_pubkey_t = 0 as gnutls_pubkey_t; - /* Result is returned to caller */ - let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - /* if a path wasn't specified, don't pin */ - if pinnedpubkey.is_null() { - return CURLE_OK; - } - if cert.is_null() { - return result; - } - let mut ret: i32 = 0; - /* Begin Gyrations to get the public key */ - unsafe{ gnutls_pubkey_init(&mut key);} - ret = unsafe{ gnutls_pubkey_import_x509(key, cert, 0 as u32)}; - if !(ret < 0 as i32) { - ret = unsafe{ gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, 0 as *mut libc::c_void, &mut len1)}; - if !(ret != -(51 as i32) || len1 == 0 as u64) { - unsafe{ + /* Scratch */ + let mut len1: size_t = 0 as size_t; + let mut len2: size_t = 0 as size_t; + let mut buff1: *mut u8 = 0 as *mut u8; + let mut key: gnutls_pubkey_t = 0 as gnutls_pubkey_t; + /* Result is returned to caller */ + let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + /* if a path wasn't specified, don't pin */ + if pinnedpubkey.is_null() { + return CURLE_OK; + } + if cert.is_null() { + return result; + } + let mut ret: i32 = 0; + /* Begin Gyrations to get the public key */ + unsafe { + gnutls_pubkey_init(&mut key); + } + ret = unsafe { gnutls_pubkey_import_x509(key, cert, 0 as u32) }; + if !(ret < 0 as i32) { + ret = unsafe { + gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, 0 as *mut libc::c_void, &mut len1) + }; + if !(ret != -(51 as i32) || len1 == 0 as u64) { + unsafe { match () { #[cfg(not(CURLDEBUG))] _ => { @@ -1691,25 +1708,30 @@ extern "C" fn pkp_pin_peer_pubkey( /* The one good exit point */ result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); } - }} + } } } - if unsafe{ !key.is_null() }{ - unsafe{ - gnutls_pubkey_deinit(key);} + } + if unsafe { !key.is_null() } { + unsafe { + gnutls_pubkey_deinit(key); } - #[cfg(not(CURLDEBUG))] - unsafe{ Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void);} + } + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void); + } - #[cfg(CURLDEBUG)] - unsafe{ curl_dbg_free( + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( buff1 as *mut libc::c_void, 804 as i32, b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - );} - buff1 = 0 as *mut u8; - return result; - + ); + } + buff1 = 0 as *mut u8; + return result; } extern "C" fn gtls_connect_step3( @@ -2926,9 +2948,9 @@ extern "C" fn gtls_connect( mut conn: *mut connectdata, mut sockindex: i32, ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut done: bool = 0 as i32 != 0; - unsafe{ + let mut result: CURLcode = CURLE_OK; + let mut done: bool = 0 as i32 != 0; + unsafe { result = gtls_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done); if result as u64 != 0 { return result; @@ -2950,29 +2972,31 @@ extern "C" fn gtls_connect( } } extern "C" fn gtls_data_pending(mut conn: *const connectdata, mut connindex: i32) -> bool { - let mut connssl: *const ssl_connect_data =unsafe{ - &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data}; - let mut res: bool = 0 as i32 != 0; - let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; - if unsafe{ !((*backend).session).is_null() - && 0 as u64 != gnutls_record_check_pending((*backend).session)} - { + let mut connssl: *const ssl_connect_data = + unsafe { &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data }; + let mut res: bool = 0 as i32 != 0; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + if unsafe { + !((*backend).session).is_null() + && 0 as u64 != gnutls_record_check_pending((*backend).session) + } { + res = 1 as i32 != 0; + } + #[cfg(not(CURL_DISABLE_PROXY))] + if true { + connssl = unsafe { + &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data + }; + backend = unsafe { (*connssl).backend }; + if unsafe { + !((*backend).session).is_null() + && 0 as u64 != gnutls_record_check_pending((*backend).session) + } { res = 1 as i32 != 0; } - #[cfg(not(CURL_DISABLE_PROXY))] - if true { - connssl = unsafe{ &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) - as *const ssl_connect_data}; - backend = unsafe{ (*connssl).backend}; - if unsafe{ !((*backend).session).is_null() - && 0 as u64 != gnutls_record_check_pending((*backend).session)} - { - res = 1 as i32 != 0; - } - } + } - return res; - + return res; } extern "C" fn gtls_send( mut data: *mut Curl_easy, @@ -2981,13 +3005,13 @@ extern "C" fn gtls_send( mut len: size_t, mut curlcode: *mut CURLcode, ) -> ssize_t { - - let mut conn: *mut connectdata = unsafe{ (*data).conn}; - let mut connssl: *mut ssl_connect_data =unsafe{ - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data = unsafe{ (*connssl).backend}; - let mut rc: ssize_t =unsafe{ gnutls_record_send((*backend).session, mem, len)}; - unsafe{ + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut rc: ssize_t = unsafe { gnutls_record_send((*backend).session, mem, len) }; + unsafe { if rc < 0 as i64 { *curlcode = (if rc == -(28 as i32) as i64 { CURLE_AGAIN as i32 @@ -3001,9 +3025,8 @@ extern "C" fn gtls_send( } extern "C" fn close_one(mut connssl: *mut ssl_connect_data) { - - let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; - unsafe{ + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { if !((*backend).session).is_null() { let mut buf: [libc::c_char; 32] = [0; 32]; /* Maybe the server has already sent a close notify alert. @@ -3046,12 +3069,12 @@ extern "C" fn gtls_shutdown( mut conn: *mut connectdata, mut sockindex: i32, ) -> i32 { - - let mut connssl: *mut ssl_connect_data =unsafe{ - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; - let mut retval: i32 = 0 as i32; - unsafe{ + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut retval: i32 = 0 as i32; + unsafe { /* This has only been tested on the proftpd server, and the mod_tls code sends a close notify alert without waiting for a close notify alert in response. Thus we wait for a close notify alert from the server, but @@ -3169,12 +3192,12 @@ extern "C" fn gtls_recv( mut buffersize: size_t, mut curlcode: *mut CURLcode, ) -> ssize_t { - let mut conn: *mut connectdata =unsafe{ (*data).conn}; - let mut connssl: *mut ssl_connect_data =unsafe{ - &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) as *mut ssl_connect_data}; - let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; - let mut ret: ssize_t = 0; - unsafe{ + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) as *mut ssl_connect_data }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut ret: ssize_t = 0; + unsafe { ret = gnutls_record_recv((*backend).session, buf as *mut libc::c_void, buffersize); if ret == -(28 as i32) as i64 || ret == -(52 as i32) as i64 { *curlcode = CURLE_AGAIN; @@ -3235,9 +3258,8 @@ extern "C" fn gtls_random( mut entropy: *mut u8, mut length: size_t, ) -> CURLcode { - - let mut rc: i32 = 0; - unsafe{ + let mut rc: i32 = 0; + unsafe { rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy as *mut libc::c_void, length); return (if rc != 0 { CURLE_FAILED_INIT as i32 @@ -3252,14 +3274,15 @@ extern "C" fn gtls_sha256sum( mut sha256sum: *mut u8, mut sha256len: size_t, ) -> CURLcode { - - let mut SHA256pw: sha256_ctx =unsafe{ sha256_ctx { + let mut SHA256pw: sha256_ctx = unsafe { + sha256_ctx { state: [0; 8], count: 0, block: [0; 64], index: 0, - }}; - unsafe{ + } + }; + unsafe { nettle_sha256_init(&mut SHA256pw); nettle_sha256_update(&mut SHA256pw, tmplen as size_t, tmp); nettle_sha256_digest(&mut SHA256pw, sha256len as size_t, sha256sum); diff --git a/rust/rust_project/src/vtls/openssl.rs b/rust/rust_project/src/vtls/openssl.rs index 1917385..afdf4ae 100644 --- a/rust/rust_project/src/vtls/openssl.rs +++ b/rust/rust_project/src/vtls/openssl.rs @@ -12,726 +12,726 @@ * Create: 2022-10-31 * Description: support openssl backend ******************************************************************************/ - use crate::src::vtls::keylog::*; - use crate::src::vtls::vtls::*; - use libc; - use rust_ffi::src::ffi_alias::type_alias::*; - use rust_ffi::src::ffi_fun::fun_call::*; - use rust_ffi::src::ffi_struct::struct_define::*; - - #[inline] - extern "C" fn sk_X509_pop(mut sk: *mut stack_st_X509) -> *mut X509 { - unsafe { - return OPENSSL_sk_pop(sk as *mut OPENSSL_STACK) as *mut X509; - } - } - #[inline] - extern "C" fn sk_X509_pop_free(mut sk: *mut stack_st_X509, mut freefunc: sk_X509_freefunc) { - unsafe { - OPENSSL_sk_pop_free( - sk as *mut OPENSSL_STACK, - ::std::mem::transmute::(freefunc), - ); - } - } - #[inline] - extern "C" fn sk_X509_INFO_num(mut sk: *const stack_st_X509_INFO) -> i32 { - unsafe { - return OPENSSL_sk_num(sk as *const OPENSSL_STACK); - } - } - #[inline] - extern "C" fn sk_X509_INFO_value( - mut sk: *const stack_st_X509_INFO, - mut idx: i32, - ) -> *mut X509_INFO { - unsafe { - return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509_INFO; - } - } - #[inline] - extern "C" fn sk_X509_INFO_pop_free( - mut sk: *mut stack_st_X509_INFO, - mut freefunc: sk_X509_INFO_freefunc, - ) { - unsafe { - OPENSSL_sk_pop_free( - sk as *mut OPENSSL_STACK, - ::std::mem::transmute::(freefunc), - ); - } - } - #[inline] - extern "C" fn sk_X509_EXTENSION_num(mut sk: *const stack_st_X509_EXTENSION) -> i32 { - unsafe { - return OPENSSL_sk_num(sk as *const OPENSSL_STACK); - } - } - #[inline] - extern "C" fn sk_X509_EXTENSION_value( - mut sk: *const stack_st_X509_EXTENSION, - mut idx: i32, - ) -> *mut X509_EXTENSION { - unsafe { - return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509_EXTENSION; - } - } - #[inline] - extern "C" fn sk_X509_num(mut sk: *const stack_st_X509) -> i32 { - unsafe { - return OPENSSL_sk_num(sk as *const OPENSSL_STACK); - } - } - #[inline] - extern "C" fn sk_X509_value(mut sk: *const stack_st_X509, mut idx: i32) -> *mut X509 { - unsafe { - return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509; - } - } - #[inline] - extern "C" fn sk_GENERAL_NAME_num(mut sk: *const stack_st_GENERAL_NAME) -> i32 { - unsafe { - return OPENSSL_sk_num(sk as *const OPENSSL_STACK); - } - } - #[inline] - extern "C" fn sk_GENERAL_NAME_value( - mut sk: *const stack_st_GENERAL_NAME, - mut idx: i32, - ) -> *mut GENERAL_NAME { - unsafe { - return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut GENERAL_NAME; - } - } - #[cfg(HAVE_KEYLOG_CALLBACK)] - extern "C" fn ossl_keylog_callback(mut ssl: *const SSL, mut line: *const libc::c_char) { - unsafe { - Curl_tls_keylog_write_line(line); - } - } - // TODO - 255 - 关闭 HAVE_KEYLOG_CALLBACK选项,在翻译一次 - // #[cfg(not(HAVE_KEYLOG_CALLBACK))] - - extern "C" fn SSL_ERROR_to_str(mut err: i32) -> *const libc::c_char { - match err { - 0 => return b"SSL_ERROR_NONE\0" as *const u8 as *const libc::c_char, - 1 => return b"SSL_ERROR_SSL\0" as *const u8 as *const libc::c_char, - 2 => return b"SSL_ERROR_WANT_READ\0" as *const u8 as *const libc::c_char, - 3 => return b"SSL_ERROR_WANT_WRITE\0" as *const u8 as *const libc::c_char, - 4 => return b"SSL_ERROR_WANT_X509_LOOKUP\0" as *const u8 as *const libc::c_char, - 5 => return b"SSL_ERROR_SYSCALL\0" as *const u8 as *const libc::c_char, - 6 => return b"SSL_ERROR_ZERO_RETURN\0" as *const u8 as *const libc::c_char, - 7 => return b"SSL_ERROR_WANT_CONNECT\0" as *const u8 as *const libc::c_char, - 8 => return b"SSL_ERROR_WANT_ACCEPT\0" as *const u8 as *const libc::c_char, - #[cfg(SSL_ERROR_WANT_ASYNC)] - 9 => return b"SSL_ERROR_WANT_ASYNC\0" as *const u8 as *const libc::c_char, - #[cfg(SSL_ERROR_WANT_ASYNC_JOB)] - 10 => return b"SSL_ERROR_WANT_ASYNC_JOB\0" as *const u8 as *const libc::c_char, - #[cfg(SSL_ERROR_WANT_EARLY)] - 11 => return b"SSL_ERROR_WANT_EARLY\0" as *const u8 as *const libc::c_char, - _ => return b"SSL_ERROR unknown\0" as *const u8 as *const libc::c_char, - }; - } - /* Return error string for last OpenSSL error - */ - extern "C" fn ossl_strerror( - mut error: u64, - mut buf: *mut libc::c_char, - mut size: size_t, - ) -> *mut libc::c_char { - unsafe { - if size != 0 { - *buf = '\0' as libc::c_char; - } - // TODO - 351 - // #[cfg(OPENSSL_IS_BORINGSSL)] - #[cfg(not(OPENSSL_IS_BORINGSSL))] - ERR_error_string_n(error, buf, size); - if size > 1 as u64 && *buf == 0 { - strncpy( - buf, - if error != 0 { - b"Unknown error\0" as *const u8 as *const libc::c_char - } else { - b"No error\0" as *const u8 as *const libc::c_char - }, - size, - ); - *buf.offset(size.wrapping_sub(1 as u64) as isize) = '\0' as libc::c_char; - } - } - return buf; - } - /* Return an extra data index for the transfer data. - * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). - */ - extern "C" fn ossl_get_ssl_data_index() -> i32 { - static mut ssl_ex_data_data_index: i32 = -(1 as i32); - unsafe { - if ssl_ex_data_data_index < 0 as i32 { - ssl_ex_data_data_index = CRYPTO_get_ex_new_index( - 0 as i32, - 0 as i64, - 0 as *mut libc::c_void, - None, - None, - None, - ); - } - return ssl_ex_data_data_index; - } - } - /* Return an extra data index for the connection data. - * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). - */ - extern "C" fn ossl_get_ssl_conn_index() -> i32 { - static mut ssl_ex_data_conn_index: i32 = -(1 as i32); - unsafe { - if ssl_ex_data_conn_index < 0 as i32 { - ssl_ex_data_conn_index = CRYPTO_get_ex_new_index( - 0 as i32, - 0 as i64, - 0 as *mut libc::c_void, - None, - None, - None, - ); - } - return ssl_ex_data_conn_index; - } - } - /* Return an extra data index for the sockindex. - * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). - */ - extern "C" fn ossl_get_ssl_sockindex_index() -> i32 { - static mut sockindex_index: i32 = -(1 as i32); - unsafe { - if sockindex_index < 0 as i32 { - sockindex_index = CRYPTO_get_ex_new_index( - 0 as i32, - 0 as i64, - 0 as *mut libc::c_void, - None, - None, - None, - ); - } - return sockindex_index; - } - } - /* Return an extra data index for proxy boolean. - * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). - */ - extern "C" fn ossl_get_proxy_index() -> i32 { - static mut proxy_index: i32 = -(1 as i32); - unsafe { - if proxy_index < 0 as i32 { - proxy_index = CRYPTO_get_ex_new_index( - 0 as i32, - 0 as i64, - 0 as *mut libc::c_void, - None, - None, - None, - ); - } - return proxy_index; - } - } - - extern "C" fn passwd_callback( - mut buf: *mut libc::c_char, - mut num: i32, - mut encrypting: i32, - mut global_passwd: *mut libc::c_void, - ) -> i32 { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if 0 as i32 == encrypting { - } else { - unsafe { - __assert_fail( - b"0 == encrypting\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 416 as u32, - (*::std::mem::transmute::<&[u8; 46], &[libc::c_char; 46]>( - b"int passwd_callback(char *, int, int, void *)\0", - )) - .as_ptr(), - ); - } - } - if encrypting == 0 { - let mut klen: i32 = unsafe { curlx_uztosi(strlen(global_passwd as *mut libc::c_char)) }; - if num > klen { - unsafe { - memcpy( - buf as *mut libc::c_void, - global_passwd, - (klen + 1 as i32) as u64, - ); - } - return klen; - } - } - return 0 as i32; - } - extern "C" fn rand_enough() -> bool { - return if 0 as i32 != unsafe { RAND_status() } { - 1 as i32 - } else { - 0 as i32 - } != 0; - } - extern "C" fn ossl_seed(mut data: *mut Curl_easy) -> CURLcode { - let mut fname: [libc::c_char; 256] = [0; 256]; - /* This might get called before it has been added to a multi handle */ - if unsafe { !((*data).multi).is_null() && (*(*data).multi).ssl_seeded as i32 != 0 } { - return CURLE_OK; - } - if rand_enough() { - if unsafe { !((*data).multi).is_null() } { - unsafe { - (*(*data).multi).ssl_seeded = 1 as i32 != 0; - } - } - return CURLE_OK; - } - // TODO - 451 - 选项 RANDOM_FILE - unsafe { - RAND_load_file( - if !((*data).set.str_0[STRING_SSL_RANDOM_FILE as usize]).is_null() { - (*data).set.str_0[STRING_SSL_RANDOM_FILE as usize] as *const libc::c_char - } else { - b"/dev/urandom\0" as *const u8 as *const libc::c_char - }, - 1024 as i64, - ); - } - if rand_enough() { - return CURLE_OK; - } - - /* fallback to a custom seeding of the PRNG using a hash based on a current - time */ - // TODO - 467 有一段if的条件编译 - // #[cfg(HAVE_RAND_EGD)] - loop { - let mut randb: [u8; 64] = [0; 64]; - let mut len: size_t = ::std::mem::size_of::<[u8; 64]>() as u64; - let mut i: size_t = 0; - let mut i_max: size_t = 0; - i = 0 as size_t; - i_max = len.wrapping_div(::std::mem::size_of::() as u64); - while i < i_max { - let mut tv: curltime = unsafe { Curl_now() }; - unsafe { - Curl_wait_ms(1 as timediff_t); - } - tv.tv_sec = (tv.tv_sec as u64).wrapping_mul(i.wrapping_add(1 as u64)) as time_t; - tv.tv_usec = (tv.tv_usec as u32).wrapping_mul((i as u32).wrapping_add(2 as u32)) as i32; - unsafe { - tv.tv_sec = (tv.tv_sec as u64 - ^ (((Curl_now()).tv_sec + (Curl_now()).tv_usec as i64) as u64) - .wrapping_mul(i.wrapping_add(3 as u64)) - << 8 as i32) as time_t; - tv.tv_usec = (tv.tv_usec as u32 - ^ ((((Curl_now()).tv_sec + (Curl_now()).tv_usec as i64) as u64) - .wrapping_mul(i.wrapping_add(4 as u64)) as u32) - << 16 as i32) as i32; - memcpy( - &mut *randb - .as_mut_ptr() - .offset(i.wrapping_mul(::std::mem::size_of::() as u64) as isize) - as *mut u8 as *mut libc::c_void, - &mut tv as *mut curltime as *const libc::c_void, - ::std::mem::size_of::() as u64, - ); - } - i = i.wrapping_add(1); - } - unsafe { - RAND_add( - randb.as_mut_ptr() as *const libc::c_void, - len as i32, - len as libc::c_double / 2 as libc::c_double, - ); - } - if rand_enough() { - break; - } - } - /* generates a default path for the random seed file */ - fname[0 as usize] = 0 as libc::c_char; /* blank it first */ - unsafe { - RAND_file_name( - fname.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - if fname[0 as usize] != 0 { - /* we got a file name to try */ - unsafe { - RAND_load_file(fname.as_mut_ptr(), 1024 as i64); - } - if rand_enough() { - return CURLE_OK; - } - } - unsafe { - Curl_infof( - data, - b"libcurl is now using a weak random seed!\0" as *const u8 as *const libc::c_char, - ); - } - return (if rand_enough() as i32 != 0 { - CURLE_OK as i32 - } else { - CURLE_SSL_CONNECT_ERROR as i32 - }) as CURLcode; - } - - extern "C" fn do_file_type(mut type_0: *const libc::c_char) -> i32 { - unsafe { - if type_0.is_null() || *type_0.offset(0 as isize) == 0 { - return 1 as i32; - } - if Curl_strcasecompare(type_0, b"PEM\0" as *const u8 as *const libc::c_char) != 0 { - return 1 as i32; - } - if Curl_strcasecompare(type_0, b"DER\0" as *const u8 as *const libc::c_char) != 0 { - return 2 as i32; - } - if Curl_strcasecompare(type_0, b"ENG\0" as *const u8 as *const libc::c_char) != 0 { - return 42 as i32; - } - if Curl_strcasecompare(type_0, b"P12\0" as *const u8 as *const libc::c_char) != 0 { - return 43 as i32; - } - return -(1 as i32); - } - } - - /* - * Supply default password to the engine user interface conversation. - * The password is passed by OpenSSL engine from ENGINE_load_private_key() - * last argument to the ui and can be obtained by UI_get0_user_data(ui) here. - */ - #[cfg(USE_OPENSSL_ENGINE)] - extern "C" fn ssl_ui_reader(mut ui: *mut UI, mut uis: *mut UI_STRING) -> i32 { - let mut password: *const libc::c_char = 0 as *const libc::c_char; - match unsafe { UI_get_string_type(uis) as u32 } { - 1 | 2 => { - password = unsafe { UI_get0_user_data(ui) as *const libc::c_char }; - if !password.is_null() && unsafe { UI_get_input_flags(uis) & 0x2 as i32 != 0 } { - unsafe { - UI_set_result(ui, uis, password); - } - return 1 as i32; - } - } - _ => {} - } - return unsafe { - (UI_method_get_reader(UI_OpenSSL())).expect("non-null function pointer")(ui, uis) - }; - } - - /* - * Suppress interactive request for a default password if available. - */ - #[cfg(USE_OPENSSL_ENGINE)] - extern "C" fn ssl_ui_writer(mut ui: *mut UI, mut uis: *mut UI_STRING) -> i32 { - unsafe { - match UI_get_string_type(uis) as u32 { - 1 | 2 => { - if !(UI_get0_user_data(ui)).is_null() && UI_get_input_flags(uis) & 0x2 as i32 != 0 { - return 1 as i32; - } - } - _ => {} - } - return (UI_method_get_writer(UI_OpenSSL())).expect("non-null function pointer")(ui, uis); - } - } - - /* - * Check if a given string is a PKCS#11 URI - */ - #[cfg(USE_OPENSSL_ENGINE)] - extern "C" fn is_pkcs11_uri(mut string: *const libc::c_char) -> bool { - unsafe { - return !string.is_null() - && Curl_strncasecompare( - string, - b"pkcs11:\0" as *const u8 as *const libc::c_char, - 7 as size_t, - ) != 0; - } - } - extern "C" fn SSL_CTX_use_certificate_blob( - mut ctx: *mut SSL_CTX, - mut blob: *const curl_blob, - mut type_0: i32, - mut key_passwd: *const libc::c_char, - ) -> i32 { - let mut current_block: u64; - let mut ret: i32 = 0 as i32; - let mut x: *mut X509 = 0 as *mut X509; - /* the typecast of blob->len is fine since it is guaranteed to never be - larger than CURL_MAX_INPUT_LENGTH */ - let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; - if in_0.is_null() { - return CURLE_OUT_OF_MEMORY as i32; - } - 'end: loop { - if type_0 == 2 as i32 { - /* j = ERR_R_ASN1_LIB; */ - x = unsafe { d2i_X509_bio(in_0, 0 as *mut *mut X509) }; - } else if type_0 == 1 as i32 { - /* ERR_R_PEM_LIB; */ - x = unsafe { - PEM_read_bio_X509( - in_0, - 0 as *mut *mut X509, - Some( - passwd_callback - as unsafe extern "C" fn( - *mut libc::c_char, - i32, - i32, - *mut libc::c_void, - ) -> i32, - ), - key_passwd as *mut libc::c_void, - ) - }; - } else { - ret = 0 as i32; - break 'end; - } - if x.is_null() { - ret = 0 as i32; - break 'end; - } - ret = unsafe { SSL_CTX_use_certificate(ctx, x) }; - break 'end; - } - unsafe { - X509_free(x); - BIO_free(in_0); - } - return ret; - } - - extern "C" fn SSL_CTX_use_PrivateKey_blob( - mut ctx: *mut SSL_CTX, - mut blob: *const curl_blob, - mut type_0: i32, - mut key_passwd: *const libc::c_char, - ) -> i32 { - /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ - let mut current_block: u64; - let mut ret: i32 = 0 as i32; - let mut pkey: *mut EVP_PKEY = 0 as *mut EVP_PKEY; - let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; - if in_0.is_null() { - return CURLE_OUT_OF_MEMORY as i32; - } - 'end: loop { - if type_0 == 1 as i32 { - pkey = unsafe { - PEM_read_bio_PrivateKey( - in_0, - 0 as *mut *mut EVP_PKEY, - Some( - passwd_callback - as unsafe extern "C" fn( - *mut libc::c_char, - i32, - i32, - *mut libc::c_void, - ) -> i32, - ), - key_passwd as *mut libc::c_void, - ) - }; - } else if type_0 == 2 as i32 { - pkey = unsafe { d2i_PrivateKey_bio(in_0, 0 as *mut *mut EVP_PKEY) }; - } else { - ret = 0 as i32; - break 'end; - } - if pkey.is_null() { - ret = 0 as i32; - break 'end; - } - unsafe { - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); - } - break 'end; - } - unsafe { - BIO_free(in_0); - } - return ret; - } - extern "C" fn SSL_CTX_use_certificate_chain_blob( - mut ctx: *mut SSL_CTX, - mut blob: *const curl_blob, - mut key_passwd: *const libc::c_char, - ) -> i32 { - /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ - // TODO - 672 与OPENSSL_VERSION_NUMBER有关的条件编译 - let mut current_block: u64; - let mut ret: i32 = 0 as i32; - let mut x: *mut X509 = 0 as *mut X509; - let mut passwd_callback_userdata: *mut libc::c_void = key_passwd as *mut libc::c_void; - let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; - if in_0.is_null() { - return CURLE_OUT_OF_MEMORY as i32; - } - unsafe { - ERR_clear_error(); - x = PEM_read_bio_X509_AUX( - in_0, - 0 as *mut *mut X509, - Some( - passwd_callback - as unsafe extern "C" fn(*mut libc::c_char, i32, i32, *mut libc::c_void) -> i32, - ), - key_passwd as *mut libc::c_void, - ); - } - 'end: loop { - if x.is_null() { - ret = 0 as i32; - break 'end; - } - ret = unsafe { SSL_CTX_use_certificate(ctx, x) }; - if unsafe { ERR_peek_error() } != 0 as u64 { - ret = 0 as i32; - } - if ret != 0 { - let mut ca: *mut X509 = 0 as *mut X509; - let mut err: u64 = 0; - if unsafe { - SSL_CTX_ctrl( - ctx, - 88 as i32, - 0 as i64, - 0 as *mut libc::c_void as *mut libc::c_char as *mut libc::c_void, - ) - } == 0 - { - ret = 0 as i32; - break 'end; - } - loop { - ca = unsafe { - PEM_read_bio_X509( - in_0, - 0 as *mut *mut X509, - Some( - passwd_callback - as unsafe extern "C" fn( - *mut libc::c_char, - i32, - i32, - *mut libc::c_void, - ) -> i32, - ), - passwd_callback_userdata, - ) - }; - if ca.is_null() { - break; - } - if unsafe { - SSL_CTX_ctrl( - ctx, - 89 as i32, - 0 as i64, - ca as *mut libc::c_char as *mut libc::c_void, - ) - } == 0 - { - unsafe { - X509_free(ca); - } - ret = 0 as i32; - break 'end; - } - } - err = unsafe { ERR_peek_last_error() }; - if (err >> 24 as i64 & 0xff as u64) as i32 == 9 as i32 - && (err & 0xfff as u64) as i32 == 108 as i32 - { - unsafe { ERR_clear_error() }; - } else { - ret = 0 as i32; - } - } - break 'end; - } - unsafe { - X509_free(x); - BIO_free(in_0); - } - return ret; - } - - extern "C" fn cert_stuff( - mut data: *mut Curl_easy, - mut ctx: *mut SSL_CTX, - mut cert_file: *mut libc::c_char, - mut cert_blob: *const curl_blob, - mut cert_type: *const libc::c_char, - mut key_file: *mut libc::c_char, - mut key_blob: *const curl_blob, - mut key_type: *const libc::c_char, - mut key_passwd: *mut libc::c_char, - ) -> i32 { - let mut current_block: u64; - let mut error_buffer: [libc::c_char; 256] = [0; 256]; - let mut check_privkey: bool = 1 as i32 != 0; - let mut file_type: i32 = do_file_type(cert_type); - if !cert_file.is_null() || !cert_blob.is_null() || file_type == 42 as i32 { - let mut ssl: *mut SSL = 0 as *mut SSL; - let mut x509: *mut X509 = 0 as *mut X509; - let mut cert_done: i32 = 0 as i32; - let mut cert_use_result: i32 = 0; - if !key_passwd.is_null() { - /* set the password in the callback userdata */ - unsafe { - SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd as *mut libc::c_void); - /* Set passwd callback: */ - SSL_CTX_set_default_passwd_cb( - ctx, - Some( - passwd_callback - as unsafe extern "C" fn( - *mut libc::c_char, - i32, - i32, - *mut libc::c_void, - ) -> i32, - ), - ); - } - } - - match file_type { - 1 => { - /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ - cert_use_result = if !cert_blob.is_null() { - SSL_CTX_use_certificate_chain_blob(ctx, cert_blob, key_passwd) - } else { - unsafe { SSL_CTX_use_certificate_chain_file(ctx, cert_file) } - }; - if cert_use_result != 1 as i32 { - unsafe { - Curl_failf( +use crate::src::vtls::keylog::*; +use crate::src::vtls::vtls::*; +use libc; +use rust_ffi::src::ffi_alias::type_alias::*; +use rust_ffi::src::ffi_fun::fun_call::*; +use rust_ffi::src::ffi_struct::struct_define::*; + +#[inline] +extern "C" fn sk_X509_pop(mut sk: *mut stack_st_X509) -> *mut X509 { + unsafe { + return OPENSSL_sk_pop(sk as *mut OPENSSL_STACK) as *mut X509; + } +} +#[inline] +extern "C" fn sk_X509_pop_free(mut sk: *mut stack_st_X509, mut freefunc: sk_X509_freefunc) { + unsafe { + OPENSSL_sk_pop_free( + sk as *mut OPENSSL_STACK, + ::std::mem::transmute::(freefunc), + ); + } +} +#[inline] +extern "C" fn sk_X509_INFO_num(mut sk: *const stack_st_X509_INFO) -> i32 { + unsafe { + return OPENSSL_sk_num(sk as *const OPENSSL_STACK); + } +} +#[inline] +extern "C" fn sk_X509_INFO_value( + mut sk: *const stack_st_X509_INFO, + mut idx: i32, +) -> *mut X509_INFO { + unsafe { + return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509_INFO; + } +} +#[inline] +extern "C" fn sk_X509_INFO_pop_free( + mut sk: *mut stack_st_X509_INFO, + mut freefunc: sk_X509_INFO_freefunc, +) { + unsafe { + OPENSSL_sk_pop_free( + sk as *mut OPENSSL_STACK, + ::std::mem::transmute::(freefunc), + ); + } +} +#[inline] +extern "C" fn sk_X509_EXTENSION_num(mut sk: *const stack_st_X509_EXTENSION) -> i32 { + unsafe { + return OPENSSL_sk_num(sk as *const OPENSSL_STACK); + } +} +#[inline] +extern "C" fn sk_X509_EXTENSION_value( + mut sk: *const stack_st_X509_EXTENSION, + mut idx: i32, +) -> *mut X509_EXTENSION { + unsafe { + return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509_EXTENSION; + } +} +#[inline] +extern "C" fn sk_X509_num(mut sk: *const stack_st_X509) -> i32 { + unsafe { + return OPENSSL_sk_num(sk as *const OPENSSL_STACK); + } +} +#[inline] +extern "C" fn sk_X509_value(mut sk: *const stack_st_X509, mut idx: i32) -> *mut X509 { + unsafe { + return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut X509; + } +} +#[inline] +extern "C" fn sk_GENERAL_NAME_num(mut sk: *const stack_st_GENERAL_NAME) -> i32 { + unsafe { + return OPENSSL_sk_num(sk as *const OPENSSL_STACK); + } +} +#[inline] +extern "C" fn sk_GENERAL_NAME_value( + mut sk: *const stack_st_GENERAL_NAME, + mut idx: i32, +) -> *mut GENERAL_NAME { + unsafe { + return OPENSSL_sk_value(sk as *const OPENSSL_STACK, idx) as *mut GENERAL_NAME; + } +} +#[cfg(HAVE_KEYLOG_CALLBACK)] +extern "C" fn ossl_keylog_callback(mut ssl: *const SSL, mut line: *const libc::c_char) { + unsafe { + Curl_tls_keylog_write_line(line); + } +} +// TODO - 255 - 关闭 HAVE_KEYLOG_CALLBACK选项,在翻译一次 +// #[cfg(not(HAVE_KEYLOG_CALLBACK))] + +extern "C" fn SSL_ERROR_to_str(mut err: i32) -> *const libc::c_char { + match err { + 0 => return b"SSL_ERROR_NONE\0" as *const u8 as *const libc::c_char, + 1 => return b"SSL_ERROR_SSL\0" as *const u8 as *const libc::c_char, + 2 => return b"SSL_ERROR_WANT_READ\0" as *const u8 as *const libc::c_char, + 3 => return b"SSL_ERROR_WANT_WRITE\0" as *const u8 as *const libc::c_char, + 4 => return b"SSL_ERROR_WANT_X509_LOOKUP\0" as *const u8 as *const libc::c_char, + 5 => return b"SSL_ERROR_SYSCALL\0" as *const u8 as *const libc::c_char, + 6 => return b"SSL_ERROR_ZERO_RETURN\0" as *const u8 as *const libc::c_char, + 7 => return b"SSL_ERROR_WANT_CONNECT\0" as *const u8 as *const libc::c_char, + 8 => return b"SSL_ERROR_WANT_ACCEPT\0" as *const u8 as *const libc::c_char, + #[cfg(SSL_ERROR_WANT_ASYNC)] + 9 => return b"SSL_ERROR_WANT_ASYNC\0" as *const u8 as *const libc::c_char, + #[cfg(SSL_ERROR_WANT_ASYNC_JOB)] + 10 => return b"SSL_ERROR_WANT_ASYNC_JOB\0" as *const u8 as *const libc::c_char, + #[cfg(SSL_ERROR_WANT_EARLY)] + 11 => return b"SSL_ERROR_WANT_EARLY\0" as *const u8 as *const libc::c_char, + _ => return b"SSL_ERROR unknown\0" as *const u8 as *const libc::c_char, + }; +} +/* Return error string for last OpenSSL error + */ +extern "C" fn ossl_strerror( + mut error: u64, + mut buf: *mut libc::c_char, + mut size: size_t, +) -> *mut libc::c_char { + unsafe { + if size != 0 { + *buf = '\0' as libc::c_char; + } + // TODO - 351 + // #[cfg(OPENSSL_IS_BORINGSSL)] + #[cfg(not(OPENSSL_IS_BORINGSSL))] + ERR_error_string_n(error, buf, size); + if size > 1 as u64 && *buf == 0 { + strncpy( + buf, + if error != 0 { + b"Unknown error\0" as *const u8 as *const libc::c_char + } else { + b"No error\0" as *const u8 as *const libc::c_char + }, + size, + ); + *buf.offset(size.wrapping_sub(1 as u64) as isize) = '\0' as libc::c_char; + } + } + return buf; +} +/* Return an extra data index for the transfer data. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ +extern "C" fn ossl_get_ssl_data_index() -> i32 { + static mut ssl_ex_data_data_index: i32 = -(1 as i32); + unsafe { + if ssl_ex_data_data_index < 0 as i32 { + ssl_ex_data_data_index = CRYPTO_get_ex_new_index( + 0 as i32, + 0 as i64, + 0 as *mut libc::c_void, + None, + None, + None, + ); + } + return ssl_ex_data_data_index; + } +} +/* Return an extra data index for the connection data. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ +extern "C" fn ossl_get_ssl_conn_index() -> i32 { + static mut ssl_ex_data_conn_index: i32 = -(1 as i32); + unsafe { + if ssl_ex_data_conn_index < 0 as i32 { + ssl_ex_data_conn_index = CRYPTO_get_ex_new_index( + 0 as i32, + 0 as i64, + 0 as *mut libc::c_void, + None, + None, + None, + ); + } + return ssl_ex_data_conn_index; + } +} +/* Return an extra data index for the sockindex. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ +extern "C" fn ossl_get_ssl_sockindex_index() -> i32 { + static mut sockindex_index: i32 = -(1 as i32); + unsafe { + if sockindex_index < 0 as i32 { + sockindex_index = CRYPTO_get_ex_new_index( + 0 as i32, + 0 as i64, + 0 as *mut libc::c_void, + None, + None, + None, + ); + } + return sockindex_index; + } +} +/* Return an extra data index for proxy boolean. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ +extern "C" fn ossl_get_proxy_index() -> i32 { + static mut proxy_index: i32 = -(1 as i32); + unsafe { + if proxy_index < 0 as i32 { + proxy_index = CRYPTO_get_ex_new_index( + 0 as i32, + 0 as i64, + 0 as *mut libc::c_void, + None, + None, + None, + ); + } + return proxy_index; + } +} + +extern "C" fn passwd_callback( + mut buf: *mut libc::c_char, + mut num: i32, + mut encrypting: i32, + mut global_passwd: *mut libc::c_void, +) -> i32 { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if 0 as i32 == encrypting { + } else { + unsafe { + __assert_fail( + b"0 == encrypting\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 416 as u32, + (*::std::mem::transmute::<&[u8; 46], &[libc::c_char; 46]>( + b"int passwd_callback(char *, int, int, void *)\0", + )) + .as_ptr(), + ); + } + } + if encrypting == 0 { + let mut klen: i32 = unsafe { curlx_uztosi(strlen(global_passwd as *mut libc::c_char)) }; + if num > klen { + unsafe { + memcpy( + buf as *mut libc::c_void, + global_passwd, + (klen + 1 as i32) as u64, + ); + } + return klen; + } + } + return 0 as i32; +} +extern "C" fn rand_enough() -> bool { + return if 0 as i32 != unsafe { RAND_status() } { + 1 as i32 + } else { + 0 as i32 + } != 0; +} +extern "C" fn ossl_seed(mut data: *mut Curl_easy) -> CURLcode { + let mut fname: [libc::c_char; 256] = [0; 256]; + /* This might get called before it has been added to a multi handle */ + if unsafe { !((*data).multi).is_null() && (*(*data).multi).ssl_seeded as i32 != 0 } { + return CURLE_OK; + } + if rand_enough() { + if unsafe { !((*data).multi).is_null() } { + unsafe { + (*(*data).multi).ssl_seeded = 1 as i32 != 0; + } + } + return CURLE_OK; + } + // TODO - 451 - 选项 RANDOM_FILE + unsafe { + RAND_load_file( + if !((*data).set.str_0[STRING_SSL_RANDOM_FILE as usize]).is_null() { + (*data).set.str_0[STRING_SSL_RANDOM_FILE as usize] as *const libc::c_char + } else { + b"/dev/urandom\0" as *const u8 as *const libc::c_char + }, + 1024 as i64, + ); + } + if rand_enough() { + return CURLE_OK; + } + + /* fallback to a custom seeding of the PRNG using a hash based on a current + time */ + // TODO - 467 有一段if的条件编译 + // #[cfg(HAVE_RAND_EGD)] + loop { + let mut randb: [u8; 64] = [0; 64]; + let mut len: size_t = ::std::mem::size_of::<[u8; 64]>() as u64; + let mut i: size_t = 0; + let mut i_max: size_t = 0; + i = 0 as size_t; + i_max = len.wrapping_div(::std::mem::size_of::() as u64); + while i < i_max { + let mut tv: curltime = unsafe { Curl_now() }; + unsafe { + Curl_wait_ms(1 as timediff_t); + } + tv.tv_sec = (tv.tv_sec as u64).wrapping_mul(i.wrapping_add(1 as u64)) as time_t; + tv.tv_usec = (tv.tv_usec as u32).wrapping_mul((i as u32).wrapping_add(2 as u32)) as i32; + unsafe { + tv.tv_sec = (tv.tv_sec as u64 + ^ (((Curl_now()).tv_sec + (Curl_now()).tv_usec as i64) as u64) + .wrapping_mul(i.wrapping_add(3 as u64)) + << 8 as i32) as time_t; + tv.tv_usec = (tv.tv_usec as u32 + ^ ((((Curl_now()).tv_sec + (Curl_now()).tv_usec as i64) as u64) + .wrapping_mul(i.wrapping_add(4 as u64)) as u32) + << 16 as i32) as i32; + memcpy( + &mut *randb + .as_mut_ptr() + .offset(i.wrapping_mul(::std::mem::size_of::() as u64) as isize) + as *mut u8 as *mut libc::c_void, + &mut tv as *mut curltime as *const libc::c_void, + ::std::mem::size_of::() as u64, + ); + } + i = i.wrapping_add(1); + } + unsafe { + RAND_add( + randb.as_mut_ptr() as *const libc::c_void, + len as i32, + len as libc::c_double / 2 as libc::c_double, + ); + } + if rand_enough() { + break; + } + } + /* generates a default path for the random seed file */ + fname[0 as usize] = 0 as libc::c_char; /* blank it first */ + unsafe { + RAND_file_name( + fname.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + if fname[0 as usize] != 0 { + /* we got a file name to try */ + unsafe { + RAND_load_file(fname.as_mut_ptr(), 1024 as i64); + } + if rand_enough() { + return CURLE_OK; + } + } + unsafe { + Curl_infof( + data, + b"libcurl is now using a weak random seed!\0" as *const u8 as *const libc::c_char, + ); + } + return (if rand_enough() as i32 != 0 { + CURLE_OK as i32 + } else { + CURLE_SSL_CONNECT_ERROR as i32 + }) as CURLcode; +} + +extern "C" fn do_file_type(mut type_0: *const libc::c_char) -> i32 { + unsafe { + if type_0.is_null() || *type_0.offset(0 as isize) == 0 { + return 1 as i32; + } + if Curl_strcasecompare(type_0, b"PEM\0" as *const u8 as *const libc::c_char) != 0 { + return 1 as i32; + } + if Curl_strcasecompare(type_0, b"DER\0" as *const u8 as *const libc::c_char) != 0 { + return 2 as i32; + } + if Curl_strcasecompare(type_0, b"ENG\0" as *const u8 as *const libc::c_char) != 0 { + return 42 as i32; + } + if Curl_strcasecompare(type_0, b"P12\0" as *const u8 as *const libc::c_char) != 0 { + return 43 as i32; + } + return -(1 as i32); + } +} + +/* + * Supply default password to the engine user interface conversation. + * The password is passed by OpenSSL engine from ENGINE_load_private_key() + * last argument to the ui and can be obtained by UI_get0_user_data(ui) here. + */ +#[cfg(USE_OPENSSL_ENGINE)] +extern "C" fn ssl_ui_reader(mut ui: *mut UI, mut uis: *mut UI_STRING) -> i32 { + let mut password: *const libc::c_char = 0 as *const libc::c_char; + match unsafe { UI_get_string_type(uis) as u32 } { + 1 | 2 => { + password = unsafe { UI_get0_user_data(ui) as *const libc::c_char }; + if !password.is_null() && unsafe { UI_get_input_flags(uis) & 0x2 as i32 != 0 } { + unsafe { + UI_set_result(ui, uis, password); + } + return 1 as i32; + } + } + _ => {} + } + return unsafe { + (UI_method_get_reader(UI_OpenSSL())).expect("non-null function pointer")(ui, uis) + }; +} + +/* + * Suppress interactive request for a default password if available. + */ +#[cfg(USE_OPENSSL_ENGINE)] +extern "C" fn ssl_ui_writer(mut ui: *mut UI, mut uis: *mut UI_STRING) -> i32 { + unsafe { + match UI_get_string_type(uis) as u32 { + 1 | 2 => { + if !(UI_get0_user_data(ui)).is_null() && UI_get_input_flags(uis) & 0x2 as i32 != 0 { + return 1 as i32; + } + } + _ => {} + } + return (UI_method_get_writer(UI_OpenSSL())).expect("non-null function pointer")(ui, uis); + } +} + +/* + * Check if a given string is a PKCS#11 URI + */ +#[cfg(USE_OPENSSL_ENGINE)] +extern "C" fn is_pkcs11_uri(mut string: *const libc::c_char) -> bool { + unsafe { + return !string.is_null() + && Curl_strncasecompare( + string, + b"pkcs11:\0" as *const u8 as *const libc::c_char, + 7 as size_t, + ) != 0; + } +} +extern "C" fn SSL_CTX_use_certificate_blob( + mut ctx: *mut SSL_CTX, + mut blob: *const curl_blob, + mut type_0: i32, + mut key_passwd: *const libc::c_char, +) -> i32 { + let mut current_block: u64; + let mut ret: i32 = 0 as i32; + let mut x: *mut X509 = 0 as *mut X509; + /* the typecast of blob->len is fine since it is guaranteed to never be + larger than CURL_MAX_INPUT_LENGTH */ + let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; + if in_0.is_null() { + return CURLE_OUT_OF_MEMORY as i32; + } + 'end: loop { + if type_0 == 2 as i32 { + /* j = ERR_R_ASN1_LIB; */ + x = unsafe { d2i_X509_bio(in_0, 0 as *mut *mut X509) }; + } else if type_0 == 1 as i32 { + /* ERR_R_PEM_LIB; */ + x = unsafe { + PEM_read_bio_X509( + in_0, + 0 as *mut *mut X509, + Some( + passwd_callback + as unsafe extern "C" fn( + *mut libc::c_char, + i32, + i32, + *mut libc::c_void, + ) -> i32, + ), + key_passwd as *mut libc::c_void, + ) + }; + } else { + ret = 0 as i32; + break 'end; + } + if x.is_null() { + ret = 0 as i32; + break 'end; + } + ret = unsafe { SSL_CTX_use_certificate(ctx, x) }; + break 'end; + } + unsafe { + X509_free(x); + BIO_free(in_0); + } + return ret; +} + +extern "C" fn SSL_CTX_use_PrivateKey_blob( + mut ctx: *mut SSL_CTX, + mut blob: *const curl_blob, + mut type_0: i32, + mut key_passwd: *const libc::c_char, +) -> i32 { + /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ + let mut current_block: u64; + let mut ret: i32 = 0 as i32; + let mut pkey: *mut EVP_PKEY = 0 as *mut EVP_PKEY; + let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; + if in_0.is_null() { + return CURLE_OUT_OF_MEMORY as i32; + } + 'end: loop { + if type_0 == 1 as i32 { + pkey = unsafe { + PEM_read_bio_PrivateKey( + in_0, + 0 as *mut *mut EVP_PKEY, + Some( + passwd_callback + as unsafe extern "C" fn( + *mut libc::c_char, + i32, + i32, + *mut libc::c_void, + ) -> i32, + ), + key_passwd as *mut libc::c_void, + ) + }; + } else if type_0 == 2 as i32 { + pkey = unsafe { d2i_PrivateKey_bio(in_0, 0 as *mut *mut EVP_PKEY) }; + } else { + ret = 0 as i32; + break 'end; + } + if pkey.is_null() { + ret = 0 as i32; + break 'end; + } + unsafe { + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + } + break 'end; + } + unsafe { + BIO_free(in_0); + } + return ret; +} +extern "C" fn SSL_CTX_use_certificate_chain_blob( + mut ctx: *mut SSL_CTX, + mut blob: *const curl_blob, + mut key_passwd: *const libc::c_char, +) -> i32 { + /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ + // TODO - 672 与OPENSSL_VERSION_NUMBER有关的条件编译 + let mut current_block: u64; + let mut ret: i32 = 0 as i32; + let mut x: *mut X509 = 0 as *mut X509; + let mut passwd_callback_userdata: *mut libc::c_void = key_passwd as *mut libc::c_void; + let mut in_0: *mut BIO = unsafe { BIO_new_mem_buf((*blob).data, (*blob).len as i32) }; + if in_0.is_null() { + return CURLE_OUT_OF_MEMORY as i32; + } + unsafe { + ERR_clear_error(); + x = PEM_read_bio_X509_AUX( + in_0, + 0 as *mut *mut X509, + Some( + passwd_callback + as unsafe extern "C" fn(*mut libc::c_char, i32, i32, *mut libc::c_void) -> i32, + ), + key_passwd as *mut libc::c_void, + ); + } + 'end: loop { + if x.is_null() { + ret = 0 as i32; + break 'end; + } + ret = unsafe { SSL_CTX_use_certificate(ctx, x) }; + if unsafe { ERR_peek_error() } != 0 as u64 { + ret = 0 as i32; + } + if ret != 0 { + let mut ca: *mut X509 = 0 as *mut X509; + let mut err: u64 = 0; + if unsafe { + SSL_CTX_ctrl( + ctx, + 88 as i32, + 0 as i64, + 0 as *mut libc::c_void as *mut libc::c_char as *mut libc::c_void, + ) + } == 0 + { + ret = 0 as i32; + break 'end; + } + loop { + ca = unsafe { + PEM_read_bio_X509( + in_0, + 0 as *mut *mut X509, + Some( + passwd_callback + as unsafe extern "C" fn( + *mut libc::c_char, + i32, + i32, + *mut libc::c_void, + ) -> i32, + ), + passwd_callback_userdata, + ) + }; + if ca.is_null() { + break; + } + if unsafe { + SSL_CTX_ctrl( + ctx, + 89 as i32, + 0 as i64, + ca as *mut libc::c_char as *mut libc::c_void, + ) + } == 0 + { + unsafe { + X509_free(ca); + } + ret = 0 as i32; + break 'end; + } + } + err = unsafe { ERR_peek_last_error() }; + if (err >> 24 as i64 & 0xff as u64) as i32 == 9 as i32 + && (err & 0xfff as u64) as i32 == 108 as i32 + { + unsafe { ERR_clear_error() }; + } else { + ret = 0 as i32; + } + } + break 'end; + } + unsafe { + X509_free(x); + BIO_free(in_0); + } + return ret; +} + +extern "C" fn cert_stuff( + mut data: *mut Curl_easy, + mut ctx: *mut SSL_CTX, + mut cert_file: *mut libc::c_char, + mut cert_blob: *const curl_blob, + mut cert_type: *const libc::c_char, + mut key_file: *mut libc::c_char, + mut key_blob: *const curl_blob, + mut key_type: *const libc::c_char, + mut key_passwd: *mut libc::c_char, +) -> i32 { + let mut current_block: u64; + let mut error_buffer: [libc::c_char; 256] = [0; 256]; + let mut check_privkey: bool = 1 as i32 != 0; + let mut file_type: i32 = do_file_type(cert_type); + if !cert_file.is_null() || !cert_blob.is_null() || file_type == 42 as i32 { + let mut ssl: *mut SSL = 0 as *mut SSL; + let mut x509: *mut X509 = 0 as *mut X509; + let mut cert_done: i32 = 0 as i32; + let mut cert_use_result: i32 = 0; + if !key_passwd.is_null() { + /* set the password in the callback userdata */ + unsafe { + SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd as *mut libc::c_void); + /* Set passwd callback: */ + SSL_CTX_set_default_passwd_cb( + ctx, + Some( + passwd_callback + as unsafe extern "C" fn( + *mut libc::c_char, + i32, + i32, + *mut libc::c_void, + ) -> i32, + ), + ); + } + } + + match file_type { + 1 => { + /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ + cert_use_result = if !cert_blob.is_null() { + SSL_CTX_use_certificate_chain_blob(ctx, cert_blob, key_passwd) + } else { + unsafe { SSL_CTX_use_certificate_chain_file(ctx, cert_file) } + }; + if cert_use_result != 1 as i32 { + unsafe { + Curl_failf( data, b"could not load PEM client certificate, OpenSSL error %s, (no key found, wrong pass phrase, or wrong file format?)\0" as *const u8 as *const libc::c_char, @@ -741,22 +741,22 @@ ::std::mem::size_of::<[libc::c_char; 256]>() as u64, ), ); - } - return 0 as i32; - } - } - 2 => { - /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but - we use the case above for PEM so this can only be performed with - ASN1 files. */ - cert_use_result = if !cert_blob.is_null() { - SSL_CTX_use_certificate_blob(ctx, cert_blob, file_type, key_passwd) - } else { - unsafe { SSL_CTX_use_certificate_file(ctx, cert_file, file_type) } - }; - if cert_use_result != 1 as i32 { - unsafe { - Curl_failf( + } + return 0 as i32; + } + } + 2 => { + /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but + we use the case above for PEM so this can only be performed with + ASN1 files. */ + cert_use_result = if !cert_blob.is_null() { + SSL_CTX_use_certificate_blob(ctx, cert_blob, file_type, key_passwd) + } else { + unsafe { SSL_CTX_use_certificate_file(ctx, cert_file, file_type) } + }; + if cert_use_result != 1 as i32 { + unsafe { + Curl_failf( data, b"could not load ASN1 client certificate, OpenSSL error %s, (no key found, wrong pass phrase, or wrong file format?)\0" as *const u8 as *const libc::c_char, @@ -766,3222 +766,3222 @@ ::std::mem::size_of::<[libc::c_char; 256]>() as u64, ), ); - } - return 0 as i32; - } - } - // DONE - 804 - 42 => { - unsafe { - /* Implicitly use pkcs11 engine if none was provided and the - * cert_file is a PKCS#11 URI */ - #[cfg(all(USE_OPENSSL_ENGINE, ENGINE_CTRL_GET_CMD_FROM_NAME))] - if ((*data).state.engine).is_null() { - if is_pkcs11_uri(cert_file) { - if ossl_set_engine( - data, - b"pkcs11\0" as *const u8 as *const libc::c_char, - ) as u32 - != CURLE_OK as u32 - { - return 0 as i32; - } - } - } - #[cfg(all(USE_OPENSSL_ENGINE, ENGINE_CTRL_GET_CMD_FROM_NAME))] - if !((*data).state.engine).is_null() { - let mut cmd_name: *const libc::c_char = - b"LOAD_CERT_CTRL\0" as *const u8 as *const libc::c_char; - let mut params: C2RustUnnamed_13 = C2RustUnnamed_13 { - cert_id: 0 as *const libc::c_char, - cert: 0 as *mut X509, - }; - params.cert_id = cert_file; - params.cert = 0 as *mut X509; - /* Does the engine supports LOAD_CERT_CTRL ? */ - if ENGINE_ctrl( - (*data).state.engine as *mut ENGINE, - 13 as i32, - 0 as i64, - cmd_name as *mut libc::c_void, - None, - ) == 0 - { - Curl_failf( - data, - b"ssl engine does not support loading certificates\0" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - /* Load the certificate from the engine */ - if ENGINE_ctrl_cmd( - (*data).state.engine as *mut ENGINE, - cmd_name, - 0 as i64, - &mut params as *mut C2RustUnnamed_13 as *mut libc::c_void, - None, - 1 as i32, - ) == 0 - { - Curl_failf( - data, - b"ssl engine cannot load client cert with id '%s' [%s]\0" - as *const u8 - as *const libc::c_char, - cert_file, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return 0 as i32; - } - if (params.cert).is_null() { - Curl_failf( - data, - b"ssl engine didn't initialized the certificate properly.\0" - as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - if SSL_CTX_use_certificate(ctx, params.cert) != 1 as i32 { - Curl_failf( - data, - b"unable to set client certificate\0" as *const u8 - as *const libc::c_char, - ); - X509_free(params.cert); - return 0 as i32; - } - X509_free(params.cert); /* we don't need the handle any more... */ - } else { - Curl_failf( - data, - b"crypto engine not set, can't load certificate\0" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - #[cfg(any(not(USE_OPENSSL_ENGINE), not(ENGINE_CTRL_GET_CMD_FROM_NAME)))] - Curl_failf( - data, - b"file type ENG for certificate not implemented" as *const u8 - as *const libc::c_char, - ); - } - #[cfg(any(not(USE_OPENSSL_ENGINE), not(ENGINE_CTRL_GET_CMD_FROM_NAME)))] - return 0 as i32; - } - 43 => { - let mut cert_bio: *mut BIO = 0 as *mut BIO; - let mut p12: *mut PKCS12 = 0 as *mut PKCS12; - let mut pri: *mut EVP_PKEY = 0 as *mut EVP_PKEY; - let mut ca: *mut stack_st_X509 = 0 as *mut stack_st_X509; - if !cert_blob.is_null() { - unsafe { - cert_bio = BIO_new_mem_buf((*cert_blob).data, (*cert_blob).len as i32); - if cert_bio.is_null() { - Curl_failf( - data, - b"BIO_new_mem_buf NULL, OpenSSL error %s\0" as *const u8 - as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - } - return 0 as i32; - } - } else { - unsafe { - cert_bio = BIO_new(BIO_s_file()); - if cert_bio.is_null() { - Curl_failf( - data, - b"BIO_new return NULL, OpenSSL error %s\0" as *const u8 - as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return 0 as i32; - } - if BIO_ctrl( - cert_bio, - 108 as i32, - (0x1 as i32 | 0x2 as i32) as i64, - cert_file as *mut libc::c_void, - ) as i32 - <= 0 as i32 - { - Curl_failf( - data, - b"could not open PKCS12 file '%s'\0" as *const u8 - as *const libc::c_char, - cert_file, - ); - BIO_free(cert_bio); - return 0 as i32; - } - } - } - unsafe { - p12 = d2i_PKCS12_bio(cert_bio, 0 as *mut *mut PKCS12); - BIO_free(cert_bio); - if p12.is_null() { - Curl_failf( - data, - b"error reading PKCS12 file '%s'\0" as *const u8 as *const libc::c_char, - if !cert_blob.is_null() { - b"(memory blob)\0" as *const u8 as *const libc::c_char - } else { - cert_file as *const libc::c_char - }, - ); - return 0 as i32; - } - PKCS12_PBE_add(); - if PKCS12_parse(p12, key_passwd, &mut pri, &mut x509, &mut ca) == 0 { - Curl_failf( - data, - b"could not parse PKCS12 file, check password, OpenSSL error %s\0" - as *const u8 as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - PKCS12_free(p12); - return 0 as i32; - } - - PKCS12_free(p12); - } - 'fail: loop { - if unsafe { SSL_CTX_use_certificate(ctx, x509) } != 1 as i32 { - unsafe { - Curl_failf( - data, - b"could not load PKCS12 client certificate, OpenSSL error %s\0" - as *const u8 - as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - } - break 'fail; - } - if unsafe { SSL_CTX_use_PrivateKey(ctx, pri) } != 1 as i32 { - unsafe { - Curl_failf( - data, - b"unable to use private key from PKCS12 file '%s'\0" as *const u8 - as *const libc::c_char, - cert_file, - ); - } - break 'fail; - } - if unsafe { SSL_CTX_check_private_key(ctx) } == 0 { - unsafe { - Curl_failf( + } + return 0 as i32; + } + } + // DONE - 804 + 42 => { + unsafe { + /* Implicitly use pkcs11 engine if none was provided and the + * cert_file is a PKCS#11 URI */ + #[cfg(all(USE_OPENSSL_ENGINE, ENGINE_CTRL_GET_CMD_FROM_NAME))] + if ((*data).state.engine).is_null() { + if is_pkcs11_uri(cert_file) { + if ossl_set_engine( + data, + b"pkcs11\0" as *const u8 as *const libc::c_char, + ) as u32 + != CURLE_OK as u32 + { + return 0 as i32; + } + } + } + #[cfg(all(USE_OPENSSL_ENGINE, ENGINE_CTRL_GET_CMD_FROM_NAME))] + if !((*data).state.engine).is_null() { + let mut cmd_name: *const libc::c_char = + b"LOAD_CERT_CTRL\0" as *const u8 as *const libc::c_char; + let mut params: C2RustUnnamed_13 = C2RustUnnamed_13 { + cert_id: 0 as *const libc::c_char, + cert: 0 as *mut X509, + }; + params.cert_id = cert_file; + params.cert = 0 as *mut X509; + /* Does the engine supports LOAD_CERT_CTRL ? */ + if ENGINE_ctrl( + (*data).state.engine as *mut ENGINE, + 13 as i32, + 0 as i64, + cmd_name as *mut libc::c_void, + None, + ) == 0 + { + Curl_failf( + data, + b"ssl engine does not support loading certificates\0" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + /* Load the certificate from the engine */ + if ENGINE_ctrl_cmd( + (*data).state.engine as *mut ENGINE, + cmd_name, + 0 as i64, + &mut params as *mut C2RustUnnamed_13 as *mut libc::c_void, + None, + 1 as i32, + ) == 0 + { + Curl_failf( + data, + b"ssl engine cannot load client cert with id '%s' [%s]\0" + as *const u8 + as *const libc::c_char, + cert_file, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return 0 as i32; + } + if (params.cert).is_null() { + Curl_failf( + data, + b"ssl engine didn't initialized the certificate properly.\0" + as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + if SSL_CTX_use_certificate(ctx, params.cert) != 1 as i32 { + Curl_failf( + data, + b"unable to set client certificate\0" as *const u8 + as *const libc::c_char, + ); + X509_free(params.cert); + return 0 as i32; + } + X509_free(params.cert); /* we don't need the handle any more... */ + } else { + Curl_failf( + data, + b"crypto engine not set, can't load certificate\0" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + #[cfg(any(not(USE_OPENSSL_ENGINE), not(ENGINE_CTRL_GET_CMD_FROM_NAME)))] + Curl_failf( + data, + b"file type ENG for certificate not implemented" as *const u8 + as *const libc::c_char, + ); + } + #[cfg(any(not(USE_OPENSSL_ENGINE), not(ENGINE_CTRL_GET_CMD_FROM_NAME)))] + return 0 as i32; + } + 43 => { + let mut cert_bio: *mut BIO = 0 as *mut BIO; + let mut p12: *mut PKCS12 = 0 as *mut PKCS12; + let mut pri: *mut EVP_PKEY = 0 as *mut EVP_PKEY; + let mut ca: *mut stack_st_X509 = 0 as *mut stack_st_X509; + if !cert_blob.is_null() { + unsafe { + cert_bio = BIO_new_mem_buf((*cert_blob).data, (*cert_blob).len as i32); + if cert_bio.is_null() { + Curl_failf( + data, + b"BIO_new_mem_buf NULL, OpenSSL error %s\0" as *const u8 + as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + return 0 as i32; + } + } else { + unsafe { + cert_bio = BIO_new(BIO_s_file()); + if cert_bio.is_null() { + Curl_failf( + data, + b"BIO_new return NULL, OpenSSL error %s\0" as *const u8 + as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return 0 as i32; + } + if BIO_ctrl( + cert_bio, + 108 as i32, + (0x1 as i32 | 0x2 as i32) as i64, + cert_file as *mut libc::c_void, + ) as i32 + <= 0 as i32 + { + Curl_failf( + data, + b"could not open PKCS12 file '%s'\0" as *const u8 + as *const libc::c_char, + cert_file, + ); + BIO_free(cert_bio); + return 0 as i32; + } + } + } + unsafe { + p12 = d2i_PKCS12_bio(cert_bio, 0 as *mut *mut PKCS12); + BIO_free(cert_bio); + if p12.is_null() { + Curl_failf( + data, + b"error reading PKCS12 file '%s'\0" as *const u8 as *const libc::c_char, + if !cert_blob.is_null() { + b"(memory blob)\0" as *const u8 as *const libc::c_char + } else { + cert_file as *const libc::c_char + }, + ); + return 0 as i32; + } + PKCS12_PBE_add(); + if PKCS12_parse(p12, key_passwd, &mut pri, &mut x509, &mut ca) == 0 { + Curl_failf( + data, + b"could not parse PKCS12 file, check password, OpenSSL error %s\0" + as *const u8 as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + PKCS12_free(p12); + return 0 as i32; + } + + PKCS12_free(p12); + } + 'fail: loop { + if unsafe { SSL_CTX_use_certificate(ctx, x509) } != 1 as i32 { + unsafe { + Curl_failf( + data, + b"could not load PKCS12 client certificate, OpenSSL error %s\0" + as *const u8 + as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + break 'fail; + } + if unsafe { SSL_CTX_use_PrivateKey(ctx, pri) } != 1 as i32 { + unsafe { + Curl_failf( + data, + b"unable to use private key from PKCS12 file '%s'\0" as *const u8 + as *const libc::c_char, + cert_file, + ); + } + break 'fail; + } + if unsafe { SSL_CTX_check_private_key(ctx) } == 0 { + unsafe { + Curl_failf( data, b"private key from PKCS12 file '%s' does not match certificate in same file\0" as *const u8 as *const libc::c_char, cert_file, ); - } - break 'fail; - } - /* Set Certificate Verification chain */ - if !ca.is_null() { - while sk_X509_num(ca) != 0 { - /* - * Note that sk_X509_pop() is used below to make sure the cert is - * removed from the stack properly before getting passed to - * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously - * we used sk_X509_value() instead, but then we'd clean it in the - * subsequent sk_X509_pop_free() call. - */ - let mut x: *mut X509 = sk_X509_pop(ca); - if unsafe { SSL_CTX_add_client_CA(ctx, x) } == 0 { - unsafe { - X509_free(x); - Curl_failf( - data, - b"cannot add certificate to client CA list\0" as *const u8 - as *const libc::c_char, - ); - } - break 'fail; - } - if unsafe { - SSL_CTX_ctrl( - ctx, - 14 as i32, - 0 as i64, - x as *mut libc::c_char as *mut libc::c_void, - ) - } == 0 - { - unsafe { - X509_free(x); - Curl_failf( - data, - b"cannot add certificate to certificate chain\0" - as *const u8 - as *const libc::c_char, - ); - } - break 'fail; - } - } - break 'fail; - } - cert_done = 1 as i32; - } - unsafe { - EVP_PKEY_free(pri); - X509_free(x509); - - #[cfg(USE_AMISSL)] - sk_X509_pop_free( - ca, - Some(Curl_amiga_X509_free as unsafe extern "C" fn(*mut X509) -> ()), - ); - #[cfg(not(USE_AMISSL))] - sk_X509_pop_free(ca, Some(X509_free as unsafe extern "C" fn(*mut X509) -> ())); - if cert_done == 0 { - return 0 as i32; - } - } - } - _ => { - unsafe { - Curl_failf( - data, - b"not supported file type '%s' for certificate\0" as *const u8 - as *const libc::c_char, - cert_type, - ); - } - return 0 as i32; - } - } - if key_file.is_null() && key_blob.is_null() { - key_file = cert_file; - key_blob = cert_blob; - } else { - file_type = do_file_type(key_type); - } - let mut current_block_141: u64; - match file_type { - 1 => { - if cert_done != 0 { - current_block_141 = 14358540534591340610; - } else { - current_block_141 = 2766187242236248435; - } - } - 2 => { - current_block_141 = 2766187242236248435; - } - // DONE - 1011 - 42 => match () { - #[cfg(USE_OPENSSL_ENGINE)] - _ => { - /* XXXX still needs some work */ - let mut priv_key: *mut EVP_PKEY = 0 as *mut EVP_PKEY; - unsafe { - /* Implicitly use pkcs11 engine if none was provided and the - * key_file is a PKCS#11 URI */ - if ((*data).state.engine).is_null() { - if is_pkcs11_uri(key_file) { - if ossl_set_engine( - data, - b"pkcs11\0" as *const u8 as *const libc::c_char, - ) as u32 - != CURLE_OK as u32 - { - return 0 as i32; - } - } - } - if !((*data).state.engine).is_null() { - let mut ui_method: *mut UI_METHOD = UI_create_method( - b"curl user interface\0" as *const u8 as *const libc::c_char - as *mut libc::c_char, - ); - if ui_method.is_null() { - Curl_failf( - data, - b"unable do create OpenSSL user-interface method\0" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); - UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); - UI_method_set_reader( - ui_method, - Some( - ssl_ui_reader - as unsafe extern "C" fn(*mut UI, *mut UI_STRING) -> i32, - ), - ); - UI_method_set_writer( - ui_method, - Some( - ssl_ui_writer - as unsafe extern "C" fn(*mut UI, *mut UI_STRING) -> i32, - ), - ); - /* the typecast below was added to please mingw32 */ - priv_key = ENGINE_load_private_key( - (*data).state.engine as *mut ENGINE, - key_file, - ui_method, - key_passwd as *mut libc::c_void, - ); - UI_destroy_method(ui_method); - if priv_key.is_null() { - Curl_failf( - data, - b"failed to load private key from crypto engine\0" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - } - if SSL_CTX_use_PrivateKey(ctx, priv_key) != 1 as i32 { - Curl_failf( - data, - b"unable to set private key\0" as *const u8 - as *const libc::c_char, - ); - EVP_PKEY_free(priv_key); /* we don't need the handle any more... */ - return 0 as i32; - } - EVP_PKEY_free(priv_key); - } else { - Curl_failf( - data, - b"crypto engine not set, can't load private key\0" as *const u8 - as *const libc::c_char, - ); - - return 0 as i32; - } - current_block_141 = 14358540534591340610; - } - } - #[cfg(not(USE_OPENSSL_ENGINE))] - _ => unsafe { - Curl_failf( - data, - b"file type ENG for private key not supported" as *const u8 - as *const libc::c_char, - ); - return 0 as i32; - }, - }, - 43 => { - if cert_done == 0 { - unsafe { - Curl_failf( - data, - b"file type P12 for private key not supported\0" as *const u8 - as *const libc::c_char, - ); - } - return 0 as i32; - } - current_block_141 = 14358540534591340610; - } - _ => { - unsafe { - Curl_failf( - data, - b"not supported file type for private key\0" as *const u8 - as *const libc::c_char, - ); - } - return 0 as i32; - } - } - match current_block_141 { - 2766187242236248435 => { - cert_use_result = if !key_blob.is_null() { - SSL_CTX_use_PrivateKey_blob(ctx, key_blob, file_type, key_passwd) - } else { - unsafe { SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) } - }; - if cert_use_result != 1 as i32 { - unsafe { - Curl_failf( - data, - b"unable to set private key file: '%s' type %s\0" as *const u8 - as *const libc::c_char, - if !key_file.is_null() { - key_file as *const libc::c_char - } else { - b"(memory blob)\0" as *const u8 as *const libc::c_char - }, - if !key_type.is_null() { - key_type - } else { - b"PEM\0" as *const u8 as *const libc::c_char - }, - ); - } - return 0 as i32; - } - } - _ => {} - } - unsafe { - ssl = SSL_new(ctx); - if ssl.is_null() { - Curl_failf( - data, - b"unable to create an SSL structure\0" as *const u8 as *const libc::c_char, - ); - return 0 as i32; - } - x509 = SSL_get_certificate(ssl); - } - /* This version was provided by Evan Jordan and is supposed to not - leak memory as the previous version: */ - if !x509.is_null() { - unsafe { - let mut pktmp: *mut EVP_PKEY = X509_get_pubkey(x509); - EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl)); - EVP_PKEY_free(pktmp); - } - } - #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL)))] - let mut priv_key_0: *mut EVP_PKEY = unsafe { SSL_get_privatekey(ssl) }; - - #[cfg(all( - not(OPENSSL_NO_RSA), - not(OPENSSL_IS_BORINGSSL), - not(HAVE_OPAQUE_EVP_PKEY) - ))] - // TODO 未开的情况下不是 = 0,是另一种情况 - let mut pktype: i32 = 0; - #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL), HAVE_OPAQUE_EVP_PKEY))] - let mut pktype: i32 = EVP_PKEY_id(priv_key_0); - // TODO - 不开HAVE_OPAQUE_EVP_PKEY选项 - // #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL), not(HAVE_OPAQUE_EVP_PKEY)))] - #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL)))] - if pktype == 6 as i32 { - let mut rsa: *mut RSA = unsafe { EVP_PKEY_get1_RSA(priv_key_0) }; - unsafe { - if RSA_flags(rsa) & 0x1 as i32 != 0 { - check_privkey = 0 as i32 != 0; - } - RSA_free(rsa); /* Decrement reference count */ - } - } - unsafe { - SSL_free(ssl); - } - /* If we are using DSA, we can copy the parameters from - * the private key */ - if check_privkey as i32 == 1 as i32 { - /* Now we know that a key and cert have been set against - * the SSL context */ - if unsafe { SSL_CTX_check_private_key(ctx) == 0 } { - unsafe { - Curl_failf( - data, - b"Private key does not match the certificate public key\0" as *const u8 - as *const libc::c_char, - ); - } - return 0 as i32; - } - } - } - return 1 as i32; - } - - /* returns non-zero on failure */ - extern "C" fn x509_name_oneline( - mut a: *mut X509_NAME, - mut buf: *mut libc::c_char, - mut size: size_t, - ) -> i32 { - let mut bio_out: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; - let mut biomem: *mut BUF_MEM = 0 as *mut BUF_MEM; - let mut rc: i32 = 0; - if bio_out.is_null() { - return 1 as i32; /* alloc failed! */ - } - rc = unsafe { X509_NAME_print_ex(bio_out, a, 0 as i32, ((3 as i32) << 16 as i32) as u64) }; - unsafe { - BIO_ctrl( - bio_out, - 115 as i32, - 0 as i64, - &mut biomem as *mut *mut BUF_MEM as *mut libc::c_char as *mut libc::c_void, - ); - if (*biomem).length < size { - size = (*biomem).length; - } else { - size = size.wrapping_sub(1); /* don't overwrite the buffer end */ - } - memcpy( - buf as *mut libc::c_void, - (*biomem).data as *const libc::c_void, - size, - ); - *buf.offset(size as isize) = 0 as libc::c_char; - BIO_free(bio_out); - } - return (rc == 0) as i32; - } - - /** - * Global SSL init - * - * @retval 0 error initializing SSL - * @retval 1 SSL initialized successfully - */ - extern "C" fn ossl_init() -> i32 { - #[cfg(OPENSSL_INIT_ENGINE_ALL_BUILTIN)] - let flag_1 = 0x200 as i64 | 0x400 as i64 | 0x1000 as i64 | 0x2000 as i64 | 0x4000 as i64; - #[cfg(not(OPENSSL_INIT_ENGINE_ALL_BUILTIN))] - let flag_1 = 0x0000 as i64; - #[cfg(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG)] - let flag_2 = 0x80 as i64; - #[cfg(not(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG))] - let flag_2 = 0x40 as i64; - let flags: uint64_t = (flag_1 | flag_2 | 0 as i64) as uint64_t; - - unsafe { - OPENSSL_init_ssl(flags, 0 as *const OPENSSL_INIT_SETTINGS); - } - Curl_tls_keylog_open(); - /* Initialize the extra data indexes */ - if ossl_get_ssl_data_index() < 0 as i32 - || ossl_get_ssl_conn_index() < 0 as i32 - || ossl_get_ssl_sockindex_index() < 0 as i32 - || ossl_get_proxy_index() < 0 as i32 - { - return 0 as i32; - } - return 1 as i32; - } - - /* Global cleanup */ - extern "C" fn ossl_cleanup() { - Curl_tls_keylog_close(); - } - - /* - * This function is used to determine connection status. - * - * Return codes: - * 1 means the connection is still in place - * 0 means the connection has been closed - * -1 means the connection status is unknown - */ - extern "C" fn ossl_check_cxn(mut conn: *mut connectdata) -> i32 { - /* SSL_peek takes data out of the raw recv buffer without peeking so we use - recv MSG_PEEK instead. Bug #795 */ - #[cfg(MSG_PEEK)] - let mut buf: libc::c_char = 0; - #[cfg(MSG_PEEK)] - let mut nread: ssize_t = recv( - (*conn).sock[0 as usize], - &mut buf as *mut libc::c_char as *mut libc::c_void, - 1 as size_t, - MSG_PEEK as i32, - ); - #[cfg(MSG_PEEK)] - if nread == 0 as i64 { - return 0 as i32; /* connection has been closed */ - } - #[cfg(MSG_PEEK)] - if nread == 1 as i64 { - return 1 as i32; /* connection still in place */ - } else { - if nread == -(1 as i32) as i64 { - let mut err: i32 = *__errno_location(); - // 写法不对,rust中如何判断宏值的相等 - // TODO - 1276 - if err == 115 as i32 || err == 11 as i32 { - return 1 as i32; /* connection still in place */ - } - // DONE - 1282 - #[cfg(ECONNABORTED)] - let ECONNABORTED_flag = err == 103; - #[cfg(not(ECONNABORTED))] - let ECONNABORTED_flag = false; - #[cfg(ENETDOWN)] - let ENETDOWN_flag = err == 100; - #[cfg(not(ENETDOWN))] - let ENETDOWN_flag = false; - #[cfg(ENETRESET)] - let ENETRESET_flag = err == 102; - #[cfg(not(ENETRESET))] - let ENETRESET_flag = false; - #[cfg(ESHUTDOWN)] - let ESHUTDOWN_flag = err == 108; - #[cfg(not(ESHUTDOWN))] - let ESHUTDOWN_flag = false; - #[cfg(ETIMEDOUT)] - let ETIMEDOUT_flag = err == 110; - #[cfg(not(ETIMEDOUT))] - let ETIMEDOUT_flag = false; - if err == 104 as i32 - || ECONNABORTED_flag - || ENETDOWN_flag - || ENETRESET_flag - || ENETDOWN_flag - || ETIMEDOUT_flag - || err == 107 as i32 - { - return 0 as i32; /* connection has been closed */ - } - } - } - return -(1 as i32); /* connection status unknown */ - } - - /* Selects an OpenSSL crypto engine - */ - extern "C" fn ossl_set_engine( - mut data: *mut Curl_easy, - mut engine: *const libc::c_char, - ) -> CURLcode { - if cfg!(USE_OPENSSL_ENGINE) { - let mut e: *mut ENGINE = 0 as *mut ENGINE; - e = unsafe { ENGINE_by_id(engine) }; - if e.is_null() { - unsafe { - Curl_failf( - data, - b"SSL Engine '%s' not found\0" as *const u8 as *const libc::c_char, - engine, - ); - } - return CURLE_SSL_ENGINE_NOTFOUND; - } - unsafe { - if !((*data).state.engine).is_null() { - ENGINE_finish((*data).state.engine as *mut ENGINE); - ENGINE_free((*data).state.engine as *mut ENGINE); - (*data).state.engine = 0 as *mut libc::c_void; - } - if ENGINE_init(e) == 0 { - let mut buf: [libc::c_char; 256] = [0; 256]; - ENGINE_free(e); - Curl_failf( - data, - b"Failed to initialise SSL Engine '%s': %s\0" as *const u8 - as *const libc::c_char, - engine, - ossl_strerror( - ERR_get_error(), - buf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return CURLE_SSL_ENGINE_INITFAILED; - } - (*data).state.engine = e as *mut libc::c_void; - } - return CURLE_OK; - } else { - unsafe { - Curl_infof( - data, - b"SSL Engine not supported\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_SSL_ENGINE_NOTFOUND; - } - } - - /* Sets engine as default for all SSL operations - */ - extern "C" fn ossl_set_engine_default(mut data: *mut Curl_easy) -> CURLcode { - if cfg!(USE_OPENSSL_ENGINE) { - unsafe { - if !((*data).state.engine).is_null() { - if ENGINE_set_default((*data).state.engine as *mut ENGINE, 0xffff as i32 as u32) - > 0 as i32 - { - Curl_infof( - data, - b"set default crypto engine '%s'\0" as *const u8 as *const libc::c_char, - ENGINE_get_id((*data).state.engine as *const ENGINE), - ); - } else { - Curl_failf( - data, - b"set default crypto engine '%s' failed\0" as *const u8 - as *const libc::c_char, - ENGINE_get_id((*data).state.engine as *const ENGINE), - ); - return CURLE_SSL_ENGINE_SETFAILED; - } - } - } - } - return CURLE_OK; - } - - /* Return list of OpenSSL crypto engine names. - */ - extern "C" fn ossl_engines_list(mut data: *mut Curl_easy) -> *mut curl_slist { - let mut list: *mut curl_slist = 0 as *mut curl_slist; - if cfg!(USE_OPENSSL_ENGINE) { - let mut beg: *mut curl_slist = 0 as *mut curl_slist; - let mut e: *mut ENGINE = 0 as *mut ENGINE; - e = unsafe { ENGINE_get_first() }; - while !e.is_null() { - unsafe { - beg = curl_slist_append(list, ENGINE_get_id(e)); - if beg.is_null() { - curl_slist_free_all(list); - return 0 as *mut curl_slist; - } - } - list = beg; - e = unsafe { ENGINE_get_next(e) }; - } - } - return list; - } - extern "C" fn ossl_closeone( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut connssl: *mut ssl_connect_data, - ) { - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - unsafe { - if !((*backend).handle).is_null() { - let mut buf: [libc::c_char; 32] = [0; 32]; - (*(*conn).ssl[0 as usize].backend).logger = data; - /* Maybe the server has already sent a close notify alert. - Read it to avoid an RST on the TCP connection. */ - SSL_read( - (*backend).handle, - buf.as_mut_ptr() as *mut libc::c_void, - ::std::mem::size_of::<[libc::c_char; 32]>() as i32, - ); - SSL_shutdown((*backend).handle); - SSL_set_connect_state((*backend).handle); - SSL_free((*backend).handle); - (*backend).handle = 0 as *mut SSL; - } - if !((*backend).ctx).is_null() { - SSL_CTX_free((*backend).ctx); - (*backend).ctx = 0 as *mut SSL_CTX; - } - } - } - - /* - * This function is called when an SSL connection is closed. - */ - extern "C" fn ossl_close(mut data: *mut Curl_easy, mut conn: *mut connectdata, mut sockindex: i32) { - unsafe { - ossl_closeone( - data, - conn, - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize), - ); - #[cfg(not(CURL_DISABLE_PROXY))] - ossl_closeone( - data, - conn, - &mut *((*conn).proxy_ssl).as_mut_ptr().offset(sockindex as isize), - ); - } - } - - /* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ - extern "C" fn ossl_shutdown( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) -> i32 { - let mut retval: i32 = 0 as i32; - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - let mut buf: [libc::c_char; 256] = [0; 256]; /* We will use this for the OpenSSL error buffer, so it has - to be at least 256 bytes long. */ - let mut sslerror: u64 = 0; - let mut nread: ssize_t = 0; - let mut buffsize: i32 = 0; - let mut err: i32 = 0; - let mut done: bool = 0 as i32 != 0; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - let mut loop_0: i32 = 10 as i32; - /* This has only been tested on the proftpd server, and the mod_tls code - sends a close notify alert without waiting for a close notify alert in - response. Thus we wait for a close notify alert from the server, but - we do not send one. Let's hope other servers do the same... */ - #[cfg(not(CURL_DISABLE_FTP))] - unsafe { - if (*data).set.ftp_ccc as u32 == CURLFTPSSL_CCC_ACTIVE as u32 { - SSL_shutdown((*backend).handle); - } - } - if unsafe { !((*backend).handle).is_null() } { - buffsize = ::std::mem::size_of::<[libc::c_char; 256]>() as i32; - while !done && { - let fresh5 = loop_0; - loop_0 = loop_0 - 1; - fresh5 != 0 - } { - let mut what: i32 = unsafe { - Curl_socket_check( - (*conn).sock[sockindex as usize], - -(1 as i32), - -(1 as i32), - 10000 as timediff_t, - ) - }; - if what > 0 as i32 { - /* Something to read, let's do it and hope that it is the close - notify alert from the server */ - unsafe { - ERR_clear_error(); - nread = SSL_read( - (*backend).handle, - buf.as_mut_ptr() as *mut libc::c_void, - buffsize, - ) as ssize_t; - err = SSL_get_error((*backend).handle, nread as i32); - } - match err { - 0 | 6 => { - /* This is the expected response. There was no data but only - the close notify alert */ - done = 1 as i32 != 0; - } - 2 => unsafe { - Curl_infof( - data, - b"SSL_ERROR_WANT_READ\0" as *const u8 as *const libc::c_char, - ); - }, - 3 => { - /* SSL wants a write. Really odd. Let's bail out. */ - unsafe { - Curl_infof( - data, - b"SSL_ERROR_WANT_WRITE\0" as *const u8 as *const libc::c_char, - ); - } - done = 1 as i32 != 0; - } - _ => { - /* openssl/ssl.h says "look at error stack/return value/errno" */ - unsafe { - sslerror = ERR_get_error(); - Curl_failf( - data, - b"OpenSSL SSL_read on shutdown: %s, errno %d\0" as *const u8 - as *const libc::c_char, - if sslerror != 0 { - ossl_strerror( - sslerror, - buf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ) as *const libc::c_char - } else { - SSL_ERROR_to_str(err) - }, - *__errno_location(), - ); - } - done = 1 as i32 != 0; - } - } - } else if 0 as i32 == what { - /* timeout */ - unsafe { - Curl_failf( - data, - b"SSL shutdown timeout\0" as *const u8 as *const libc::c_char, - ); - } - done = 1 as i32 != 0; - } else { - /* anything that gets here is fatally bad */ - unsafe { - Curl_failf( - data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, - *__errno_location(), - ); - } - retval = -(1 as i32); - done = 1 as i32 != 0; - } - } /* while()-loop for the select() */ - if unsafe { ((*data).set).verbose() != 0 } { - if cfg!(HAVE_SSL_GET_SHUTDOWN) { - unsafe { - match SSL_get_shutdown((*backend).handle) { - 1 => { - Curl_infof( - data, - b"SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\0" as *const u8 - as *const libc::c_char, - ); - } - 2 => { - Curl_infof( - data, - b"SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\0" as *const u8 - as *const libc::c_char, - ); - } - 3 => { - Curl_infof( + } + break 'fail; + } + /* Set Certificate Verification chain */ + if !ca.is_null() { + while sk_X509_num(ca) != 0 { + /* + * Note that sk_X509_pop() is used below to make sure the cert is + * removed from the stack properly before getting passed to + * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously + * we used sk_X509_value() instead, but then we'd clean it in the + * subsequent sk_X509_pop_free() call. + */ + let mut x: *mut X509 = sk_X509_pop(ca); + if unsafe { SSL_CTX_add_client_CA(ctx, x) } == 0 { + unsafe { + X509_free(x); + Curl_failf( + data, + b"cannot add certificate to client CA list\0" as *const u8 + as *const libc::c_char, + ); + } + break 'fail; + } + if unsafe { + SSL_CTX_ctrl( + ctx, + 14 as i32, + 0 as i64, + x as *mut libc::c_char as *mut libc::c_void, + ) + } == 0 + { + unsafe { + X509_free(x); + Curl_failf( + data, + b"cannot add certificate to certificate chain\0" + as *const u8 + as *const libc::c_char, + ); + } + break 'fail; + } + } + break 'fail; + } + cert_done = 1 as i32; + } + unsafe { + EVP_PKEY_free(pri); + X509_free(x509); + + #[cfg(USE_AMISSL)] + sk_X509_pop_free( + ca, + Some(Curl_amiga_X509_free as unsafe extern "C" fn(*mut X509) -> ()), + ); + #[cfg(not(USE_AMISSL))] + sk_X509_pop_free(ca, Some(X509_free as unsafe extern "C" fn(*mut X509) -> ())); + if cert_done == 0 { + return 0 as i32; + } + } + } + _ => { + unsafe { + Curl_failf( + data, + b"not supported file type '%s' for certificate\0" as *const u8 + as *const libc::c_char, + cert_type, + ); + } + return 0 as i32; + } + } + if key_file.is_null() && key_blob.is_null() { + key_file = cert_file; + key_blob = cert_blob; + } else { + file_type = do_file_type(key_type); + } + let mut current_block_141: u64; + match file_type { + 1 => { + if cert_done != 0 { + current_block_141 = 14358540534591340610; + } else { + current_block_141 = 2766187242236248435; + } + } + 2 => { + current_block_141 = 2766187242236248435; + } + // DONE - 1011 + 42 => match () { + #[cfg(USE_OPENSSL_ENGINE)] + _ => { + /* XXXX still needs some work */ + let mut priv_key: *mut EVP_PKEY = 0 as *mut EVP_PKEY; + unsafe { + /* Implicitly use pkcs11 engine if none was provided and the + * key_file is a PKCS#11 URI */ + if ((*data).state.engine).is_null() { + if is_pkcs11_uri(key_file) { + if ossl_set_engine( + data, + b"pkcs11\0" as *const u8 as *const libc::c_char, + ) as u32 + != CURLE_OK as u32 + { + return 0 as i32; + } + } + } + if !((*data).state.engine).is_null() { + let mut ui_method: *mut UI_METHOD = UI_create_method( + b"curl user interface\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + if ui_method.is_null() { + Curl_failf( + data, + b"unable do create OpenSSL user-interface method\0" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); + UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); + UI_method_set_reader( + ui_method, + Some( + ssl_ui_reader + as unsafe extern "C" fn(*mut UI, *mut UI_STRING) -> i32, + ), + ); + UI_method_set_writer( + ui_method, + Some( + ssl_ui_writer + as unsafe extern "C" fn(*mut UI, *mut UI_STRING) -> i32, + ), + ); + /* the typecast below was added to please mingw32 */ + priv_key = ENGINE_load_private_key( + (*data).state.engine as *mut ENGINE, + key_file, + ui_method, + key_passwd as *mut libc::c_void, + ); + UI_destroy_method(ui_method); + if priv_key.is_null() { + Curl_failf( + data, + b"failed to load private key from crypto engine\0" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + } + if SSL_CTX_use_PrivateKey(ctx, priv_key) != 1 as i32 { + Curl_failf( + data, + b"unable to set private key\0" as *const u8 + as *const libc::c_char, + ); + EVP_PKEY_free(priv_key); /* we don't need the handle any more... */ + return 0 as i32; + } + EVP_PKEY_free(priv_key); + } else { + Curl_failf( + data, + b"crypto engine not set, can't load private key\0" as *const u8 + as *const libc::c_char, + ); + + return 0 as i32; + } + current_block_141 = 14358540534591340610; + } + } + #[cfg(not(USE_OPENSSL_ENGINE))] + _ => unsafe { + Curl_failf( + data, + b"file type ENG for private key not supported" as *const u8 + as *const libc::c_char, + ); + return 0 as i32; + }, + }, + 43 => { + if cert_done == 0 { + unsafe { + Curl_failf( + data, + b"file type P12 for private key not supported\0" as *const u8 + as *const libc::c_char, + ); + } + return 0 as i32; + } + current_block_141 = 14358540534591340610; + } + _ => { + unsafe { + Curl_failf( + data, + b"not supported file type for private key\0" as *const u8 + as *const libc::c_char, + ); + } + return 0 as i32; + } + } + match current_block_141 { + 2766187242236248435 => { + cert_use_result = if !key_blob.is_null() { + SSL_CTX_use_PrivateKey_blob(ctx, key_blob, file_type, key_passwd) + } else { + unsafe { SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) } + }; + if cert_use_result != 1 as i32 { + unsafe { + Curl_failf( + data, + b"unable to set private key file: '%s' type %s\0" as *const u8 + as *const libc::c_char, + if !key_file.is_null() { + key_file as *const libc::c_char + } else { + b"(memory blob)\0" as *const u8 as *const libc::c_char + }, + if !key_type.is_null() { + key_type + } else { + b"PEM\0" as *const u8 as *const libc::c_char + }, + ); + } + return 0 as i32; + } + } + _ => {} + } + unsafe { + ssl = SSL_new(ctx); + if ssl.is_null() { + Curl_failf( + data, + b"unable to create an SSL structure\0" as *const u8 as *const libc::c_char, + ); + return 0 as i32; + } + x509 = SSL_get_certificate(ssl); + } + /* This version was provided by Evan Jordan and is supposed to not + leak memory as the previous version: */ + if !x509.is_null() { + unsafe { + let mut pktmp: *mut EVP_PKEY = X509_get_pubkey(x509); + EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl)); + EVP_PKEY_free(pktmp); + } + } + #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL)))] + let mut priv_key_0: *mut EVP_PKEY = unsafe { SSL_get_privatekey(ssl) }; + + #[cfg(all( + not(OPENSSL_NO_RSA), + not(OPENSSL_IS_BORINGSSL), + not(HAVE_OPAQUE_EVP_PKEY) + ))] + // TODO 未开的情况下不是 = 0,是另一种情况 + let mut pktype: i32 = 0; + #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL), HAVE_OPAQUE_EVP_PKEY))] + let mut pktype: i32 = EVP_PKEY_id(priv_key_0); + // TODO - 不开HAVE_OPAQUE_EVP_PKEY选项 + // #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL), not(HAVE_OPAQUE_EVP_PKEY)))] + #[cfg(all(not(OPENSSL_NO_RSA), not(OPENSSL_IS_BORINGSSL)))] + if pktype == 6 as i32 { + let mut rsa: *mut RSA = unsafe { EVP_PKEY_get1_RSA(priv_key_0) }; + unsafe { + if RSA_flags(rsa) & 0x1 as i32 != 0 { + check_privkey = 0 as i32 != 0; + } + RSA_free(rsa); /* Decrement reference count */ + } + } + unsafe { + SSL_free(ssl); + } + /* If we are using DSA, we can copy the parameters from + * the private key */ + if check_privkey as i32 == 1 as i32 { + /* Now we know that a key and cert have been set against + * the SSL context */ + if unsafe { SSL_CTX_check_private_key(ctx) == 0 } { + unsafe { + Curl_failf( + data, + b"Private key does not match the certificate public key\0" as *const u8 + as *const libc::c_char, + ); + } + return 0 as i32; + } + } + } + return 1 as i32; +} + +/* returns non-zero on failure */ +extern "C" fn x509_name_oneline( + mut a: *mut X509_NAME, + mut buf: *mut libc::c_char, + mut size: size_t, +) -> i32 { + let mut bio_out: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; + let mut biomem: *mut BUF_MEM = 0 as *mut BUF_MEM; + let mut rc: i32 = 0; + if bio_out.is_null() { + return 1 as i32; /* alloc failed! */ + } + rc = unsafe { X509_NAME_print_ex(bio_out, a, 0 as i32, ((3 as i32) << 16 as i32) as u64) }; + unsafe { + BIO_ctrl( + bio_out, + 115 as i32, + 0 as i64, + &mut biomem as *mut *mut BUF_MEM as *mut libc::c_char as *mut libc::c_void, + ); + if (*biomem).length < size { + size = (*biomem).length; + } else { + size = size.wrapping_sub(1); /* don't overwrite the buffer end */ + } + memcpy( + buf as *mut libc::c_void, + (*biomem).data as *const libc::c_void, + size, + ); + *buf.offset(size as isize) = 0 as libc::c_char; + BIO_free(bio_out); + } + return (rc == 0) as i32; +} + +/** + * Global SSL init + * + * @retval 0 error initializing SSL + * @retval 1 SSL initialized successfully + */ +extern "C" fn ossl_init() -> i32 { + #[cfg(OPENSSL_INIT_ENGINE_ALL_BUILTIN)] + let flag_1 = 0x200 as i64 | 0x400 as i64 | 0x1000 as i64 | 0x2000 as i64 | 0x4000 as i64; + #[cfg(not(OPENSSL_INIT_ENGINE_ALL_BUILTIN))] + let flag_1 = 0x0000 as i64; + #[cfg(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG)] + let flag_2 = 0x80 as i64; + #[cfg(not(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG))] + let flag_2 = 0x40 as i64; + let flags: uint64_t = (flag_1 | flag_2 | 0 as i64) as uint64_t; + + unsafe { + OPENSSL_init_ssl(flags, 0 as *const OPENSSL_INIT_SETTINGS); + } + Curl_tls_keylog_open(); + /* Initialize the extra data indexes */ + if ossl_get_ssl_data_index() < 0 as i32 + || ossl_get_ssl_conn_index() < 0 as i32 + || ossl_get_ssl_sockindex_index() < 0 as i32 + || ossl_get_proxy_index() < 0 as i32 + { + return 0 as i32; + } + return 1 as i32; +} + +/* Global cleanup */ +extern "C" fn ossl_cleanup() { + Curl_tls_keylog_close(); +} + +/* + * This function is used to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +extern "C" fn ossl_check_cxn(mut conn: *mut connectdata) -> i32 { + /* SSL_peek takes data out of the raw recv buffer without peeking so we use + recv MSG_PEEK instead. Bug #795 */ + #[cfg(MSG_PEEK)] + let mut buf: libc::c_char = 0; + #[cfg(MSG_PEEK)] + let mut nread: ssize_t = recv( + (*conn).sock[0 as usize], + &mut buf as *mut libc::c_char as *mut libc::c_void, + 1 as size_t, + MSG_PEEK as i32, + ); + #[cfg(MSG_PEEK)] + if nread == 0 as i64 { + return 0 as i32; /* connection has been closed */ + } + #[cfg(MSG_PEEK)] + if nread == 1 as i64 { + return 1 as i32; /* connection still in place */ + } else { + if nread == -(1 as i32) as i64 { + let mut err: i32 = *__errno_location(); + // 写法不对,rust中如何判断宏值的相等 + // TODO - 1276 + if err == 115 as i32 || err == 11 as i32 { + return 1 as i32; /* connection still in place */ + } + // DONE - 1282 + #[cfg(ECONNABORTED)] + let ECONNABORTED_flag = err == 103; + #[cfg(not(ECONNABORTED))] + let ECONNABORTED_flag = false; + #[cfg(ENETDOWN)] + let ENETDOWN_flag = err == 100; + #[cfg(not(ENETDOWN))] + let ENETDOWN_flag = false; + #[cfg(ENETRESET)] + let ENETRESET_flag = err == 102; + #[cfg(not(ENETRESET))] + let ENETRESET_flag = false; + #[cfg(ESHUTDOWN)] + let ESHUTDOWN_flag = err == 108; + #[cfg(not(ESHUTDOWN))] + let ESHUTDOWN_flag = false; + #[cfg(ETIMEDOUT)] + let ETIMEDOUT_flag = err == 110; + #[cfg(not(ETIMEDOUT))] + let ETIMEDOUT_flag = false; + if err == 104 as i32 + || ECONNABORTED_flag + || ENETDOWN_flag + || ENETRESET_flag + || ENETDOWN_flag + || ETIMEDOUT_flag + || err == 107 as i32 + { + return 0 as i32; /* connection has been closed */ + } + } + } + return -(1 as i32); /* connection status unknown */ +} + +/* Selects an OpenSSL crypto engine + */ +extern "C" fn ossl_set_engine( + mut data: *mut Curl_easy, + mut engine: *const libc::c_char, +) -> CURLcode { + if cfg!(USE_OPENSSL_ENGINE) { + let mut e: *mut ENGINE = 0 as *mut ENGINE; + e = unsafe { ENGINE_by_id(engine) }; + if e.is_null() { + unsafe { + Curl_failf( + data, + b"SSL Engine '%s' not found\0" as *const u8 as *const libc::c_char, + engine, + ); + } + return CURLE_SSL_ENGINE_NOTFOUND; + } + unsafe { + if !((*data).state.engine).is_null() { + ENGINE_finish((*data).state.engine as *mut ENGINE); + ENGINE_free((*data).state.engine as *mut ENGINE); + (*data).state.engine = 0 as *mut libc::c_void; + } + if ENGINE_init(e) == 0 { + let mut buf: [libc::c_char; 256] = [0; 256]; + ENGINE_free(e); + Curl_failf( + data, + b"Failed to initialise SSL Engine '%s': %s\0" as *const u8 + as *const libc::c_char, + engine, + ossl_strerror( + ERR_get_error(), + buf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return CURLE_SSL_ENGINE_INITFAILED; + } + (*data).state.engine = e as *mut libc::c_void; + } + return CURLE_OK; + } else { + unsafe { + Curl_infof( + data, + b"SSL Engine not supported\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_SSL_ENGINE_NOTFOUND; + } +} + +/* Sets engine as default for all SSL operations + */ +extern "C" fn ossl_set_engine_default(mut data: *mut Curl_easy) -> CURLcode { + if cfg!(USE_OPENSSL_ENGINE) { + unsafe { + if !((*data).state.engine).is_null() { + if ENGINE_set_default((*data).state.engine as *mut ENGINE, 0xffff as i32 as u32) + > 0 as i32 + { + Curl_infof( + data, + b"set default crypto engine '%s'\0" as *const u8 as *const libc::c_char, + ENGINE_get_id((*data).state.engine as *const ENGINE), + ); + } else { + Curl_failf( + data, + b"set default crypto engine '%s' failed\0" as *const u8 + as *const libc::c_char, + ENGINE_get_id((*data).state.engine as *const ENGINE), + ); + return CURLE_SSL_ENGINE_SETFAILED; + } + } + } + } + return CURLE_OK; +} + +/* Return list of OpenSSL crypto engine names. + */ +extern "C" fn ossl_engines_list(mut data: *mut Curl_easy) -> *mut curl_slist { + let mut list: *mut curl_slist = 0 as *mut curl_slist; + if cfg!(USE_OPENSSL_ENGINE) { + let mut beg: *mut curl_slist = 0 as *mut curl_slist; + let mut e: *mut ENGINE = 0 as *mut ENGINE; + e = unsafe { ENGINE_get_first() }; + while !e.is_null() { + unsafe { + beg = curl_slist_append(list, ENGINE_get_id(e)); + if beg.is_null() { + curl_slist_free_all(list); + return 0 as *mut curl_slist; + } + } + list = beg; + e = unsafe { ENGINE_get_next(e) }; + } + } + return list; +} +extern "C" fn ossl_closeone( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut connssl: *mut ssl_connect_data, +) { + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + if !((*backend).handle).is_null() { + let mut buf: [libc::c_char; 32] = [0; 32]; + (*(*conn).ssl[0 as usize].backend).logger = data; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + SSL_read( + (*backend).handle, + buf.as_mut_ptr() as *mut libc::c_void, + ::std::mem::size_of::<[libc::c_char; 32]>() as i32, + ); + SSL_shutdown((*backend).handle); + SSL_set_connect_state((*backend).handle); + SSL_free((*backend).handle); + (*backend).handle = 0 as *mut SSL; + } + if !((*backend).ctx).is_null() { + SSL_CTX_free((*backend).ctx); + (*backend).ctx = 0 as *mut SSL_CTX; + } + } +} + +/* + * This function is called when an SSL connection is closed. + */ +extern "C" fn ossl_close(mut data: *mut Curl_easy, mut conn: *mut connectdata, mut sockindex: i32) { + unsafe { + ossl_closeone( + data, + conn, + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize), + ); + #[cfg(not(CURL_DISABLE_PROXY))] + ossl_closeone( + data, + conn, + &mut *((*conn).proxy_ssl).as_mut_ptr().offset(sockindex as isize), + ); + } +} + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +extern "C" fn ossl_shutdown( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> i32 { + let mut retval: i32 = 0 as i32; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut buf: [libc::c_char; 256] = [0; 256]; /* We will use this for the OpenSSL error buffer, so it has + to be at least 256 bytes long. */ + let mut sslerror: u64 = 0; + let mut nread: ssize_t = 0; + let mut buffsize: i32 = 0; + let mut err: i32 = 0; + let mut done: bool = 0 as i32 != 0; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut loop_0: i32 = 10 as i32; + /* This has only been tested on the proftpd server, and the mod_tls code + sends a close notify alert without waiting for a close notify alert in + response. Thus we wait for a close notify alert from the server, but + we do not send one. Let's hope other servers do the same... */ + #[cfg(not(CURL_DISABLE_FTP))] + unsafe { + if (*data).set.ftp_ccc as u32 == CURLFTPSSL_CCC_ACTIVE as u32 { + SSL_shutdown((*backend).handle); + } + } + if unsafe { !((*backend).handle).is_null() } { + buffsize = ::std::mem::size_of::<[libc::c_char; 256]>() as i32; + while !done && { + let fresh5 = loop_0; + loop_0 = loop_0 - 1; + fresh5 != 0 + } { + let mut what: i32 = unsafe { + Curl_socket_check( + (*conn).sock[sockindex as usize], + -(1 as i32), + -(1 as i32), + 10000 as timediff_t, + ) + }; + if what > 0 as i32 { + /* Something to read, let's do it and hope that it is the close + notify alert from the server */ + unsafe { + ERR_clear_error(); + nread = SSL_read( + (*backend).handle, + buf.as_mut_ptr() as *mut libc::c_void, + buffsize, + ) as ssize_t; + err = SSL_get_error((*backend).handle, nread as i32); + } + match err { + 0 | 6 => { + /* This is the expected response. There was no data but only + the close notify alert */ + done = 1 as i32 != 0; + } + 2 => unsafe { + Curl_infof( + data, + b"SSL_ERROR_WANT_READ\0" as *const u8 as *const libc::c_char, + ); + }, + 3 => { + /* SSL wants a write. Really odd. Let's bail out. */ + unsafe { + Curl_infof( + data, + b"SSL_ERROR_WANT_WRITE\0" as *const u8 as *const libc::c_char, + ); + } + done = 1 as i32 != 0; + } + _ => { + /* openssl/ssl.h says "look at error stack/return value/errno" */ + unsafe { + sslerror = ERR_get_error(); + Curl_failf( + data, + b"OpenSSL SSL_read on shutdown: %s, errno %d\0" as *const u8 + as *const libc::c_char, + if sslerror != 0 { + ossl_strerror( + sslerror, + buf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ) as *const libc::c_char + } else { + SSL_ERROR_to_str(err) + }, + *__errno_location(), + ); + } + done = 1 as i32 != 0; + } + } + } else if 0 as i32 == what { + /* timeout */ + unsafe { + Curl_failf( + data, + b"SSL shutdown timeout\0" as *const u8 as *const libc::c_char, + ); + } + done = 1 as i32 != 0; + } else { + /* anything that gets here is fatally bad */ + unsafe { + Curl_failf( + data, + b"select/poll on SSL socket, errno: %d\0" as *const u8 + as *const libc::c_char, + *__errno_location(), + ); + } + retval = -(1 as i32); + done = 1 as i32 != 0; + } + } /* while()-loop for the select() */ + if unsafe { ((*data).set).verbose() != 0 } { + if cfg!(HAVE_SSL_GET_SHUTDOWN) { + unsafe { + match SSL_get_shutdown((*backend).handle) { + 1 => { + Curl_infof( + data, + b"SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\0" as *const u8 + as *const libc::c_char, + ); + } + 2 => { + Curl_infof( + data, + b"SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\0" as *const u8 + as *const libc::c_char, + ); + } + 3 => { + Curl_infof( data, b"SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|SSL_RECEIVED__SHUTDOWN\0" as *const u8 as *const libc::c_char, ); - } - _ => {} - } - } - } - } - unsafe { - SSL_free((*backend).handle); - (*backend).handle = 0 as *mut SSL; - } - } - return retval; - } - - extern "C" fn ossl_session_free(mut ptr: *mut libc::c_void) { - unsafe { - SSL_SESSION_free(ptr as *mut SSL_SESSION); /* free the ID */ - } - } - - /* - * This function is called when the 'data' struct is going away. Close - * down everything and free all resources! - */ - extern "C" fn ossl_close_all(mut data: *mut Curl_easy) { - unsafe { - #[cfg(USE_OPENSSL_ENGINE)] - if !((*data).state.engine).is_null() { - ENGINE_finish((*data).state.engine as *mut ENGINE); - ENGINE_free((*data).state.engine as *mut ENGINE); - (*data).state.engine = 0 as *mut libc::c_void; - } - // TODO - 1560 - // #[cfg(all(not(HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED), HAVE_ERR_REMOVE_THREAD_STATE))] - } - } - - /* - * Match subjectAltName against the host name. This requires a conversion - * in CURL_DOES_CONVERSIONS builds. - */ - // TODO - 1579 开启 CURL_DOES_CONVERSIONS 选项 - // #[cfg(CURL_DOES_CONVERSIONS)] - #[cfg(not(CURL_DOES_CONVERSIONS))] - extern "C" fn subj_alt_hostcheck( - mut data: *mut Curl_easy, - mut match_pattern: *const libc::c_char, - mut hostname: *const libc::c_char, - mut dispname: *const libc::c_char, - ) -> bool { - unsafe { - if Curl_cert_hostcheck(match_pattern, hostname) != 0 { - Curl_infof( - data, - b" subjectAltName: host \"%s\" matched cert's \"%s\"\0" as *const u8 - as *const libc::c_char, - dispname, - match_pattern, - ); - return 1 as i32 != 0; - } - return 0 as i32 != 0; - } - } - - /* Quote from RFC2818 section 3.1 "Server Identity" - - If a subjectAltName extension of type dNSName is present, that MUST - be used as the identity. Otherwise, the (most specific) Common Name - field in the Subject field of the certificate MUST be used. Although - the use of the Common Name is existing practice, it is deprecated and - Certification Authorities are encouraged to use the dNSName instead. - - Matching is performed using the matching rules specified by - [RFC2459]. If more than one identity of a given type is present in - the certificate (e.g., more than one dNSName name, a match in any one - of the set is considered acceptable.) Names may contain the wildcard - character * which is considered to match any single domain name - component or component fragment. E.g., *.a.com matches foo.a.com but - not bar.foo.a.com. f*.com matches foo.com but not bar.com. - - In some cases, the URI is specified as an IP address rather than a - hostname. In this case, the iPAddress subjectAltName must be present - in the certificate and must exactly match the IP in the URI. - + } + _ => {} + } + } + } + } + unsafe { + SSL_free((*backend).handle); + (*backend).handle = 0 as *mut SSL; + } + } + return retval; +} + +extern "C" fn ossl_session_free(mut ptr: *mut libc::c_void) { + unsafe { + SSL_SESSION_free(ptr as *mut SSL_SESSION); /* free the ID */ + } +} + +/* + * This function is called when the 'data' struct is going away. Close + * down everything and free all resources! */ - extern "C" fn verifyhost( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut server_cert: *mut X509, - ) -> CURLcode { - let mut matched: bool = 0 as i32 != 0; - let mut target: i32 = 2 as i32; /* target type, GEN_DNS or GEN_IPADD */ - let mut addrlen: size_t = 0 as size_t; - let mut altnames: *mut stack_st_GENERAL_NAME = 0 as *mut stack_st_GENERAL_NAME; - #[cfg(ENABLE_IPV6)] - let mut addr: in6_addr = in6_addr { - __in6_u: C2RustUnnamed_8 { - __u6_addr8: [0; 16], - }, - }; - #[cfg(not(ENABLE_IPV6))] - let mut addr: in_addr = in_addr { s_addr: 0 }; - // TODO - 1650 - // #[cfg(not(ENABLE_IPV6))] - let mut result: CURLcode = CURLE_OK; - let mut dNSName: bool = 0 as i32 != 0; /* if a dNSName field exists in the cert */ - let mut iPAddress: bool = 0 as i32 != 0; /* if a iPAddress field exists in the cert */ - #[cfg(not(CURL_DISABLE_PROXY))] - let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).http_proxy.host.name } - } else { - unsafe { (*conn).host.name } - }; - #[cfg(CURL_DISABLE_PROXY)] - let hostname: *const libc::c_char = unsafe { (*conn).host.name }; - #[cfg(not(CURL_DISABLE_PROXY))] - let dispname: *const libc::c_char = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).http_proxy.host.dispname } - } else { - unsafe { (*conn).host.dispname } - }; - #[cfg(CURL_DISABLE_PROXY)] - let dispname: *const libc::c_char = unsafe { (*conn).host.dispname }; - // DONE - 1661 - #[cfg(ENABLE_IPV6)] - if unsafe { - ((*conn).bits).ipv6_ip() as i32 != 0 - && inet_pton( - 10 as i32, - hostname, - &mut addr as *mut in6_addr as *mut libc::c_void, - ) != 0 - } { - target = 7 as i32; - addrlen = ::std::mem::size_of::() as u64; - } else if unsafe { - inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in6_addr as *mut libc::c_void, - ) - } != 0 - { - target = 7 as i32; - addrlen = ::std::mem::size_of::() as u64; - } - #[cfg(not(ENABLE_IPV6))] - if unsafe { - inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in_addr as *mut libc::c_void, - ) - } != 0 - { - target = 7 as i32; - addrlen = ::std::mem::size_of::() as u64; - } - /* get a "list" of alternative names */ - altnames = unsafe { X509_get_ext_d2i(server_cert, 85 as i32, 0 as *mut i32, 0 as *mut i32) } - as *mut stack_st_GENERAL_NAME; - if !altnames.is_null() { - unsafe { - // TODO 待确认 - #[cfg(OPENSSL_IS_BORINGSSL)] - let mut numalts: ibc::c_int = 0; - #[cfg(OPENSSL_IS_BORINGSSL)] - let mut i: ibc::c_int = 0; - #[cfg(not(OPENSSL_IS_BORINGSSL))] - let mut numalts: i32 = 0; - #[cfg(not(OPENSSL_IS_BORINGSSL))] - let mut i: i32 = 0; - let mut dnsmatched: bool = 0 as i32 != 0; - let mut ipmatched: bool = 0 as i32 != 0; - /* get amount of alternatives, RFC2459 claims there MUST be at least - one, but we don't depend on it... */ - numalts = sk_GENERAL_NAME_num(altnames); - /* loop through all alternatives - until a dnsmatch */ - i = 0 as i32; - while i < numalts && !dnsmatched { - /* get a handle to alternative name number i */ - let mut check: *const GENERAL_NAME = sk_GENERAL_NAME_value(altnames, i); - if (*check).type_0 == 2 as i32 { - dNSName = 1 as i32 != 0; - } else if (*check).type_0 == 7 as i32 { - iPAddress = 1 as i32 != 0; - } - /* only check alternatives of the same type the target is */ - if (*check).type_0 == target { - /* get data and length */ - let mut altptr: *const libc::c_char = - ASN1_STRING_get0_data((*check).d.ia5) as *mut libc::c_char; - let mut altlen: size_t = ASN1_STRING_length((*check).d.ia5) as size_t; - match target { - 2 => { - /* name/pattern comparison */ - /* The OpenSSL man page explicitly says: "In general it cannot be - assumed that the data returned by ASN1_STRING_data() is null - terminated or does not contain embedded nulls." But also that - "The actual format of the data will depend on the actual string - type itself: for example for an IA5String the data will be ASCII" - - It has been however verified that in 0.9.6 and 0.9.7, IA5String - is always null-terminated. - */ - if altlen == strlen(altptr) - && subj_alt_hostcheck(data, altptr, hostname, dispname) as i32 != 0 - { - /* if this isn't true, there was an embedded zero in the name - string and we cannot match it. */ - dnsmatched = 1 as i32 != 0; - } - } - 7 => { - /* IP address comparison */ - #[cfg(ENABLE_IPV6)] - let ENABLE_IPV6_a = memcmp( - altptr as *const libc::c_void, - &mut addr as *mut in6_addr as *const libc::c_void, - altlen, - ) == 0; - #[cfg(not(ENABLE_IPV6))] - let ENABLE_IPV6_a = memcmp( - altptr as *const libc::c_void, - &mut addr as *mut in_addr as *const libc::c_void, - altlen, - ) == 0; - /* compare alternative IP address if the data chunk is the same size - our server IP address is */ - if altlen == addrlen && ENABLE_IPV6_a { - ipmatched = 1 as i32 != 0; - Curl_infof( - data, - b" subjectAltName: host \"%s\" matched cert's IP address!\0" - as *const u8 - as *const libc::c_char, - dispname, - ); - } - } - _ => {} - } - } - i += 1; - } - GENERAL_NAMES_free(altnames); - if dnsmatched as i32 != 0 || ipmatched as i32 != 0 { - matched = 1 as i32 != 0; - } - } - } - /* an alternative name matched */ - if !matched { - if dNSName as i32 != 0 || iPAddress as i32 != 0 { - unsafe { - Curl_infof( - data, - b" subjectAltName does not match %s\0" as *const u8 as *const libc::c_char, - dispname, - ); - Curl_failf( - data, - b"SSL: no alternative certificate subject name matches target host name '%s'\0" - as *const u8 as *const libc::c_char, - dispname, - ); - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else { - /* we have to look to the last occurrence of a commonName in the - distinguished one to get the most significant one. */ - let mut j: i32 = 0; - let mut i_0: i32 = -(1 as i32); - /* The following is done because of a bug in 0.9.6b */ - let mut nulstr: *mut u8 = b"\0" as *const u8 as *const libc::c_char as *mut u8; - let mut peer_CN: *mut u8 = nulstr; - let mut name: *mut X509_NAME = unsafe { X509_get_subject_name(server_cert) }; - if !name.is_null() { - loop { - j = unsafe { X509_NAME_get_index_by_NID(name, 13 as i32, i_0) }; - if !(j >= 0 as i32) { - break; - } - i_0 = j; - } - } - /* we have the name entry and we will now convert this to a string - that we can use for comparison. Doing this we support BMPstring, - UTF8, etc. */ - - if i_0 >= 0 as i32 { - let mut tmp: *mut ASN1_STRING = - unsafe { X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i_0)) }; - if !tmp.is_null() { - unsafe { - /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input - is already UTF-8 encoded. We check for this case and copy the raw - string manually to avoid the problem. This code can be made - conditional in the future when OpenSSL has been fixed. */ - if ASN1_STRING_type(tmp) == 12 as i32 { - j = ASN1_STRING_length(tmp); - if j >= 0 as i32 { - peer_CN = CRYPTO_malloc( - (j + 1 as i32) as size_t, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 1786 as i32, - ) as *mut u8; - if !peer_CN.is_null() { - memcpy( - peer_CN as *mut libc::c_void, - ASN1_STRING_get0_data(tmp) as *const libc::c_void, - j as u64, - ); - *peer_CN.offset(j as isize) = '\0' as i32 as u8; - } - } - } else { - /* not a UTF8 name */ - j = ASN1_STRING_to_UTF8(&mut peer_CN, tmp); - } - if !peer_CN.is_null() - && curlx_uztosi(strlen(peer_CN as *mut libc::c_char)) != j - { - /* there was a terminating zero before the end of string, this - cannot match and we return failure! */ - Curl_failf( - data, - b"SSL: illegal cert name field\0" as *const u8 - as *const libc::c_char, - ); - result = CURLE_PEER_FAILED_VERIFICATION; - } - } - } - } - if peer_CN == nulstr { - peer_CN = 0 as *mut u8; - } else { - /* convert peer_CN from UTF8 */ - let mut rc: CURLcode = CURLE_OK as CURLcode; - /* Curl_convert_from_utf8 calls failf if unsuccessful */ - if rc as u64 != 0 { - unsafe { - CRYPTO_free( - peer_CN as *mut libc::c_void, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 1813 as i32, - ); - } - return rc; - } - } - if !(result as u64 != 0) { - /* error already detected, pass through */ - if peer_CN.is_null() { - unsafe { - Curl_failf( - data, - b"SSL: unable to obtain common name from peer certificate\0" - as *const u8 as *const libc::c_char, - ); - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else if unsafe { Curl_cert_hostcheck(peer_CN as *const libc::c_char, hostname) } - == 0 - { - unsafe { - Curl_failf( +extern "C" fn ossl_close_all(mut data: *mut Curl_easy) { + unsafe { + #[cfg(USE_OPENSSL_ENGINE)] + if !((*data).state.engine).is_null() { + ENGINE_finish((*data).state.engine as *mut ENGINE); + ENGINE_free((*data).state.engine as *mut ENGINE); + (*data).state.engine = 0 as *mut libc::c_void; + } + // TODO - 1560 + // #[cfg(all(not(HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED), HAVE_ERR_REMOVE_THREAD_STATE))] + } +} + +/* + * Match subjectAltName against the host name. This requires a conversion + * in CURL_DOES_CONVERSIONS builds. + */ +// TODO - 1579 开启 CURL_DOES_CONVERSIONS 选项 +// #[cfg(CURL_DOES_CONVERSIONS)] +#[cfg(not(CURL_DOES_CONVERSIONS))] +extern "C" fn subj_alt_hostcheck( + mut data: *mut Curl_easy, + mut match_pattern: *const libc::c_char, + mut hostname: *const libc::c_char, + mut dispname: *const libc::c_char, +) -> bool { + unsafe { + if Curl_cert_hostcheck(match_pattern, hostname) != 0 { + Curl_infof( + data, + b" subjectAltName: host \"%s\" matched cert's \"%s\"\0" as *const u8 + as *const libc::c_char, + dispname, + match_pattern, + ); + return 1 as i32 != 0; + } + return 0 as i32 != 0; + } +} + +/* Quote from RFC2818 section 3.1 "Server Identity" + + If a subjectAltName extension of type dNSName is present, that MUST + be used as the identity. Otherwise, the (most specific) Common Name + field in the Subject field of the certificate MUST be used. Although + the use of the Common Name is existing practice, it is deprecated and + Certification Authorities are encouraged to use the dNSName instead. + + Matching is performed using the matching rules specified by + [RFC2459]. If more than one identity of a given type is present in + the certificate (e.g., more than one dNSName name, a match in any one + of the set is considered acceptable.) Names may contain the wildcard + character * which is considered to match any single domain name + component or component fragment. E.g., *.a.com matches foo.a.com but + not bar.foo.a.com. f*.com matches foo.com but not bar.com. + + In some cases, the URI is specified as an IP address rather than a + hostname. In this case, the iPAddress subjectAltName must be present + in the certificate and must exactly match the IP in the URI. + +*/ +extern "C" fn verifyhost( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut server_cert: *mut X509, +) -> CURLcode { + let mut matched: bool = 0 as i32 != 0; + let mut target: i32 = 2 as i32; /* target type, GEN_DNS or GEN_IPADD */ + let mut addrlen: size_t = 0 as size_t; + let mut altnames: *mut stack_st_GENERAL_NAME = 0 as *mut stack_st_GENERAL_NAME; + #[cfg(ENABLE_IPV6)] + let mut addr: in6_addr = in6_addr { + __in6_u: C2RustUnnamed_8 { + __u6_addr8: [0; 16], + }, + }; + #[cfg(not(ENABLE_IPV6))] + let mut addr: in_addr = in_addr { s_addr: 0 }; + // TODO - 1650 + // #[cfg(not(ENABLE_IPV6))] + let mut result: CURLcode = CURLE_OK; + let mut dNSName: bool = 0 as i32 != 0; /* if a dNSName field exists in the cert */ + let mut iPAddress: bool = 0 as i32 != 0; /* if a iPAddress field exists in the cert */ + #[cfg(not(CURL_DISABLE_PROXY))] + let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).http_proxy.host.name } + } else { + unsafe { (*conn).host.name } + }; + #[cfg(CURL_DISABLE_PROXY)] + let hostname: *const libc::c_char = unsafe { (*conn).host.name }; + #[cfg(not(CURL_DISABLE_PROXY))] + let dispname: *const libc::c_char = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).http_proxy.host.dispname } + } else { + unsafe { (*conn).host.dispname } + }; + #[cfg(CURL_DISABLE_PROXY)] + let dispname: *const libc::c_char = unsafe { (*conn).host.dispname }; + // DONE - 1661 + #[cfg(ENABLE_IPV6)] + if unsafe { + ((*conn).bits).ipv6_ip() as i32 != 0 + && inet_pton( + 10 as i32, + hostname, + &mut addr as *mut in6_addr as *mut libc::c_void, + ) != 0 + } { + target = 7 as i32; + addrlen = ::std::mem::size_of::() as u64; + } else if unsafe { + inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in6_addr as *mut libc::c_void, + ) + } != 0 + { + target = 7 as i32; + addrlen = ::std::mem::size_of::() as u64; + } + #[cfg(not(ENABLE_IPV6))] + if unsafe { + inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in_addr as *mut libc::c_void, + ) + } != 0 + { + target = 7 as i32; + addrlen = ::std::mem::size_of::() as u64; + } + /* get a "list" of alternative names */ + altnames = unsafe { X509_get_ext_d2i(server_cert, 85 as i32, 0 as *mut i32, 0 as *mut i32) } + as *mut stack_st_GENERAL_NAME; + if !altnames.is_null() { + unsafe { + // TODO 待确认 + #[cfg(OPENSSL_IS_BORINGSSL)] + let mut numalts: ibc::c_int = 0; + #[cfg(OPENSSL_IS_BORINGSSL)] + let mut i: ibc::c_int = 0; + #[cfg(not(OPENSSL_IS_BORINGSSL))] + let mut numalts: i32 = 0; + #[cfg(not(OPENSSL_IS_BORINGSSL))] + let mut i: i32 = 0; + let mut dnsmatched: bool = 0 as i32 != 0; + let mut ipmatched: bool = 0 as i32 != 0; + /* get amount of alternatives, RFC2459 claims there MUST be at least + one, but we don't depend on it... */ + numalts = sk_GENERAL_NAME_num(altnames); + /* loop through all alternatives - until a dnsmatch */ + i = 0 as i32; + while i < numalts && !dnsmatched { + /* get a handle to alternative name number i */ + let mut check: *const GENERAL_NAME = sk_GENERAL_NAME_value(altnames, i); + if (*check).type_0 == 2 as i32 { + dNSName = 1 as i32 != 0; + } else if (*check).type_0 == 7 as i32 { + iPAddress = 1 as i32 != 0; + } + /* only check alternatives of the same type the target is */ + if (*check).type_0 == target { + /* get data and length */ + let mut altptr: *const libc::c_char = + ASN1_STRING_get0_data((*check).d.ia5) as *mut libc::c_char; + let mut altlen: size_t = ASN1_STRING_length((*check).d.ia5) as size_t; + match target { + 2 => { + /* name/pattern comparison */ + /* The OpenSSL man page explicitly says: "In general it cannot be + assumed that the data returned by ASN1_STRING_data() is null + terminated or does not contain embedded nulls." But also that + "The actual format of the data will depend on the actual string + type itself: for example for an IA5String the data will be ASCII" + + It has been however verified that in 0.9.6 and 0.9.7, IA5String + is always null-terminated. + */ + if altlen == strlen(altptr) + && subj_alt_hostcheck(data, altptr, hostname, dispname) as i32 != 0 + { + /* if this isn't true, there was an embedded zero in the name + string and we cannot match it. */ + dnsmatched = 1 as i32 != 0; + } + } + 7 => { + /* IP address comparison */ + #[cfg(ENABLE_IPV6)] + let ENABLE_IPV6_a = memcmp( + altptr as *const libc::c_void, + &mut addr as *mut in6_addr as *const libc::c_void, + altlen, + ) == 0; + #[cfg(not(ENABLE_IPV6))] + let ENABLE_IPV6_a = memcmp( + altptr as *const libc::c_void, + &mut addr as *mut in_addr as *const libc::c_void, + altlen, + ) == 0; + /* compare alternative IP address if the data chunk is the same size + our server IP address is */ + if altlen == addrlen && ENABLE_IPV6_a { + ipmatched = 1 as i32 != 0; + Curl_infof( + data, + b" subjectAltName: host \"%s\" matched cert's IP address!\0" + as *const u8 + as *const libc::c_char, + dispname, + ); + } + } + _ => {} + } + } + i += 1; + } + GENERAL_NAMES_free(altnames); + if dnsmatched as i32 != 0 || ipmatched as i32 != 0 { + matched = 1 as i32 != 0; + } + } + } + /* an alternative name matched */ + if !matched { + if dNSName as i32 != 0 || iPAddress as i32 != 0 { + unsafe { + Curl_infof( + data, + b" subjectAltName does not match %s\0" as *const u8 as *const libc::c_char, + dispname, + ); + Curl_failf( + data, + b"SSL: no alternative certificate subject name matches target host name '%s'\0" + as *const u8 as *const libc::c_char, + dispname, + ); + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else { + /* we have to look to the last occurrence of a commonName in the + distinguished one to get the most significant one. */ + let mut j: i32 = 0; + let mut i_0: i32 = -(1 as i32); + /* The following is done because of a bug in 0.9.6b */ + let mut nulstr: *mut u8 = b"\0" as *const u8 as *const libc::c_char as *mut u8; + let mut peer_CN: *mut u8 = nulstr; + let mut name: *mut X509_NAME = unsafe { X509_get_subject_name(server_cert) }; + if !name.is_null() { + loop { + j = unsafe { X509_NAME_get_index_by_NID(name, 13 as i32, i_0) }; + if !(j >= 0 as i32) { + break; + } + i_0 = j; + } + } + /* we have the name entry and we will now convert this to a string + that we can use for comparison. Doing this we support BMPstring, + UTF8, etc. */ + + if i_0 >= 0 as i32 { + let mut tmp: *mut ASN1_STRING = + unsafe { X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i_0)) }; + if !tmp.is_null() { + unsafe { + /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input + is already UTF-8 encoded. We check for this case and copy the raw + string manually to avoid the problem. This code can be made + conditional in the future when OpenSSL has been fixed. */ + if ASN1_STRING_type(tmp) == 12 as i32 { + j = ASN1_STRING_length(tmp); + if j >= 0 as i32 { + peer_CN = CRYPTO_malloc( + (j + 1 as i32) as size_t, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 1786 as i32, + ) as *mut u8; + if !peer_CN.is_null() { + memcpy( + peer_CN as *mut libc::c_void, + ASN1_STRING_get0_data(tmp) as *const libc::c_void, + j as u64, + ); + *peer_CN.offset(j as isize) = '\0' as i32 as u8; + } + } + } else { + /* not a UTF8 name */ + j = ASN1_STRING_to_UTF8(&mut peer_CN, tmp); + } + if !peer_CN.is_null() + && curlx_uztosi(strlen(peer_CN as *mut libc::c_char)) != j + { + /* there was a terminating zero before the end of string, this + cannot match and we return failure! */ + Curl_failf( + data, + b"SSL: illegal cert name field\0" as *const u8 + as *const libc::c_char, + ); + result = CURLE_PEER_FAILED_VERIFICATION; + } + } + } + } + if peer_CN == nulstr { + peer_CN = 0 as *mut u8; + } else { + /* convert peer_CN from UTF8 */ + let mut rc: CURLcode = CURLE_OK as CURLcode; + /* Curl_convert_from_utf8 calls failf if unsuccessful */ + if rc as u64 != 0 { + unsafe { + CRYPTO_free( + peer_CN as *mut libc::c_void, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 1813 as i32, + ); + } + return rc; + } + } + if !(result as u64 != 0) { + /* error already detected, pass through */ + if peer_CN.is_null() { + unsafe { + Curl_failf( + data, + b"SSL: unable to obtain common name from peer certificate\0" + as *const u8 as *const libc::c_char, + ); + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else if unsafe { Curl_cert_hostcheck(peer_CN as *const libc::c_char, hostname) } + == 0 + { + unsafe { + Curl_failf( data, b"SSL: certificate subject name '%s' does not match target host name '%s'\0" as *const u8 as *const libc::c_char, peer_CN, dispname, ); - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else { - unsafe { - Curl_infof( - data, - b" common name: %s (matched)\0" as *const u8 as *const libc::c_char, - peer_CN, - ); - } - } - } - if !peer_CN.is_null() { - unsafe { - CRYPTO_free( - peer_CN as *mut libc::c_void, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 1835 as i32, - ); - } - } - } - } - return result; - } - - #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP)))] - extern "C" fn verifystatus( - mut data: *mut Curl_easy, - mut connssl: *mut ssl_connect_data, - ) -> CURLcode { - let mut current_block: u64; - let mut i: i32 = 0; - let mut ocsp_status: i32 = 0; - let mut status: *mut u8 = 0 as *mut u8; - let mut p: *const u8 = 0 as *const u8; - let mut result: CURLcode = CURLE_OK; - let mut rsp: *mut OCSP_RESPONSE = 0 as *mut OCSP_RESPONSE; - let mut br: *mut OCSP_BASICRESP = 0 as *mut OCSP_BASICRESP; - let mut st: *mut X509_STORE = 0 as *mut X509_STORE; - let mut ch: *mut stack_st_X509 = 0 as *mut stack_st_X509; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - let mut cert: *mut X509 = 0 as *mut X509; - let mut id: *mut OCSP_CERTID = 0 as *mut OCSP_CERTID; - let mut cert_status: i32 = 0; - let mut crl_reason: i32 = 0; - let mut rev: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; - let mut thisupd: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; - let mut nextupd: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; - let mut ret: i32 = 0; - let mut len: i64 = unsafe { - SSL_ctrl( - (*backend).handle, - 70 as i32, - 0 as i64, - &mut status as *mut *mut u8 as *mut libc::c_void, - ) - }; - 'end: loop { - if status.is_null() { - unsafe { - Curl_failf( - data, - b"No OCSP response received\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - p = status; - rsp = unsafe { d2i_OCSP_RESPONSE(0 as *mut *mut OCSP_RESPONSE, &mut p, len) }; - if rsp.is_null() { - unsafe { - Curl_failf( - data, - b"Invalid OCSP response\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - ocsp_status = unsafe { OCSP_response_status(rsp) }; - if ocsp_status != 0 as i32 { - unsafe { - Curl_failf( - data, - b"Invalid OCSP response status: %s (%d)\0" as *const u8 as *const libc::c_char, - OCSP_response_status_str(ocsp_status as i64), - ocsp_status, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - br = unsafe { OCSP_response_get1_basic(rsp) }; - if br.is_null() { - unsafe { - Curl_failf( - data, - b"Invalid OCSP response\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - unsafe { - ch = SSL_get_peer_cert_chain((*backend).handle); - st = SSL_CTX_get_cert_store((*backend).ctx); - } - /* The authorized responder cert in the OCSP response MUST be signed by the - peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert, - no problem, but if it's an intermediate cert OpenSSL has a bug where it - expects this issuer to be present in the chain embedded in the OCSP - response. So we add it if necessary. */ - - /* First make sure the peer cert chain includes both a peer and an issuer, - and the OCSP response contains a responder cert. */ - // TODO - 1894 这里有一段跟OPENSSL_VERSION_NUMBER相关的条件编译 - if cfg!(any( - OPENSSL_VERSION_NUMBER_LT_0X1000201FL, - all( - LIBRESSL_VERSION_NUMBER, - LIBRESSL_VERSION_NUMBER_LT_0X2040200FL - ) - )) { - // TODO - } - if unsafe { OCSP_basic_verify(br, ch, st, 0 as u64) <= 0 as i32 } { - unsafe { - Curl_failf( - data, - b"OCSP response verification failed\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - cert = unsafe { SSL_get_peer_certificate((*backend).handle) }; - if cert.is_null() { - unsafe { - Curl_failf( - data, - b"Error getting peer certificate\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - /* Find issuer of responder cert and add it to the OCSP response chain */ - i = 0 as i32; - while i < sk_X509_num(ch) { - let mut issuer: *mut X509 = sk_X509_value(ch, i); - if unsafe { X509_check_issued(issuer, cert) } == 0 as i32 { - id = unsafe { OCSP_cert_to_id(EVP_sha1(), cert, issuer) }; - break; - } else { - i += 1; - } - } - unsafe { - X509_free(cert); - } - if id.is_null() { - unsafe { - Curl_failf( - data, - b"Error computing OCSP ID\0" as *const u8 as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - /* Find the single OCSP response corresponding to the certificate ID */ - unsafe { - ret = OCSP_resp_find_status( - br, - id, - &mut cert_status, - &mut crl_reason, - &mut rev, - &mut thisupd, - &mut nextupd, - ); - OCSP_CERTID_free(id); - } - if ret != 1 as i32 { - unsafe { - Curl_failf( - data, - b"Could not find certificate ID in OCSP response\0" as *const u8 - as *const libc::c_char, - ); - } - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - /* Validate the corresponding single OCSP response */ - unsafe { - if OCSP_check_validity(thisupd, nextupd, 300 as i64, -(1 as i64)) == 0 { - Curl_failf( - data, - b"OCSP response has expired\0" as *const u8 as *const libc::c_char, - ); - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - Curl_infof( - data, - b"SSL certificate status: %s (%d)\0" as *const u8 as *const libc::c_char, - OCSP_cert_status_str(cert_status as i64), - cert_status, - ); - } - let mut current_block_63: u64; - match cert_status { - 0 => { - current_block_63 = 13484060386966298149; - } - 1 => { - result = CURLE_SSL_INVALIDCERTSTATUS; - unsafe { - Curl_failf( - data, - b"SSL certificate revocation reason: %s (%d)\0" as *const u8 - as *const libc::c_char, - OCSP_crl_reason_str(crl_reason as i64), - crl_reason, - ); - } - current_block_63 = 11531555616992456840; - break 'end; - } - 2 | _ => { - current_block_63 = 11531555616992456840; - } - } - match current_block_63 { - 11531555616992456840 => { - result = CURLE_SSL_INVALIDCERTSTATUS; - break 'end; - } - _ => {} - } - break 'end; - } - if !br.is_null() { - unsafe { - OCSP_BASICRESP_free(br); - } - } - unsafe { - OCSP_RESPONSE_free(rsp); - } - return result; - } - - #[cfg(SSL_CTRL_SET_MSG_CALLBACK)] - extern "C" fn ssl_msg_type(mut ssl_ver: i32, mut msg: i32) -> *const libc::c_char { - if ssl_ver == 0x3 as i32 { - match msg { - 0 => return b"Hello request\0" as *const u8 as *const libc::c_char, - 1 => return b"Client hello\0" as *const u8 as *const libc::c_char, - 2 => return b"Server hello\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_NEWSESSION_TICKET)] - 4 => return b"Newsession Ticket\0" as *const u8 as *const libc::c_char, - 11 => return b"Certificate\0" as *const u8 as *const libc::c_char, - 12 => return b"Server key exchange\0" as *const u8 as *const libc::c_char, - 16 => return b"Client key exchange\0" as *const u8 as *const libc::c_char, - 13 => return b"Request CERT\0" as *const u8 as *const libc::c_char, - 14 => return b"Server finished\0" as *const u8 as *const libc::c_char, - 15 => return b"CERT verify\0" as *const u8 as *const libc::c_char, - 20 => return b"Finished\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_CERTIFICATE_STATUS)] - 22 => return b"Certificate Status\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_ENCRYPTED_EXTENSIONS)] - 8 => return b"Encrypted Extensions\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_SUPPLEMENTAL_DATA)] - 23 => return b"Supplemental data\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_END_OF_EARLY_DATA)] - 5 => return b"End of early data\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_KEY_UPDATE)] - 24 => return b"Key update\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_NEXT_PROTO)] - 67 => return b"Next protocol\0" as *const u8 as *const libc::c_char, - #[cfg(SSL3_MT_MESSAGE_HASH)] - 254 => return b"Message hash\0" as *const u8 as *const libc::c_char, - _ => {} - } - } - return b"Unknown\0" as *const u8 as *const libc::c_char; - } - - #[cfg(SSL_CTRL_SET_MSG_CALLBACK)] - extern "C" fn tls_rt_type(mut type_0: i32) -> *const libc::c_char { - match type_0 { - #[cfg(SSL3_RT_HEADER)] - 256 => return b"TLS header\0" as *const u8 as *const libc::c_char, - 20 => return b"TLS change cipher\0" as *const u8 as *const libc::c_char, - 21 => return b"TLS alert\0" as *const u8 as *const libc::c_char, - 22 => return b"TLS handshake\0" as *const u8 as *const libc::c_char, - 23 => return b"TLS app data\0" as *const u8 as *const libc::c_char, - _ => return b"TLS Unknown\0" as *const u8 as *const libc::c_char, - }; - } - - /* - * Our callback from the SSL/TLS layers. - */ - #[cfg(SSL_CTRL_SET_MSG_CALLBACK)] - extern "C" fn ossl_trace( - mut direction: i32, - mut ssl_ver: i32, - mut content_type: i32, - mut buf: *const libc::c_void, - mut len: size_t, - mut ssl: *mut SSL, - mut userp: *mut libc::c_void, - ) { - let mut unknown: [libc::c_char; 32] = [0; 32]; - let mut verstr: *const libc::c_char = 0 as *const libc::c_char; - let mut conn: *mut connectdata = userp as *mut connectdata; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(0 as isize) as *mut ssl_connect_data }; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - let mut data: *mut Curl_easy = unsafe { (*backend).logger }; - if conn.is_null() - || data.is_null() - || unsafe { ((*data).set.fdebug).is_none() } - || direction != 0 as i32 && direction != 1 as i32 - { - return; - } - match ssl_ver { - #[cfg(SSL2_VERSION)] - 2 => { - verstr = b"SSLv2\0" as *const u8 as *const libc::c_char; - } - #[cfg(SSL3_VERSION)] - 768 => { - verstr = b"SSLv3\0" as *const u8 as *const libc::c_char; - } - 769 => { - verstr = b"TLSv1.0\0" as *const u8 as *const libc::c_char; - } - #[cfg(TLS1_1_VERSION)] - 770 => { - verstr = b"TLSv1.1\0" as *const u8 as *const libc::c_char; - } - #[cfg(TLS1_2_VERSION)] - 771 => { - verstr = b"TLSv1.2\0" as *const u8 as *const libc::c_char; - } - #[cfg(TLS1_3_VERSION)] - 772 => { - verstr = b"TLSv1.3\0" as *const u8 as *const libc::c_char; - } - 0 => {} - _ => { - unsafe { - curl_msnprintf( - unknown.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 32]>() as u64, - b"(%x)\0" as *const u8 as *const libc::c_char, - ssl_ver, - ); - } - verstr = unknown.as_mut_ptr(); - } - } - /* Log progress for interesting records only (like Handshake or Alert), skip - * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0). - * For TLS 1.3, skip notification of the decrypted inner Content-Type. - */ - // DONE - 2168 - #[cfg(SSL3_RT_INNER_CONTENT_TYPE)] - let SSL3_RT_INNER_CONTENT_TYPE_flag = content_type != 0x101; - #[cfg(not(SSL3_RT_INNER_CONTENT_TYPE))] - let SSL3_RT_INNER_CONTENT_TYPE_flag = true; - if ssl_ver != 0 && SSL3_RT_INNER_CONTENT_TYPE_flag { - let mut msg_name: *const libc::c_char = 0 as *const libc::c_char; - let mut tls_rt_name: *const libc::c_char = 0 as *const libc::c_char; - let mut ssl_buf: [libc::c_char; 1024] = [0; 1024]; - let mut msg_type: i32 = 0; - let mut txt_len: i32 = 0; - /* the info given when the version is zero is not that useful for us */ - - ssl_ver >>= 8 as i32; /* check the upper 8 bits only below */ - /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL - * always pass-up content-type as 0. But the interesting message-type - * is at 'buf[0]'. - */ - if ssl_ver == 0x3 as i32 && content_type != 0 { - tls_rt_name = tls_rt_type(content_type); - } else { - tls_rt_name = b"\0" as *const u8 as *const libc::c_char; - } - if content_type == 20 as i32 { - msg_type = unsafe { *(buf as *mut libc::c_char) } as i32; - msg_name = b"Change cipher spec\0" as *const u8 as *const libc::c_char; - } else if content_type == 21 as i32 { - msg_type = unsafe { - ((*(buf as *mut libc::c_char).offset(0 as isize) as i32) << 8 as i32) - + *(buf as *mut libc::c_char).offset(1 as isize) as i32 - }; - msg_name = unsafe { SSL_alert_desc_string_long(msg_type) }; - } else { - msg_type = unsafe { *(buf as *mut libc::c_char) } as i32; - msg_name = ssl_msg_type(ssl_ver, msg_type); - } - txt_len = unsafe { - curl_msnprintf( - ssl_buf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 1024]>() as u64, - b"%s (%s), %s, %s (%d):\n\0" as *const u8 as *const libc::c_char, - verstr, - if direction != 0 { - b"OUT\0" as *const u8 as *const libc::c_char - } else { - b"IN\0" as *const u8 as *const libc::c_char - }, - tls_rt_name, - msg_name, - msg_type, - ) - }; - if 0 as i32 <= txt_len - && (txt_len as u64) < ::std::mem::size_of::<[libc::c_char; 1024]>() as u64 - { - unsafe { - Curl_debug(data, CURLINFO_TEXT, ssl_buf.as_mut_ptr(), txt_len as size_t); - } - } - } - unsafe { - Curl_debug( - data, - (if direction == 1 as i32 { - CURLINFO_SSL_DATA_OUT as i32 - } else { - CURLINFO_SSL_DATA_IN as i32 - }) as curl_infotype, - buf as *mut libc::c_char, - len, - ); - } - } - - #[cfg(all(USE_OPENSSL, HAS_NPN))] - extern "C" fn select_next_protocol( - mut out: *mut *mut u8, - mut outlen: *mut u8, - mut in_0: *const u8, - mut inlen: u32, - mut key: *const libc::c_char, - mut keylen: u32, - ) -> i32 { - let mut i: u32 = 0; - i = 0 as u32; - while i.wrapping_add(keylen) <= inlen { - if unsafe { - memcmp( - &*in_0.offset(i.wrapping_add(1 as u32) as isize) as *const u8 - as *const libc::c_void, - key as *const libc::c_void, - keylen as u64, - ) - } == 0 as i32 - { - unsafe { - *out = &*in_0.offset(i.wrapping_add(1 as u32) as isize) as *const u8 as *mut u8; - *outlen = *in_0.offset(i as isize); - } - return 0 as i32; - } - i = unsafe { i.wrapping_add((*in_0.offset(i as isize) as i32 + 1 as i32) as u32) }; - } - return -(1 as i32); - } - - #[cfg(all(USE_OPENSSL, HAS_NPN))] - extern "C" fn select_next_proto_cb( - mut ssl: *mut SSL, - mut out: *mut *mut u8, - mut outlen: *mut u8, - mut in_0: *const u8, - mut inlen: u32, - mut arg: *mut libc::c_void, - ) -> i32 { - unsafe { - let mut data: *mut Curl_easy = arg as *mut Curl_easy; - let mut conn: *mut connectdata = (*data).conn; - #[cfg(USE_HTTP2)] - if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 - && select_next_protocol( - out, - outlen, - in_0, - inlen, - b"h2\0" as *const u8 as *const libc::c_char, - 2 as u32, - ) == 0 - { - Curl_infof( - data, - b"NPN, negotiated HTTP2 (%s)\0" as *const u8 as *const libc::c_char, - b"h2\0" as *const u8 as *const libc::c_char, - ); - (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; - return 0 as i32; - } - if select_next_protocol( - out, - outlen, - in_0, - inlen, - b"http/1.1\0" as *const u8 as *const libc::c_char, - 8 as u32, - ) == 0 - { - Curl_infof( - data, - b"NPN, negotiated HTTP1.1\0" as *const u8 as *const libc::c_char, - ); - (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; - return 0 as i32; - } - Curl_infof( - data, - b"NPN, no overlap, use HTTP1.1\0" as *const u8 as *const libc::c_char, - ); - *out = b"http/1.1\0" as *const u8 as *const libc::c_char as *mut u8; - *outlen = 8 as u8; - (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; - return 0 as i32; - } - } - // TODO - // USE_OPENSSL以及与OPENSSL_VERSION_NUMBER相关的条件编译 - #[cfg(USE_OPENSSL)] - extern "C" fn set_ssl_version_min_max( - mut ctx: *mut SSL_CTX, - mut conn: *mut connectdata, - ) -> CURLcode { - #[cfg(not(CURL_DISABLE_PROXY))] - let mut curl_ssl_version_min: i64 = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).proxy_ssl_config.version } - } else { - unsafe { (*conn).ssl_config.version } - }; - #[cfg(CURL_DISABLE_PROXY)] - let mut curl_ssl_version_min: i64 = unsafe { (*conn).ssl_config.version }; - - let mut curl_ssl_version_max: i64 = 0; - // TODO - 2307 - // #[cfg(any(OPENSSL_IS_BORINGSSL, LIBRESSL_VERSION_NUMBER))] - // TODO - 2307 - // #[cfg(any(OPENSSL_IS_BORINGSSL, LIBRESSL_VERSION_NUMBER))] - #[cfg(all(not(OPENSSL_IS_BORINGSSL), not(LIBRESSL_VERSION_NUMBER)))] - let mut ossl_ssl_version_min: i64 = 0 as i64; - #[cfg(all(not(OPENSSL_IS_BORINGSSL), not(LIBRESSL_VERSION_NUMBER)))] - let mut ossl_ssl_version_max: i64 = 0 as i64; - match curl_ssl_version_min { - 1 | 4 => { - ossl_ssl_version_min = 0x301 as i64; - } - 5 => { - ossl_ssl_version_min = 0x302 as i64; - } - 6 => { - ossl_ssl_version_min = 0x303 as i64; - } - #[cfg(TLS1_3_VERSION)] - 7 => { - ossl_ssl_version_min = 0x304 as i64; - } - _ => {} - } - /* CURL_SSLVERSION_DEFAULT means that no option was selected. - We don't want to pass 0 to SSL_CTX_set_min_proto_version as - it would enable all versions down to the lowest supported by - the library. - So we skip this, and stay with the library default + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else { + unsafe { + Curl_infof( + data, + b" common name: %s (matched)\0" as *const u8 as *const libc::c_char, + peer_CN, + ); + } + } + } + if !peer_CN.is_null() { + unsafe { + CRYPTO_free( + peer_CN as *mut libc::c_void, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 1835 as i32, + ); + } + } + } + } + return result; +} + +#[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP)))] +extern "C" fn verifystatus( + mut data: *mut Curl_easy, + mut connssl: *mut ssl_connect_data, +) -> CURLcode { + let mut current_block: u64; + let mut i: i32 = 0; + let mut ocsp_status: i32 = 0; + let mut status: *mut u8 = 0 as *mut u8; + let mut p: *const u8 = 0 as *const u8; + let mut result: CURLcode = CURLE_OK; + let mut rsp: *mut OCSP_RESPONSE = 0 as *mut OCSP_RESPONSE; + let mut br: *mut OCSP_BASICRESP = 0 as *mut OCSP_BASICRESP; + let mut st: *mut X509_STORE = 0 as *mut X509_STORE; + let mut ch: *mut stack_st_X509 = 0 as *mut stack_st_X509; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut cert: *mut X509 = 0 as *mut X509; + let mut id: *mut OCSP_CERTID = 0 as *mut OCSP_CERTID; + let mut cert_status: i32 = 0; + let mut crl_reason: i32 = 0; + let mut rev: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; + let mut thisupd: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; + let mut nextupd: *mut ASN1_GENERALIZEDTIME = 0 as *mut ASN1_GENERALIZEDTIME; + let mut ret: i32 = 0; + let mut len: i64 = unsafe { + SSL_ctrl( + (*backend).handle, + 70 as i32, + 0 as i64, + &mut status as *mut *mut u8 as *mut libc::c_void, + ) + }; + 'end: loop { + if status.is_null() { + unsafe { + Curl_failf( + data, + b"No OCSP response received\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + p = status; + rsp = unsafe { d2i_OCSP_RESPONSE(0 as *mut *mut OCSP_RESPONSE, &mut p, len) }; + if rsp.is_null() { + unsafe { + Curl_failf( + data, + b"Invalid OCSP response\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + ocsp_status = unsafe { OCSP_response_status(rsp) }; + if ocsp_status != 0 as i32 { + unsafe { + Curl_failf( + data, + b"Invalid OCSP response status: %s (%d)\0" as *const u8 as *const libc::c_char, + OCSP_response_status_str(ocsp_status as i64), + ocsp_status, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + br = unsafe { OCSP_response_get1_basic(rsp) }; + if br.is_null() { + unsafe { + Curl_failf( + data, + b"Invalid OCSP response\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + unsafe { + ch = SSL_get_peer_cert_chain((*backend).handle); + st = SSL_CTX_get_cert_store((*backend).ctx); + } + /* The authorized responder cert in the OCSP response MUST be signed by the + peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert, + no problem, but if it's an intermediate cert OpenSSL has a bug where it + expects this issuer to be present in the chain embedded in the OCSP + response. So we add it if necessary. */ + + /* First make sure the peer cert chain includes both a peer and an issuer, + and the OCSP response contains a responder cert. */ + // TODO - 1894 这里有一段跟OPENSSL_VERSION_NUMBER相关的条件编译 + if cfg!(any( + OPENSSL_VERSION_NUMBER_LT_0X1000201FL, + all( + LIBRESSL_VERSION_NUMBER, + LIBRESSL_VERSION_NUMBER_LT_0X2040200FL + ) + )) { + // TODO + } + if unsafe { OCSP_basic_verify(br, ch, st, 0 as u64) <= 0 as i32 } { + unsafe { + Curl_failf( + data, + b"OCSP response verification failed\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + cert = unsafe { SSL_get_peer_certificate((*backend).handle) }; + if cert.is_null() { + unsafe { + Curl_failf( + data, + b"Error getting peer certificate\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + /* Find issuer of responder cert and add it to the OCSP response chain */ + i = 0 as i32; + while i < sk_X509_num(ch) { + let mut issuer: *mut X509 = sk_X509_value(ch, i); + if unsafe { X509_check_issued(issuer, cert) } == 0 as i32 { + id = unsafe { OCSP_cert_to_id(EVP_sha1(), cert, issuer) }; + break; + } else { + i += 1; + } + } + unsafe { + X509_free(cert); + } + if id.is_null() { + unsafe { + Curl_failf( + data, + b"Error computing OCSP ID\0" as *const u8 as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + /* Find the single OCSP response corresponding to the certificate ID */ + unsafe { + ret = OCSP_resp_find_status( + br, + id, + &mut cert_status, + &mut crl_reason, + &mut rev, + &mut thisupd, + &mut nextupd, + ); + OCSP_CERTID_free(id); + } + if ret != 1 as i32 { + unsafe { + Curl_failf( + data, + b"Could not find certificate ID in OCSP response\0" as *const u8 + as *const libc::c_char, + ); + } + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + /* Validate the corresponding single OCSP response */ + unsafe { + if OCSP_check_validity(thisupd, nextupd, 300 as i64, -(1 as i64)) == 0 { + Curl_failf( + data, + b"OCSP response has expired\0" as *const u8 as *const libc::c_char, + ); + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + Curl_infof( + data, + b"SSL certificate status: %s (%d)\0" as *const u8 as *const libc::c_char, + OCSP_cert_status_str(cert_status as i64), + cert_status, + ); + } + let mut current_block_63: u64; + match cert_status { + 0 => { + current_block_63 = 13484060386966298149; + } + 1 => { + result = CURLE_SSL_INVALIDCERTSTATUS; + unsafe { + Curl_failf( + data, + b"SSL certificate revocation reason: %s (%d)\0" as *const u8 + as *const libc::c_char, + OCSP_crl_reason_str(crl_reason as i64), + crl_reason, + ); + } + current_block_63 = 11531555616992456840; + break 'end; + } + 2 | _ => { + current_block_63 = 11531555616992456840; + } + } + match current_block_63 { + 11531555616992456840 => { + result = CURLE_SSL_INVALIDCERTSTATUS; + break 'end; + } + _ => {} + } + break 'end; + } + if !br.is_null() { + unsafe { + OCSP_BASICRESP_free(br); + } + } + unsafe { + OCSP_RESPONSE_free(rsp); + } + return result; +} + +#[cfg(SSL_CTRL_SET_MSG_CALLBACK)] +extern "C" fn ssl_msg_type(mut ssl_ver: i32, mut msg: i32) -> *const libc::c_char { + if ssl_ver == 0x3 as i32 { + match msg { + 0 => return b"Hello request\0" as *const u8 as *const libc::c_char, + 1 => return b"Client hello\0" as *const u8 as *const libc::c_char, + 2 => return b"Server hello\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_NEWSESSION_TICKET)] + 4 => return b"Newsession Ticket\0" as *const u8 as *const libc::c_char, + 11 => return b"Certificate\0" as *const u8 as *const libc::c_char, + 12 => return b"Server key exchange\0" as *const u8 as *const libc::c_char, + 16 => return b"Client key exchange\0" as *const u8 as *const libc::c_char, + 13 => return b"Request CERT\0" as *const u8 as *const libc::c_char, + 14 => return b"Server finished\0" as *const u8 as *const libc::c_char, + 15 => return b"CERT verify\0" as *const u8 as *const libc::c_char, + 20 => return b"Finished\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_CERTIFICATE_STATUS)] + 22 => return b"Certificate Status\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_ENCRYPTED_EXTENSIONS)] + 8 => return b"Encrypted Extensions\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_SUPPLEMENTAL_DATA)] + 23 => return b"Supplemental data\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_END_OF_EARLY_DATA)] + 5 => return b"End of early data\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_KEY_UPDATE)] + 24 => return b"Key update\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_NEXT_PROTO)] + 67 => return b"Next protocol\0" as *const u8 as *const libc::c_char, + #[cfg(SSL3_MT_MESSAGE_HASH)] + 254 => return b"Message hash\0" as *const u8 as *const libc::c_char, + _ => {} + } + } + return b"Unknown\0" as *const u8 as *const libc::c_char; +} + +#[cfg(SSL_CTRL_SET_MSG_CALLBACK)] +extern "C" fn tls_rt_type(mut type_0: i32) -> *const libc::c_char { + match type_0 { + #[cfg(SSL3_RT_HEADER)] + 256 => return b"TLS header\0" as *const u8 as *const libc::c_char, + 20 => return b"TLS change cipher\0" as *const u8 as *const libc::c_char, + 21 => return b"TLS alert\0" as *const u8 as *const libc::c_char, + 22 => return b"TLS handshake\0" as *const u8 as *const libc::c_char, + 23 => return b"TLS app data\0" as *const u8 as *const libc::c_char, + _ => return b"TLS Unknown\0" as *const u8 as *const libc::c_char, + }; +} + +/* + * Our callback from the SSL/TLS layers. + */ +#[cfg(SSL_CTRL_SET_MSG_CALLBACK)] +extern "C" fn ossl_trace( + mut direction: i32, + mut ssl_ver: i32, + mut content_type: i32, + mut buf: *const libc::c_void, + mut len: size_t, + mut ssl: *mut SSL, + mut userp: *mut libc::c_void, +) { + let mut unknown: [libc::c_char; 32] = [0; 32]; + let mut verstr: *const libc::c_char = 0 as *const libc::c_char; + let mut conn: *mut connectdata = userp as *mut connectdata; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(0 as isize) as *mut ssl_connect_data }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut data: *mut Curl_easy = unsafe { (*backend).logger }; + if conn.is_null() + || data.is_null() + || unsafe { ((*data).set.fdebug).is_none() } + || direction != 0 as i32 && direction != 1 as i32 + { + return; + } + match ssl_ver { + #[cfg(SSL2_VERSION)] + 2 => { + verstr = b"SSLv2\0" as *const u8 as *const libc::c_char; + } + #[cfg(SSL3_VERSION)] + 768 => { + verstr = b"SSLv3\0" as *const u8 as *const libc::c_char; + } + 769 => { + verstr = b"TLSv1.0\0" as *const u8 as *const libc::c_char; + } + #[cfg(TLS1_1_VERSION)] + 770 => { + verstr = b"TLSv1.1\0" as *const u8 as *const libc::c_char; + } + #[cfg(TLS1_2_VERSION)] + 771 => { + verstr = b"TLSv1.2\0" as *const u8 as *const libc::c_char; + } + #[cfg(TLS1_3_VERSION)] + 772 => { + verstr = b"TLSv1.3\0" as *const u8 as *const libc::c_char; + } + 0 => {} + _ => { + unsafe { + curl_msnprintf( + unknown.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 32]>() as u64, + b"(%x)\0" as *const u8 as *const libc::c_char, + ssl_ver, + ); + } + verstr = unknown.as_mut_ptr(); + } + } + /* Log progress for interesting records only (like Handshake or Alert), skip + * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0). + * For TLS 1.3, skip notification of the decrypted inner Content-Type. */ - if curl_ssl_version_min != CURL_SSLVERSION_DEFAULT as i64 { - if unsafe { - SSL_CTX_ctrl( - ctx, - 123 as i32, - ossl_ssl_version_min, - 0 as *mut libc::c_void, - ) - } == 0 - { - return CURLE_SSL_CONNECT_ERROR; - } - } - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_version_max = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype } as u32 - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).proxy_ssl_config.version_max } - } else { - unsafe { (*conn).ssl_config.version_max } - }; - /* ... then, TLS max version */ - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_version_max = unsafe { (*conn).ssl_config.version_max }; - - curl_ssl_version_max = SSL_CONN_CONFIG_version_max; - let mut current_block_15: u64; - /* convert curl max SSL version option to OpenSSL constant */ - match curl_ssl_version_max { - 262144 => { - ossl_ssl_version_max = 0x301 as i64; - current_block_15 = 18386322304582297246; - } - 327680 => { - ossl_ssl_version_max = 0x302 as i64; - current_block_15 = 18386322304582297246; - } - 393216 => { - ossl_ssl_version_max = 0x303 as i64; - current_block_15 = 18386322304582297246; - } - #[cfg(TLS1_3_VERSION)] - 458752 => { - ossl_ssl_version_max = 0x304 as i64; - current_block_15 = 18386322304582297246; - } - // TODO 这里翻译的很奇怪,感觉没有必要这样 - 0 => { - current_block_15 = 9181747712041856033; - } - 65536 | _ => { - current_block_15 = 9181747712041856033; - } - } - match current_block_15 { - 9181747712041856033 => { - /* SSL_CTX_set_max_proto_version states that: - setting the maximum to 0 will enable - protocol versions up to the highest version - supported by the library */ - ossl_ssl_version_max = 0 as i64; - } - _ => {} - } - if unsafe { - SSL_CTX_ctrl( - ctx, - 124 as i32, - ossl_ssl_version_max, - 0 as *mut libc::c_void, - ) - } == 0 - { - return CURLE_SSL_CONNECT_ERROR; - } - return CURLE_OK; - } - - /* The "new session" callback must return zero if the session can be removed - * or non-zero if the session has been put into the session cache. - */ - // TODO 这里有个与OPENSSL_VERSION_NUMBER相关的条件编译 - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_new_session_cb(mut ssl: *mut SSL, mut ssl_sessionid: *mut SSL_SESSION) -> i32 { - let mut res: i32 = 0 as i32; - let mut conn: *mut connectdata = 0 as *mut connectdata; - let mut data: *mut Curl_easy = 0 as *mut Curl_easy; - let mut sockindex: i32 = 0; - let mut sockindex_ptr: *mut curl_socket_t = 0 as *mut curl_socket_t; - let mut data_idx: i32 = ossl_get_ssl_data_index(); - let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); - let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); - let mut proxy_idx: i32 = ossl_get_proxy_index(); - let mut isproxy: bool = false; - if data_idx < 0 as i32 - || connectdata_idx < 0 as i32 - || sockindex_idx < 0 as i32 - || proxy_idx < 0 as i32 - { - return 0 as i32; - } - conn = unsafe { SSL_get_ex_data(ssl, connectdata_idx) as *mut connectdata }; - if conn.is_null() { - return 0 as i32; - } - data = unsafe { SSL_get_ex_data(ssl, data_idx) as *mut Curl_easy }; - /* The sockindex has been stored as a pointer to an array element */ - sockindex_ptr = unsafe { SSL_get_ex_data(ssl, sockindex_idx) as *mut curl_socket_t }; - sockindex = unsafe { sockindex_ptr.offset_from(((*conn).sock).as_mut_ptr()) as i32 }; - isproxy = if unsafe { !(SSL_get_ex_data(ssl, proxy_idx)).is_null() } { - 1 as i32 - } else { - 0 as i32 - } != 0; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } - } else { - unsafe { ((*data).set.ssl.primary).sessionid() as i32 } - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() }; - if SSL_SET_OPTION_primary_sessionid != 0 { - let mut incache: bool = false; - let mut old_ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - Curl_ssl_sessionid_lock(data); - if isproxy { - incache = 0 as i32 != 0; - } else { - incache = !Curl_ssl_getsessionid( - data, - conn, - isproxy, - &mut old_ssl_sessionid, - 0 as *mut size_t, - sockindex, - ); - } - if incache { - if old_ssl_sessionid != ssl_sessionid as *mut libc::c_void { - unsafe { - Curl_infof( - data, - b"old SSL session ID is stale, removing\0" as *const u8 - as *const libc::c_char, - ); - } - Curl_ssl_delsessionid(data, old_ssl_sessionid); - incache = 0 as i32 != 0; - } - } - if !incache { - if Curl_ssl_addsessionid( - data, - conn, - isproxy, - ssl_sessionid as *mut libc::c_void, - 0 as size_t, - sockindex, - ) as u64 - == 0 - { - /* the session has been put into the session cache */ - res = 1 as i32; - } else { - unsafe { - Curl_failf( - data, - b"failed to store ssl session\0" as *const u8 as *const libc::c_char, - ); - } - } - } - Curl_ssl_sessionid_unlock(data); - } - return res; - } + // DONE - 2168 + #[cfg(SSL3_RT_INNER_CONTENT_TYPE)] + let SSL3_RT_INNER_CONTENT_TYPE_flag = content_type != 0x101; + #[cfg(not(SSL3_RT_INNER_CONTENT_TYPE))] + let SSL3_RT_INNER_CONTENT_TYPE_flag = true; + if ssl_ver != 0 && SSL3_RT_INNER_CONTENT_TYPE_flag { + let mut msg_name: *const libc::c_char = 0 as *const libc::c_char; + let mut tls_rt_name: *const libc::c_char = 0 as *const libc::c_char; + let mut ssl_buf: [libc::c_char; 1024] = [0; 1024]; + let mut msg_type: i32 = 0; + let mut txt_len: i32 = 0; + /* the info given when the version is zero is not that useful for us */ + + ssl_ver >>= 8 as i32; /* check the upper 8 bits only below */ + /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL + * always pass-up content-type as 0. But the interesting message-type + * is at 'buf[0]'. + */ + if ssl_ver == 0x3 as i32 && content_type != 0 { + tls_rt_name = tls_rt_type(content_type); + } else { + tls_rt_name = b"\0" as *const u8 as *const libc::c_char; + } + if content_type == 20 as i32 { + msg_type = unsafe { *(buf as *mut libc::c_char) } as i32; + msg_name = b"Change cipher spec\0" as *const u8 as *const libc::c_char; + } else if content_type == 21 as i32 { + msg_type = unsafe { + ((*(buf as *mut libc::c_char).offset(0 as isize) as i32) << 8 as i32) + + *(buf as *mut libc::c_char).offset(1 as isize) as i32 + }; + msg_name = unsafe { SSL_alert_desc_string_long(msg_type) }; + } else { + msg_type = unsafe { *(buf as *mut libc::c_char) } as i32; + msg_name = ssl_msg_type(ssl_ver, msg_type); + } + txt_len = unsafe { + curl_msnprintf( + ssl_buf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 1024]>() as u64, + b"%s (%s), %s, %s (%d):\n\0" as *const u8 as *const libc::c_char, + verstr, + if direction != 0 { + b"OUT\0" as *const u8 as *const libc::c_char + } else { + b"IN\0" as *const u8 as *const libc::c_char + }, + tls_rt_name, + msg_name, + msg_type, + ) + }; + if 0 as i32 <= txt_len + && (txt_len as u64) < ::std::mem::size_of::<[libc::c_char; 1024]>() as u64 + { + unsafe { + Curl_debug(data, CURLINFO_TEXT, ssl_buf.as_mut_ptr(), txt_len as size_t); + } + } + } + unsafe { + Curl_debug( + data, + (if direction == 1 as i32 { + CURLINFO_SSL_DATA_OUT as i32 + } else { + CURLINFO_SSL_DATA_IN as i32 + }) as curl_infotype, + buf as *mut libc::c_char, + len, + ); + } +} + +#[cfg(all(USE_OPENSSL, HAS_NPN))] +extern "C" fn select_next_protocol( + mut out: *mut *mut u8, + mut outlen: *mut u8, + mut in_0: *const u8, + mut inlen: u32, + mut key: *const libc::c_char, + mut keylen: u32, +) -> i32 { + let mut i: u32 = 0; + i = 0 as u32; + while i.wrapping_add(keylen) <= inlen { + if unsafe { + memcmp( + &*in_0.offset(i.wrapping_add(1 as u32) as isize) as *const u8 + as *const libc::c_void, + key as *const libc::c_void, + keylen as u64, + ) + } == 0 as i32 + { + unsafe { + *out = &*in_0.offset(i.wrapping_add(1 as u32) as isize) as *const u8 as *mut u8; + *outlen = *in_0.offset(i as isize); + } + return 0 as i32; + } + i = unsafe { i.wrapping_add((*in_0.offset(i as isize) as i32 + 1 as i32) as u32) }; + } + return -(1 as i32); +} + +#[cfg(all(USE_OPENSSL, HAS_NPN))] +extern "C" fn select_next_proto_cb( + mut ssl: *mut SSL, + mut out: *mut *mut u8, + mut outlen: *mut u8, + mut in_0: *const u8, + mut inlen: u32, + mut arg: *mut libc::c_void, +) -> i32 { + unsafe { + let mut data: *mut Curl_easy = arg as *mut Curl_easy; + let mut conn: *mut connectdata = (*data).conn; + #[cfg(USE_HTTP2)] + if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 + && select_next_protocol( + out, + outlen, + in_0, + inlen, + b"h2\0" as *const u8 as *const libc::c_char, + 2 as u32, + ) == 0 + { + Curl_infof( + data, + b"NPN, negotiated HTTP2 (%s)\0" as *const u8 as *const libc::c_char, + b"h2\0" as *const u8 as *const libc::c_char, + ); + (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; + return 0 as i32; + } + if select_next_protocol( + out, + outlen, + in_0, + inlen, + b"http/1.1\0" as *const u8 as *const libc::c_char, + 8 as u32, + ) == 0 + { + Curl_infof( + data, + b"NPN, negotiated HTTP1.1\0" as *const u8 as *const libc::c_char, + ); + (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; + return 0 as i32; + } + Curl_infof( + data, + b"NPN, no overlap, use HTTP1.1\0" as *const u8 as *const libc::c_char, + ); + *out = b"http/1.1\0" as *const u8 as *const libc::c_char as *mut u8; + *outlen = 8 as u8; + (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; + return 0 as i32; + } +} +// TODO +// USE_OPENSSL以及与OPENSSL_VERSION_NUMBER相关的条件编译 +#[cfg(USE_OPENSSL)] +extern "C" fn set_ssl_version_min_max( + mut ctx: *mut SSL_CTX, + mut conn: *mut connectdata, +) -> CURLcode { + #[cfg(not(CURL_DISABLE_PROXY))] + let mut curl_ssl_version_min: i64 = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.version } + } else { + unsafe { (*conn).ssl_config.version } + }; + #[cfg(CURL_DISABLE_PROXY)] + let mut curl_ssl_version_min: i64 = unsafe { (*conn).ssl_config.version }; + + let mut curl_ssl_version_max: i64 = 0; + // TODO - 2307 + // #[cfg(any(OPENSSL_IS_BORINGSSL, LIBRESSL_VERSION_NUMBER))] + // TODO - 2307 + // #[cfg(any(OPENSSL_IS_BORINGSSL, LIBRESSL_VERSION_NUMBER))] + #[cfg(all(not(OPENSSL_IS_BORINGSSL), not(LIBRESSL_VERSION_NUMBER)))] + let mut ossl_ssl_version_min: i64 = 0 as i64; + #[cfg(all(not(OPENSSL_IS_BORINGSSL), not(LIBRESSL_VERSION_NUMBER)))] + let mut ossl_ssl_version_max: i64 = 0 as i64; + match curl_ssl_version_min { + 1 | 4 => { + ossl_ssl_version_min = 0x301 as i64; + } + 5 => { + ossl_ssl_version_min = 0x302 as i64; + } + 6 => { + ossl_ssl_version_min = 0x303 as i64; + } + #[cfg(TLS1_3_VERSION)] + 7 => { + ossl_ssl_version_min = 0x304 as i64; + } + _ => {} + } + /* CURL_SSLVERSION_DEFAULT means that no option was selected. + We don't want to pass 0 to SSL_CTX_set_min_proto_version as + it would enable all versions down to the lowest supported by + the library. + So we skip this, and stay with the library default + */ + if curl_ssl_version_min != CURL_SSLVERSION_DEFAULT as i64 { + if unsafe { + SSL_CTX_ctrl( + ctx, + 123 as i32, + ossl_ssl_version_min, + 0 as *mut libc::c_void, + ) + } == 0 + { + return CURLE_SSL_CONNECT_ERROR; + } + } + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_version_max = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype } as u32 + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.version_max } + } else { + unsafe { (*conn).ssl_config.version_max } + }; + /* ... then, TLS max version */ + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_version_max = unsafe { (*conn).ssl_config.version_max }; + + curl_ssl_version_max = SSL_CONN_CONFIG_version_max; + let mut current_block_15: u64; + /* convert curl max SSL version option to OpenSSL constant */ + match curl_ssl_version_max { + 262144 => { + ossl_ssl_version_max = 0x301 as i64; + current_block_15 = 18386322304582297246; + } + 327680 => { + ossl_ssl_version_max = 0x302 as i64; + current_block_15 = 18386322304582297246; + } + 393216 => { + ossl_ssl_version_max = 0x303 as i64; + current_block_15 = 18386322304582297246; + } + #[cfg(TLS1_3_VERSION)] + 458752 => { + ossl_ssl_version_max = 0x304 as i64; + current_block_15 = 18386322304582297246; + } + // TODO 这里翻译的很奇怪,感觉没有必要这样 + 0 => { + current_block_15 = 9181747712041856033; + } + 65536 | _ => { + current_block_15 = 9181747712041856033; + } + } + match current_block_15 { + 9181747712041856033 => { + /* SSL_CTX_set_max_proto_version states that: + setting the maximum to 0 will enable + protocol versions up to the highest version + supported by the library */ + ossl_ssl_version_max = 0 as i64; + } + _ => {} + } + if unsafe { + SSL_CTX_ctrl( + ctx, + 124 as i32, + ossl_ssl_version_max, + 0 as *mut libc::c_void, + ) + } == 0 + { + return CURLE_SSL_CONNECT_ERROR; + } + return CURLE_OK; +} + +/* The "new session" callback must return zero if the session can be removed + * or non-zero if the session has been put into the session cache. + */ +// TODO 这里有个与OPENSSL_VERSION_NUMBER相关的条件编译 +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_new_session_cb(mut ssl: *mut SSL, mut ssl_sessionid: *mut SSL_SESSION) -> i32 { + let mut res: i32 = 0 as i32; + let mut conn: *mut connectdata = 0 as *mut connectdata; + let mut data: *mut Curl_easy = 0 as *mut Curl_easy; + let mut sockindex: i32 = 0; + let mut sockindex_ptr: *mut curl_socket_t = 0 as *mut curl_socket_t; + let mut data_idx: i32 = ossl_get_ssl_data_index(); + let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); + let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); + let mut proxy_idx: i32 = ossl_get_proxy_index(); + let mut isproxy: bool = false; + if data_idx < 0 as i32 + || connectdata_idx < 0 as i32 + || sockindex_idx < 0 as i32 + || proxy_idx < 0 as i32 + { + return 0 as i32; + } + conn = unsafe { SSL_get_ex_data(ssl, connectdata_idx) as *mut connectdata }; + if conn.is_null() { + return 0 as i32; + } + data = unsafe { SSL_get_ex_data(ssl, data_idx) as *mut Curl_easy }; + /* The sockindex has been stored as a pointer to an array element */ + sockindex_ptr = unsafe { SSL_get_ex_data(ssl, sockindex_idx) as *mut curl_socket_t }; + sockindex = unsafe { sockindex_ptr.offset_from(((*conn).sock).as_mut_ptr()) as i32 }; + isproxy = if unsafe { !(SSL_get_ex_data(ssl, proxy_idx)).is_null() } { + 1 as i32 + } else { + 0 as i32 + } != 0; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } + } else { + unsafe { ((*data).set.ssl.primary).sessionid() as i32 } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() }; + if SSL_SET_OPTION_primary_sessionid != 0 { + let mut incache: bool = false; + let mut old_ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + Curl_ssl_sessionid_lock(data); + if isproxy { + incache = 0 as i32 != 0; + } else { + incache = !Curl_ssl_getsessionid( + data, + conn, + isproxy, + &mut old_ssl_sessionid, + 0 as *mut size_t, + sockindex, + ); + } + if incache { + if old_ssl_sessionid != ssl_sessionid as *mut libc::c_void { + unsafe { + Curl_infof( + data, + b"old SSL session ID is stale, removing\0" as *const u8 + as *const libc::c_char, + ); + } + Curl_ssl_delsessionid(data, old_ssl_sessionid); + incache = 0 as i32 != 0; + } + } + if !incache { + if Curl_ssl_addsessionid( + data, + conn, + isproxy, + ssl_sessionid as *mut libc::c_void, + 0 as size_t, + sockindex, + ) as u64 + == 0 + { + /* the session has been put into the session cache */ + res = 1 as i32; + } else { + unsafe { + Curl_failf( + data, + b"failed to store ssl session\0" as *const u8 as *const libc::c_char, + ); + } + } + } + Curl_ssl_sessionid_unlock(data); + } + return res; +} // hanxj - #[cfg(USE_OPENSSL)] - extern "C" fn load_cacert_from_memory( - mut ctx: *mut SSL_CTX, - mut ca_info_blob: *const curl_blob, - ) -> CURLcode { - /* these need to be freed at the end */ - let mut cbio: *mut BIO = 0 as *mut BIO; - let mut inf: *mut stack_st_X509_INFO = 0 as *mut stack_st_X509_INFO; - /* everything else is just a reference */ - let mut i: i32 = 0; - let mut count: i32 = 0 as i32; - let mut cts: *mut X509_STORE = 0 as *mut X509_STORE; - let mut itmp: *mut X509_INFO = 0 as *mut X509_INFO; - if unsafe { (*ca_info_blob).len } > 2147483647 as size_t { - return CURLE_SSL_CACERT_BADFILE; - } - cts = unsafe { SSL_CTX_get_cert_store(ctx) }; - if cts.is_null() { - return CURLE_OUT_OF_MEMORY; - } - cbio = unsafe { BIO_new_mem_buf((*ca_info_blob).data, (*ca_info_blob).len as i32) }; - if cbio.is_null() { - return CURLE_OUT_OF_MEMORY; - } - inf = unsafe { - PEM_X509_INFO_read_bio( - cbio, - 0 as *mut stack_st_X509_INFO, - None, - 0 as *mut libc::c_void, - ) - }; - if inf.is_null() { - unsafe { - BIO_free(cbio); - } - return CURLE_SSL_CACERT_BADFILE; - } - /* add each entry from PEM file to x509_store */ - i = 0 as i32; - while i < sk_X509_INFO_num(inf) { - itmp = sk_X509_INFO_value(inf, i); - if unsafe { !((*itmp).x509).is_null() } { - if unsafe { X509_STORE_add_cert(cts, (*itmp).x509) } != 0 { - count += 1; - } else { - /* set count to 0 to return an error */ - count = 0 as i32; - break; - } - } - if unsafe { !((*itmp).crl).is_null() } { - if unsafe { X509_STORE_add_crl(cts, (*itmp).crl) } != 0 { - count += 1; - } else { - /* set count to 0 to return an error */ - count = 0 as i32; - break; - } - } - i += 1; - } - sk_X509_INFO_pop_free( - inf, - Some(X509_INFO_free as unsafe extern "C" fn(*mut X509_INFO) -> ()), - ); - unsafe { - BIO_free(cbio); - } - /* if we didn't end up importing anything, treat that as an error */ - return (if count > 0 as i32 { - CURLE_OK as i32 - } else { - CURLE_SSL_CACERT_BADFILE as i32 - }) as CURLcode; - } - - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_connect_step1( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut ciphers: *mut libc::c_char = 0 as *mut libc::c_char; - let mut req_method: *const SSL_METHOD = 0 as *const SSL_METHOD; - let mut lookup: *mut X509_LOOKUP = 0 as *mut X509_LOOKUP; - let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } - as *mut ssl_connect_data; - let mut ctx_options: ctx_option_t = 0 as ctx_option_t; - let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - let mut sni: bool = false; - let hostname: *const libc::c_char = unsafe { (*conn).host.name }; - let mut addr: in_addr = in_addr { s_addr: 0 }; - let ssl_version: i64 = unsafe { (*conn).ssl_config.version }; - let ssl_authtype: CURL_TLSAUTH = unsafe { (*data).set.ssl.authtype }; - let ssl_cert: *mut libc::c_char = unsafe { (*data).set.ssl.primary.clientcert }; - let mut ssl_cert_blob: *const curl_blob = unsafe { (*data).set.ssl.primary.cert_blob }; - let mut ca_info_blob: *const curl_blob = unsafe { (*conn).ssl_config.ca_info_blob }; - let ssl_cert_type: *const libc::c_char = unsafe { (*data).set.ssl.cert_type }; - let ssl_cafile: *const libc::c_char = if !ca_info_blob.is_null() { - 0 as *mut libc::c_char - } else { - unsafe { (*conn).ssl_config.CAfile } - }; - let ssl_capath: *const libc::c_char = unsafe { (*conn).ssl_config.CApath }; - let verifypeer: bool = unsafe { ((*conn).ssl_config).verifypeer() } != 0; - let ssl_crlfile: *const libc::c_char = unsafe { (*data).set.ssl.CRLfile }; /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ - let mut error_buffer: [libc::c_char; 256] = [0; 256]; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - let mut imported_native_ca: bool = 0 as i32 != 0; - /* Make funny stuff to get random input */ - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ssl_connect_1 as u32 == unsafe { (*connssl).connecting_state as u32 } { - } else { - unsafe { - __assert_fail( - b"ssl_connect_1 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 2628 as u32, - (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( - b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - } - result = ossl_seed(data); - if result as u64 != 0 { - return result; - } - unsafe { - (*data).set.ssl.certverifyresult = (0 as i32 == 0) as i64; - } - /* check to see if we've been told to use an explicit SSL/TLS version */ - match ssl_version { - 0 | 1 | 4 | 5 | 6 | 7 => { - req_method = unsafe { TLS_client_method() }; /* it will be handled later with the context options */ - sni = 1 as i32 != 0; - } - 2 => { - unsafe { - Curl_failf( - data, - b"No SSLv2 support\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_NOT_BUILT_IN; - } - 3 => { - unsafe { - Curl_failf( - data, - b"No SSLv3 support\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_NOT_BUILT_IN; - } - _ => { - unsafe { - Curl_failf( - data, - b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 - as *const libc::c_char, - ); - } - return CURLE_SSL_CONNECT_ERROR; - } - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if unsafe { ((*backend).ctx).is_null() } { - } else { - unsafe { - __assert_fail( - b"!backend->ctx\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 2665 as u32, - (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( - b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - } - unsafe { - (*backend).ctx = SSL_CTX_new(req_method); - if ((*backend).ctx).is_null() { - Curl_failf( - data, - b"SSL: couldn't create a context: %s\0" as *const u8 as *const libc::c_char, - ossl_strerror( - ERR_peek_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return CURLE_OUT_OF_MEMORY; - } - SSL_CTX_ctrl( - (*backend).ctx, - 33 as i32, - 0x10 as i64, - 0 as *mut libc::c_void, - ); - if ((*data).set.fdebug).is_some() && ((*data).set).verbose() as i32 != 0 { - /* the SSL trace callback is only used for verbose logging */ - SSL_CTX_set_msg_callback( - (*backend).ctx, - Some( - ossl_trace - as unsafe extern "C" fn( - i32, - i32, - i32, - *const libc::c_void, - size_t, - *mut SSL, - *mut libc::c_void, - ) -> (), - ), - ); - SSL_CTX_ctrl( - (*backend).ctx, - 16 as i32, - 0 as i64, - conn as *mut libc::c_void, - ); - (*(*conn).ssl[0 as usize].backend).logger = data; - } - } - /* OpenSSL contains code to work around lots of bugs and flaws in various - SSL-implementations. SSL_CTX_set_options() is used to enabled those - work-arounds. The man page for this option states that SSL_OP_ALL enables - all the work-arounds and that "It is usually safe to use SSL_OP_ALL to - enable the bug workaround options if compatibility with somewhat broken - implementations is desired." - - The "-no_ticket" option was introduced in OpenSSL 0.9.8j. It's a flag to - disable "rfc4507bis session ticket support". rfc4507bis was later turned - into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077 - - The enabled extension concerns the session management. I wonder how often - libcurl stops a connection and then resumes a TLS session. Also, sending - the session data is some overhead. I suggest that you just use your - proposed patch (which explicitly disables TICKET). - - If someone writes an application with libcurl and OpenSSL who wants to - enable the feature, one can do this in the SSL callback. - - SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper - interoperability with web server Netscape Enterprise Server 2.0.1 which - was released back in 1996. - - Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has - become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate - CVE-2010-4180 when using previous OpenSSL versions we no longer enable - this option regardless of OpenSSL version and SSL_OP_ALL definition. - - OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability - (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to - SSL_OP_ALL that _disables_ that work-around despite the fact that - SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to - keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit - must not be set. - */ - ctx_options = - (0x80000000 as u32 | 0x800 as u32 | 0x4 as u32 | 0x10 as u32 | 0x40 as u32) as ctx_option_t; - ctx_options |= 0x4000 as i64; - ctx_options |= 0x20000 as i64; - ctx_options &= !(0 as i32) as i64; - if unsafe { ((*data).set.ssl).enable_beast() == 0 } { - ctx_options &= !(0x800 as u32) as i64; - } - let mut current_block_41: u64; - match ssl_version { - 2 | 3 => return CURLE_NOT_BUILT_IN, - 0 | 1 => { - current_block_41 = 14687600604451543688; - } - 4 => { - current_block_41 = 14687600604451543688; - } - 5 => { - current_block_41 = 9382186424990608957; - } - 6 | 7 => { - current_block_41 = 4869852262838046136; - } - _ => { - unsafe { - Curl_failf( - data, - b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 - as *const libc::c_char, - ); - } - return CURLE_SSL_CONNECT_ERROR; - } - } - match current_block_41 { - 14687600604451543688 => { - current_block_41 = 9382186424990608957; - } - _ => {} - } - match current_block_41 { - 9382186424990608957 => {} - _ => {} - } - /* asking for any TLS version as the minimum, means no SSL versions - allowed */ - ctx_options |= 0 as i64; - ctx_options |= 0x2000000 as i64; - result = unsafe { set_ssl_version_min_max((*backend).ctx, conn) }; - if result as u32 != CURLE_OK as u32 { - return result; - } - unsafe { - SSL_CTX_set_options((*backend).ctx, ctx_options as u64); - - // ************************************************************************ - #[cfg(HAS_NPN)] - if ((*conn).bits).tls_enable_npn() != 0 { - SSL_CTX_set_next_proto_select_cb( - (*backend).ctx, - Some( - select_next_proto_cb - as unsafe extern "C" fn( - *mut SSL, - *mut *mut u8, - *mut u8, - *const u8, - u32, - *mut libc::c_void, - ) -> i32, - ), - data as *mut libc::c_void, - ); - } - } - #[cfg(HAS_APLN)] - if unsafe { ((*conn).bits).tls_enable_alpn() != 0 } { - let mut cur: i32 = 0 as i32; - let mut protocols: [u8; 128] = [0; 128]; - if cfg!(USE_HTTP2) { - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let CURL_DISABLE_PROXY_flag_1 = (!(CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32) - || ((*conn).bits).tunnel_proxy() == 0); - #[cfg(CURL_DISABLE_PROXY)] - let CURL_DISABLE_PROXY_flag_1 = true; - if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 - && CURL_DISABLE_PROXY_flag_1 - { - let fresh10 = cur; - cur = cur + 1; - protocols[fresh10 as usize] = 2 as u8; - memcpy( - &mut *protocols.as_mut_ptr().offset(cur as isize) as *mut u8 - as *mut libc::c_void, - b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, - 2 as u64, - ); - cur += 2 as i32; - Curl_infof( - data, - b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, - b"h2\0" as *const u8 as *const libc::c_char, - ); - } - } - } - let fresh11 = cur; - cur = cur + 1; - protocols[fresh11 as usize] = 8 as u8; - unsafe { - memcpy( - &mut *protocols.as_mut_ptr().offset(cur as isize) as *mut u8 as *mut libc::c_void, - b"http/1.1\0" as *const u8 as *const libc::c_char as *const libc::c_void, - 8 as u64, - ); - } - cur += 8 as i32; - unsafe { - Curl_infof( - data, - b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, - b"http/1.1\0" as *const u8 as *const libc::c_char, - ); - } - /* expects length prefixed preference ordered list of protocols in wire - * format - */ - if unsafe { SSL_CTX_set_alpn_protos((*backend).ctx, protocols.as_mut_ptr(), cur as u32) } - != 0 - { - unsafe { - Curl_failf( - data, - b"Error setting ALPN\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_SSL_CONNECT_ERROR; - } - } - - if !ssl_cert.is_null() || !ssl_cert_blob.is_null() || !ssl_cert_type.is_null() { - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let cert_stuff_flag = cert_stuff( - data, - (*backend).ctx, - ssl_cert, - ssl_cert_blob, - ssl_cert_type, - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key - } else { - (*data).set.ssl.key - }), - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key_blob - } else { - (*data).set.ssl.key_blob - }), - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key_type - } else { - (*data).set.ssl.key_type - }), - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key_passwd - } else { - (*data).set.ssl.key_passwd - }), - ); - #[cfg(CURL_DISABLE_PROXY)] - let cert_stuff_flag = cert_stuff( - data, - (*backend).ctx, - ssl_cert, - ssl_cert_blob, - ssl_cert_type, - (*data).set.ssl.key, - (*data).set.ssl.key_blob, - (*data).set.ssl.key_type, - (*data).set.ssl.key_passwd, - ); - if result as u64 == 0 && cert_stuff_flag == 0 { - result = CURLE_SSL_CERTPROBLEM; - } - if result as u64 != 0 { - /* failf() is already done in cert_stuff() */ - return result; - } - } - } - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_cipher_list = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.cipher_list - } else { - (*conn).ssl_config.cipher_list - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_cipher_list = (*conn).ssl_config.cipher_list; - ciphers = SSL_CONN_CONFIG_cipher_list; - if ciphers.is_null() { - ciphers = 0 as *mut libc::c_char; - } - if !ciphers.is_null() { - if SSL_CTX_set_cipher_list((*backend).ctx, ciphers) == 0 { - Curl_failf( - data, - b"failed setting cipher list: %s\0" as *const u8 as *const libc::c_char, - ciphers, - ); - return CURLE_SSL_CIPHER; - } - Curl_infof( - data, - b"Cipher selection: %s\0" as *const u8 as *const libc::c_char, - ciphers, - ); - } - - // *************************************************************** - #[cfg(all(HAVE_SSL_CTX_SET_CIPHERSUITES, not(CURL_DISABLE_PROXY)))] - let mut ciphers13: *mut libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.cipher_list13 - } else { - (*conn).ssl_config.cipher_list13 - }; - - #[cfg(all(HAVE_SSL_CTX_SET_CIPHERSUITES, CURL_DISABLE_PROXY))] - let mut ciphers13: *mut libc::c_char = (*conn).ssl_config.cipher_list13; - #[cfg(HAVE_SSL_CTX_SET_CIPHERSUITES)] - if !ciphers13.is_null() { - if SSL_CTX_set_ciphersuites((*backend).ctx, ciphers13) == 0 { - Curl_failf( - data, - b"failed setting TLS 1.3 cipher suite: %s\0" as *const u8 - as *const libc::c_char, - ciphers13, - ); - return CURLE_SSL_CIPHER; - } - Curl_infof( - data, - b"TLS 1.3 cipher selection: %s\0" as *const u8 as *const libc::c_char, - ciphers13, - ); - } - /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ - #[cfg(HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH)] - SSL_CTX_set_post_handshake_auth((*backend).ctx, 1 as i32); - #[cfg(all(HAVE_SSL_CTX_SET_EC_CURVES, not(CURL_DISABLE_PROXY)))] - let mut curves: *mut libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.curves - } else { - (*conn).ssl_config.curves - }; - #[cfg(all(HAVE_SSL_CTX_SET_EC_CURVES, CURL_DISABLE_PROXY))] - let mut curves: *mut libc::c_char = (*conn).ssl_config.curves; - #[cfg(HAVE_SSL_CTX_SET_EC_CURVES)] - if !curves.is_null() { - if SSL_CTX_ctrl( - (*backend).ctx, - 92 as i32, - 0 as i64, - curves as *mut libc::c_void, - ) == 0 - { - Curl_failf( - data, - b"failed setting curves list: '%s'\0" as *const u8 as *const libc::c_char, - curves, - ); - return CURLE_SSL_CIPHER; - } - } - // #[cfg(USE_OPENSSL_SRP)] - if ssl_authtype as u32 == CURL_TLSAUTH_SRP as u32 { - #[cfg(not(CURL_DISABLE_PROXY))] - let ssl_username: *mut libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }; - #[cfg(CURL_DISABLE_PROXY)] - let ssl_username: *mut libc::c_char = (*data).set.ssl.username; - Curl_infof( - data, - b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, - ssl_username, - ); - if SSL_CTX_set_srp_username((*backend).ctx, ssl_username) == 0 { - Curl_failf( - data, - b"Unable to set SRP user name\0" as *const u8 as *const libc::c_char, - ); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - #[cfg(not(CURL_DISABLE_PROXY))] - if SSL_CTX_set_srp_password( - (*backend).ctx, - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.password - } else { - (*data).set.ssl.password - }), - ) == 0 - { - Curl_failf( - data, - b"failed setting SRP password\0" as *const u8 as *const libc::c_char, - ); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - #[cfg(CURL_DISABLE_PROXY)] - if SSL_CTX_set_srp_password((*backend).ctx, (*data).set.ssl.password) == 0 { - Curl_failf( - data, - b"failed setting SRP password\0" as *const u8 as *const libc::c_char, - ); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - #[cfg(not(CURL_DISABLE_PROXY))] - if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.cipher_list - } else { - (*conn).ssl_config.cipher_list - } - .is_null() - { - Curl_infof( - data, - b"Setting cipher list SRP\0" as *const u8 as *const libc::c_char, - ); - if SSL_CTX_set_cipher_list( - (*backend).ctx, - b"SRP\0" as *const u8 as *const libc::c_char, - ) == 0 - { - Curl_failf( - data, - b"failed setting SRP cipher list\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CIPHER; - } - } - #[cfg(CURL_DISABLE_PROXY)] - if ((*conn).ssl_config.cipher_list).is_null() { - Curl_infof( - data, - b"Setting cipher list SRP\0" as *const u8 as *const libc::c_char, - ); - if SSL_CTX_set_cipher_list( - (*backend).ctx, - b"SRP\0" as *const u8 as *const libc::c_char, - ) == 0 - { - Curl_failf( - data, - b"failed setting SRP cipher list\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CIPHER; - } - } - } - } - if !ca_info_blob.is_null() { - result = unsafe { load_cacert_from_memory((*backend).ctx, ca_info_blob) }; - if result as u64 != 0 { - if result as u32 == CURLE_OUT_OF_MEMORY as u32 - || verifypeer as i32 != 0 && !imported_native_ca - { - /* Fail if we insist on successfully verifying the server. */ - unsafe { - Curl_failf( - data, - b"error importing CA certificate blob\0" as *const u8 - as *const libc::c_char, - ); - } - return result; - } - /* Continue with warning if certificate verification isn't required. */ - unsafe { - Curl_infof( - data, - b"error importing CA certificate blob, continuing anyway\0" as *const u8 - as *const libc::c_char, - ); - } - } - } - if !ssl_cafile.is_null() || !ssl_capath.is_null() { - /* tell SSL where to find CA certificates that are used to verify - the server's certificate. */ - if unsafe { SSL_CTX_load_verify_locations((*backend).ctx, ssl_cafile, ssl_capath) } == 0 { - if verifypeer as i32 != 0 && !imported_native_ca { - /* Fail if we insist on successfully verifying the server. */ - unsafe { - Curl_failf( - data, - b"error setting certificate verify locations: CAfile: %s CApath: %s\0" - as *const u8 as *const libc::c_char, - if !ssl_cafile.is_null() { - ssl_cafile - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - if !ssl_capath.is_null() { - ssl_capath - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - } - return CURLE_SSL_CACERT_BADFILE; - } - /* Just continue with a warning if no strict certificate verification - is required. */ - unsafe { - Curl_infof( - data, - b"error setting certificate verify locations, continuing anyway:\0" as *const u8 - as *const libc::c_char, - ); - } - } else { - /* Everything is fine. */ - unsafe { - Curl_infof( - data, - b"successfully set certificate verify locations:\0" as *const u8 - as *const libc::c_char, - ); - } - } - unsafe { - Curl_infof( - data, - b" CAfile: %s\0" as *const u8 as *const libc::c_char, - if !ssl_cafile.is_null() { - ssl_cafile - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - Curl_infof( - data, - b" CApath: %s\0" as *const u8 as *const libc::c_char, - if !ssl_capath.is_null() { - ssl_capath - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - } - } - - if !ssl_crlfile.is_null() { - /* tell OpenSSL where to find CRL file that is used to check certificate - * revocation */ - lookup = unsafe { - X509_STORE_add_lookup(SSL_CTX_get_cert_store((*backend).ctx), X509_LOOKUP_file()) - }; - if lookup.is_null() || unsafe { X509_load_crl_file(lookup, ssl_crlfile, 1 as i32) } == 0 { - unsafe { - Curl_failf( - data, - b"error loading CRL file: %s\0" as *const u8 as *const libc::c_char, - ssl_crlfile, - ); - } - return CURLE_SSL_CRL_BADFILE; - } - /* Everything is fine. */ - unsafe { - Curl_infof( - data, - b"successfully loaded CRL file:\0" as *const u8 as *const libc::c_char, - ); - X509_STORE_set_flags( - SSL_CTX_get_cert_store((*backend).ctx), - (0x4 as i32 | 0x8 as i32) as u64, - ); - Curl_infof( - data, - b" CRLfile: %s\0" as *const u8 as *const libc::c_char, - ssl_crlfile, - ); - } - } - if verifypeer { - /* Try building a chain using issuers in the trusted store first to avoid - problems with server-sent legacy intermediates. Newer versions of - OpenSSL do alternate chain checking by default but we do not know how to - determine that in a reliable manner. - https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest +#[cfg(USE_OPENSSL)] +extern "C" fn load_cacert_from_memory( + mut ctx: *mut SSL_CTX, + mut ca_info_blob: *const curl_blob, +) -> CURLcode { + /* these need to be freed at the end */ + let mut cbio: *mut BIO = 0 as *mut BIO; + let mut inf: *mut stack_st_X509_INFO = 0 as *mut stack_st_X509_INFO; + /* everything else is just a reference */ + let mut i: i32 = 0; + let mut count: i32 = 0 as i32; + let mut cts: *mut X509_STORE = 0 as *mut X509_STORE; + let mut itmp: *mut X509_INFO = 0 as *mut X509_INFO; + if unsafe { (*ca_info_blob).len } > 2147483647 as size_t { + return CURLE_SSL_CACERT_BADFILE; + } + cts = unsafe { SSL_CTX_get_cert_store(ctx) }; + if cts.is_null() { + return CURLE_OUT_OF_MEMORY; + } + cbio = unsafe { BIO_new_mem_buf((*ca_info_blob).data, (*ca_info_blob).len as i32) }; + if cbio.is_null() { + return CURLE_OUT_OF_MEMORY; + } + inf = unsafe { + PEM_X509_INFO_read_bio( + cbio, + 0 as *mut stack_st_X509_INFO, + None, + 0 as *mut libc::c_void, + ) + }; + if inf.is_null() { + unsafe { + BIO_free(cbio); + } + return CURLE_SSL_CACERT_BADFILE; + } + /* add each entry from PEM file to x509_store */ + i = 0 as i32; + while i < sk_X509_INFO_num(inf) { + itmp = sk_X509_INFO_value(inf, i); + if unsafe { !((*itmp).x509).is_null() } { + if unsafe { X509_STORE_add_cert(cts, (*itmp).x509) } != 0 { + count += 1; + } else { + /* set count to 0 to return an error */ + count = 0 as i32; + break; + } + } + if unsafe { !((*itmp).crl).is_null() } { + if unsafe { X509_STORE_add_crl(cts, (*itmp).crl) } != 0 { + count += 1; + } else { + /* set count to 0 to return an error */ + count = 0 as i32; + break; + } + } + i += 1; + } + sk_X509_INFO_pop_free( + inf, + Some(X509_INFO_free as unsafe extern "C" fn(*mut X509_INFO) -> ()), + ); + unsafe { + BIO_free(cbio); + } + /* if we didn't end up importing anything, treat that as an error */ + return (if count > 0 as i32 { + CURLE_OK as i32 + } else { + CURLE_SSL_CACERT_BADFILE as i32 + }) as CURLcode; +} + +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_connect_step1( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut ciphers: *mut libc::c_char = 0 as *mut libc::c_char; + let mut req_method: *const SSL_METHOD = 0 as *const SSL_METHOD; + let mut lookup: *mut X509_LOOKUP = 0 as *mut X509_LOOKUP; + let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } + as *mut ssl_connect_data; + let mut ctx_options: ctx_option_t = 0 as ctx_option_t; + let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + let mut sni: bool = false; + let hostname: *const libc::c_char = unsafe { (*conn).host.name }; + let mut addr: in_addr = in_addr { s_addr: 0 }; + let ssl_version: i64 = unsafe { (*conn).ssl_config.version }; + let ssl_authtype: CURL_TLSAUTH = unsafe { (*data).set.ssl.authtype }; + let ssl_cert: *mut libc::c_char = unsafe { (*data).set.ssl.primary.clientcert }; + let mut ssl_cert_blob: *const curl_blob = unsafe { (*data).set.ssl.primary.cert_blob }; + let mut ca_info_blob: *const curl_blob = unsafe { (*conn).ssl_config.ca_info_blob }; + let ssl_cert_type: *const libc::c_char = unsafe { (*data).set.ssl.cert_type }; + let ssl_cafile: *const libc::c_char = if !ca_info_blob.is_null() { + 0 as *mut libc::c_char + } else { + unsafe { (*conn).ssl_config.CAfile } + }; + let ssl_capath: *const libc::c_char = unsafe { (*conn).ssl_config.CApath }; + let verifypeer: bool = unsafe { ((*conn).ssl_config).verifypeer() } != 0; + let ssl_crlfile: *const libc::c_char = unsafe { (*data).set.ssl.CRLfile }; /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ + let mut error_buffer: [libc::c_char; 256] = [0; 256]; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + let mut imported_native_ca: bool = 0 as i32 != 0; + /* Make funny stuff to get random input */ + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ssl_connect_1 as u32 == unsafe { (*connssl).connecting_state as u32 } { + } else { + unsafe { + __assert_fail( + b"ssl_connect_1 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 2628 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + result = ossl_seed(data); + if result as u64 != 0 { + return result; + } + unsafe { + (*data).set.ssl.certverifyresult = (0 as i32 == 0) as i64; + } + /* check to see if we've been told to use an explicit SSL/TLS version */ + match ssl_version { + 0 | 1 | 4 | 5 | 6 | 7 => { + req_method = unsafe { TLS_client_method() }; /* it will be handled later with the context options */ + sni = 1 as i32 != 0; + } + 2 => { + unsafe { + Curl_failf( + data, + b"No SSLv2 support\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_NOT_BUILT_IN; + } + 3 => { + unsafe { + Curl_failf( + data, + b"No SSLv3 support\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_NOT_BUILT_IN; + } + _ => { + unsafe { + Curl_failf( + data, + b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 + as *const libc::c_char, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if unsafe { ((*backend).ctx).is_null() } { + } else { + unsafe { + __assert_fail( + b"!backend->ctx\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 2665 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode ossl_connect_step1(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + unsafe { + (*backend).ctx = SSL_CTX_new(req_method); + if ((*backend).ctx).is_null() { + Curl_failf( + data, + b"SSL: couldn't create a context: %s\0" as *const u8 as *const libc::c_char, + ossl_strerror( + ERR_peek_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return CURLE_OUT_OF_MEMORY; + } + SSL_CTX_ctrl( + (*backend).ctx, + 33 as i32, + 0x10 as i64, + 0 as *mut libc::c_void, + ); + if ((*data).set.fdebug).is_some() && ((*data).set).verbose() as i32 != 0 { + /* the SSL trace callback is only used for verbose logging */ + SSL_CTX_set_msg_callback( + (*backend).ctx, + Some( + ossl_trace + as unsafe extern "C" fn( + i32, + i32, + i32, + *const libc::c_void, + size_t, + *mut SSL, + *mut libc::c_void, + ) -> (), + ), + ); + SSL_CTX_ctrl( + (*backend).ctx, + 16 as i32, + 0 as i64, + conn as *mut libc::c_void, + ); + (*(*conn).ssl[0 as usize].backend).logger = data; + } + } + /* OpenSSL contains code to work around lots of bugs and flaws in various + SSL-implementations. SSL_CTX_set_options() is used to enabled those + work-arounds. The man page for this option states that SSL_OP_ALL enables + all the work-arounds and that "It is usually safe to use SSL_OP_ALL to + enable the bug workaround options if compatibility with somewhat broken + implementations is desired." + + The "-no_ticket" option was introduced in OpenSSL 0.9.8j. It's a flag to + disable "rfc4507bis session ticket support". rfc4507bis was later turned + into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077 + + The enabled extension concerns the session management. I wonder how often + libcurl stops a connection and then resumes a TLS session. Also, sending + the session data is some overhead. I suggest that you just use your + proposed patch (which explicitly disables TICKET). + + If someone writes an application with libcurl and OpenSSL who wants to + enable the feature, one can do this in the SSL callback. + + SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper + interoperability with web server Netscape Enterprise Server 2.0.1 which + was released back in 1996. + + Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has + become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate + CVE-2010-4180 when using previous OpenSSL versions we no longer enable + this option regardless of OpenSSL version and SSL_OP_ALL definition. + + OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability + (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to + SSL_OP_ALL that _disables_ that work-around despite the fact that + SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to + keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit + must not be set. + */ + ctx_options = + (0x80000000 as u32 | 0x800 as u32 | 0x4 as u32 | 0x10 as u32 | 0x40 as u32) as ctx_option_t; + ctx_options |= 0x4000 as i64; + ctx_options |= 0x20000 as i64; + ctx_options &= !(0 as i32) as i64; + if unsafe { ((*data).set.ssl).enable_beast() == 0 } { + ctx_options &= !(0x800 as u32) as i64; + } + let mut current_block_41: u64; + match ssl_version { + 2 | 3 => return CURLE_NOT_BUILT_IN, + 0 | 1 => { + current_block_41 = 14687600604451543688; + } + 4 => { + current_block_41 = 14687600604451543688; + } + 5 => { + current_block_41 = 9382186424990608957; + } + 6 | 7 => { + current_block_41 = 4869852262838046136; + } + _ => { + unsafe { + Curl_failf( + data, + b"Unrecognized parameter passed via CURLOPT_SSLVERSION\0" as *const u8 + as *const libc::c_char, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + } + match current_block_41 { + 14687600604451543688 => { + current_block_41 = 9382186424990608957; + } + _ => {} + } + match current_block_41 { + 9382186424990608957 => {} + _ => {} + } + /* asking for any TLS version as the minimum, means no SSL versions + allowed */ + ctx_options |= 0 as i64; + ctx_options |= 0x2000000 as i64; + result = unsafe { set_ssl_version_min_max((*backend).ctx, conn) }; + if result as u32 != CURLE_OK as u32 { + return result; + } + unsafe { + SSL_CTX_set_options((*backend).ctx, ctx_options as u64); + + // ************************************************************************ + #[cfg(HAS_NPN)] + if ((*conn).bits).tls_enable_npn() != 0 { + SSL_CTX_set_next_proto_select_cb( + (*backend).ctx, + Some( + select_next_proto_cb + as unsafe extern "C" fn( + *mut SSL, + *mut *mut u8, + *mut u8, + *const u8, + u32, + *mut libc::c_void, + ) -> i32, + ), + data as *mut libc::c_void, + ); + } + } + #[cfg(HAS_APLN)] + if unsafe { ((*conn).bits).tls_enable_alpn() != 0 } { + let mut cur: i32 = 0 as i32; + let mut protocols: [u8; 128] = [0; 128]; + if cfg!(USE_HTTP2) { + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let CURL_DISABLE_PROXY_flag_1 = (!(CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32) + || ((*conn).bits).tunnel_proxy() == 0); + #[cfg(CURL_DISABLE_PROXY)] + let CURL_DISABLE_PROXY_flag_1 = true; + if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 + && CURL_DISABLE_PROXY_flag_1 + { + let fresh10 = cur; + cur = cur + 1; + protocols[fresh10 as usize] = 2 as u8; + memcpy( + &mut *protocols.as_mut_ptr().offset(cur as isize) as *mut u8 + as *mut libc::c_void, + b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, + 2 as u64, + ); + cur += 2 as i32; + Curl_infof( + data, + b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, + b"h2\0" as *const u8 as *const libc::c_char, + ); + } + } + } + let fresh11 = cur; + cur = cur + 1; + protocols[fresh11 as usize] = 8 as u8; + unsafe { + memcpy( + &mut *protocols.as_mut_ptr().offset(cur as isize) as *mut u8 as *mut libc::c_void, + b"http/1.1\0" as *const u8 as *const libc::c_char as *const libc::c_void, + 8 as u64, + ); + } + cur += 8 as i32; + unsafe { + Curl_infof( + data, + b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, + b"http/1.1\0" as *const u8 as *const libc::c_char, + ); + } + /* expects length prefixed preference ordered list of protocols in wire + * format + */ + if unsafe { SSL_CTX_set_alpn_protos((*backend).ctx, protocols.as_mut_ptr(), cur as u32) } + != 0 + { + unsafe { + Curl_failf( + data, + b"Error setting ALPN\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_SSL_CONNECT_ERROR; + } + } + + if !ssl_cert.is_null() || !ssl_cert_blob.is_null() || !ssl_cert_type.is_null() { + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let cert_stuff_flag = cert_stuff( + data, + (*backend).ctx, + ssl_cert, + ssl_cert_blob, + ssl_cert_type, + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key + } else { + (*data).set.ssl.key + }), + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key_blob + } else { + (*data).set.ssl.key_blob + }), + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key_type + } else { + (*data).set.ssl.key_type + }), + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key_passwd + } else { + (*data).set.ssl.key_passwd + }), + ); + #[cfg(CURL_DISABLE_PROXY)] + let cert_stuff_flag = cert_stuff( + data, + (*backend).ctx, + ssl_cert, + ssl_cert_blob, + ssl_cert_type, + (*data).set.ssl.key, + (*data).set.ssl.key_blob, + (*data).set.ssl.key_type, + (*data).set.ssl.key_passwd, + ); + if result as u64 == 0 && cert_stuff_flag == 0 { + result = CURLE_SSL_CERTPROBLEM; + } + if result as u64 != 0 { + /* failf() is already done in cert_stuff() */ + return result; + } + } + } + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_cipher_list = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.cipher_list + } else { + (*conn).ssl_config.cipher_list + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_cipher_list = (*conn).ssl_config.cipher_list; + ciphers = SSL_CONN_CONFIG_cipher_list; + if ciphers.is_null() { + ciphers = 0 as *mut libc::c_char; + } + if !ciphers.is_null() { + if SSL_CTX_set_cipher_list((*backend).ctx, ciphers) == 0 { + Curl_failf( + data, + b"failed setting cipher list: %s\0" as *const u8 as *const libc::c_char, + ciphers, + ); + return CURLE_SSL_CIPHER; + } + Curl_infof( + data, + b"Cipher selection: %s\0" as *const u8 as *const libc::c_char, + ciphers, + ); + } + + // *************************************************************** + #[cfg(all(HAVE_SSL_CTX_SET_CIPHERSUITES, not(CURL_DISABLE_PROXY)))] + let mut ciphers13: *mut libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.cipher_list13 + } else { + (*conn).ssl_config.cipher_list13 + }; + + #[cfg(all(HAVE_SSL_CTX_SET_CIPHERSUITES, CURL_DISABLE_PROXY))] + let mut ciphers13: *mut libc::c_char = (*conn).ssl_config.cipher_list13; + #[cfg(HAVE_SSL_CTX_SET_CIPHERSUITES)] + if !ciphers13.is_null() { + if SSL_CTX_set_ciphersuites((*backend).ctx, ciphers13) == 0 { + Curl_failf( + data, + b"failed setting TLS 1.3 cipher suite: %s\0" as *const u8 + as *const libc::c_char, + ciphers13, + ); + return CURLE_SSL_CIPHER; + } + Curl_infof( + data, + b"TLS 1.3 cipher selection: %s\0" as *const u8 as *const libc::c_char, + ciphers13, + ); + } + /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ + #[cfg(HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH)] + SSL_CTX_set_post_handshake_auth((*backend).ctx, 1 as i32); + #[cfg(all(HAVE_SSL_CTX_SET_EC_CURVES, not(CURL_DISABLE_PROXY)))] + let mut curves: *mut libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.curves + } else { + (*conn).ssl_config.curves + }; + #[cfg(all(HAVE_SSL_CTX_SET_EC_CURVES, CURL_DISABLE_PROXY))] + let mut curves: *mut libc::c_char = (*conn).ssl_config.curves; + #[cfg(HAVE_SSL_CTX_SET_EC_CURVES)] + if !curves.is_null() { + if SSL_CTX_ctrl( + (*backend).ctx, + 92 as i32, + 0 as i64, + curves as *mut libc::c_void, + ) == 0 + { + Curl_failf( + data, + b"failed setting curves list: '%s'\0" as *const u8 as *const libc::c_char, + curves, + ); + return CURLE_SSL_CIPHER; + } + } + // #[cfg(USE_OPENSSL_SRP)] + if ssl_authtype as u32 == CURL_TLSAUTH_SRP as u32 { + #[cfg(not(CURL_DISABLE_PROXY))] + let ssl_username: *mut libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }; + #[cfg(CURL_DISABLE_PROXY)] + let ssl_username: *mut libc::c_char = (*data).set.ssl.username; + Curl_infof( + data, + b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, + ssl_username, + ); + if SSL_CTX_set_srp_username((*backend).ctx, ssl_username) == 0 { + Curl_failf( + data, + b"Unable to set SRP user name\0" as *const u8 as *const libc::c_char, + ); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + #[cfg(not(CURL_DISABLE_PROXY))] + if SSL_CTX_set_srp_password( + (*backend).ctx, + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.password + } else { + (*data).set.ssl.password + }), + ) == 0 + { + Curl_failf( + data, + b"failed setting SRP password\0" as *const u8 as *const libc::c_char, + ); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + #[cfg(CURL_DISABLE_PROXY)] + if SSL_CTX_set_srp_password((*backend).ctx, (*data).set.ssl.password) == 0 { + Curl_failf( + data, + b"failed setting SRP password\0" as *const u8 as *const libc::c_char, + ); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + #[cfg(not(CURL_DISABLE_PROXY))] + if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.cipher_list + } else { + (*conn).ssl_config.cipher_list + } + .is_null() + { + Curl_infof( + data, + b"Setting cipher list SRP\0" as *const u8 as *const libc::c_char, + ); + if SSL_CTX_set_cipher_list( + (*backend).ctx, + b"SRP\0" as *const u8 as *const libc::c_char, + ) == 0 + { + Curl_failf( + data, + b"failed setting SRP cipher list\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CIPHER; + } + } + #[cfg(CURL_DISABLE_PROXY)] + if ((*conn).ssl_config.cipher_list).is_null() { + Curl_infof( + data, + b"Setting cipher list SRP\0" as *const u8 as *const libc::c_char, + ); + if SSL_CTX_set_cipher_list( + (*backend).ctx, + b"SRP\0" as *const u8 as *const libc::c_char, + ) == 0 + { + Curl_failf( + data, + b"failed setting SRP cipher list\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CIPHER; + } + } + } + } + if !ca_info_blob.is_null() { + result = unsafe { load_cacert_from_memory((*backend).ctx, ca_info_blob) }; + if result as u64 != 0 { + if result as u32 == CURLE_OUT_OF_MEMORY as u32 + || verifypeer as i32 != 0 && !imported_native_ca + { + /* Fail if we insist on successfully verifying the server. */ + unsafe { + Curl_failf( + data, + b"error importing CA certificate blob\0" as *const u8 + as *const libc::c_char, + ); + } + return result; + } + /* Continue with warning if certificate verification isn't required. */ + unsafe { + Curl_infof( + data, + b"error importing CA certificate blob, continuing anyway\0" as *const u8 + as *const libc::c_char, + ); + } + } + } + if !ssl_cafile.is_null() || !ssl_capath.is_null() { + /* tell SSL where to find CA certificates that are used to verify + the server's certificate. */ + if unsafe { SSL_CTX_load_verify_locations((*backend).ctx, ssl_cafile, ssl_capath) } == 0 { + if verifypeer as i32 != 0 && !imported_native_ca { + /* Fail if we insist on successfully verifying the server. */ + unsafe { + Curl_failf( + data, + b"error setting certificate verify locations: CAfile: %s CApath: %s\0" + as *const u8 as *const libc::c_char, + if !ssl_cafile.is_null() { + ssl_cafile + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + if !ssl_capath.is_null() { + ssl_capath + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + } + return CURLE_SSL_CACERT_BADFILE; + } + /* Just continue with a warning if no strict certificate verification + is required. */ + unsafe { + Curl_infof( + data, + b"error setting certificate verify locations, continuing anyway:\0" as *const u8 + as *const libc::c_char, + ); + } + } else { + /* Everything is fine. */ + unsafe { + Curl_infof( + data, + b"successfully set certificate verify locations:\0" as *const u8 + as *const libc::c_char, + ); + } + } + unsafe { + Curl_infof( + data, + b" CAfile: %s\0" as *const u8 as *const libc::c_char, + if !ssl_cafile.is_null() { + ssl_cafile + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + Curl_infof( + data, + b" CApath: %s\0" as *const u8 as *const libc::c_char, + if !ssl_capath.is_null() { + ssl_capath + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + } + } + + if !ssl_crlfile.is_null() { + /* tell OpenSSL where to find CRL file that is used to check certificate + * revocation */ + lookup = unsafe { + X509_STORE_add_lookup(SSL_CTX_get_cert_store((*backend).ctx), X509_LOOKUP_file()) + }; + if lookup.is_null() || unsafe { X509_load_crl_file(lookup, ssl_crlfile, 1 as i32) } == 0 { + unsafe { + Curl_failf( + data, + b"error loading CRL file: %s\0" as *const u8 as *const libc::c_char, + ssl_crlfile, + ); + } + return CURLE_SSL_CRL_BADFILE; + } + /* Everything is fine. */ + unsafe { + Curl_infof( + data, + b"successfully loaded CRL file:\0" as *const u8 as *const libc::c_char, + ); + X509_STORE_set_flags( + SSL_CTX_get_cert_store((*backend).ctx), + (0x4 as i32 | 0x8 as i32) as u64, + ); + Curl_infof( + data, + b" CRLfile: %s\0" as *const u8 as *const libc::c_char, + ssl_crlfile, + ); + } + } + if verifypeer { + /* Try building a chain using issuers in the trusted store first to avoid + problems with server-sent legacy intermediates. Newer versions of + OpenSSL do alternate chain checking by default but we do not know how to + determine that in a reliable manner. + https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest + */ + unsafe { + X509_STORE_set_flags(SSL_CTX_get_cert_store((*backend).ctx), 0x8000 as u64); + if ((*data).set.ssl).no_partialchain() == 0 && ssl_crlfile.is_null() { + /* Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert + only, instead of needing the whole chain. + + Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we + cannot do partial chains with a CRL check. + */ + X509_STORE_set_flags(SSL_CTX_get_cert_store((*backend).ctx), 0x80000 as u64); + } + } + } + /* OpenSSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue + * anyway. In the latter case the result of the verification is checked with + * SSL_get_verify_result() below. */ + unsafe { + SSL_CTX_set_verify( + (*backend).ctx, + if verifypeer as i32 != 0 { + 0x1 as i32 + } else { + 0 as i32 + }, + None, + ); + /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ + #[cfg(HAVE_KEYLOG_CALLBACK)] + if Curl_tls_keylog_enabled() { + SSL_CTX_set_keylog_callback( + (*backend).ctx, + Some( + ossl_keylog_callback + as unsafe extern "C" fn(*const SSL, *const libc::c_char) -> (), + ), + ); + } + SSL_CTX_ctrl( + (*backend).ctx, + 44 as i32, + (0x1 as i32 | (0x100 as i32 | 0x200 as i32)) as i64, + 0 as *mut libc::c_void, + ); + /* Enable the session cache because it's a prerequisite for the "new session" + * callback. Use the "external storage" mode to prevent OpenSSL from creating + * an internal session cache. */ - unsafe { - X509_STORE_set_flags(SSL_CTX_get_cert_store((*backend).ctx), 0x8000 as u64); - if ((*data).set.ssl).no_partialchain() == 0 && ssl_crlfile.is_null() { - /* Have intermediate certificates in the trust store be treated as - trust-anchors, in the same way as self-signed root CA certificates - are. This allows users to verify servers using the intermediate cert - only, instead of needing the whole chain. - - Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we - cannot do partial chains with a CRL check. - */ - X509_STORE_set_flags(SSL_CTX_get_cert_store((*backend).ctx), 0x80000 as u64); - } - } - } - /* OpenSSL always tries to verify the peer, this only says whether it should - * fail to connect if the verification fails, or if it should continue - * anyway. In the latter case the result of the verification is checked with - * SSL_get_verify_result() below. */ - unsafe { - SSL_CTX_set_verify( - (*backend).ctx, - if verifypeer as i32 != 0 { - 0x1 as i32 - } else { - 0 as i32 - }, - None, - ); - /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ - #[cfg(HAVE_KEYLOG_CALLBACK)] - if Curl_tls_keylog_enabled() { - SSL_CTX_set_keylog_callback( - (*backend).ctx, - Some( - ossl_keylog_callback - as unsafe extern "C" fn(*const SSL, *const libc::c_char) -> (), - ), - ); - } - SSL_CTX_ctrl( - (*backend).ctx, - 44 as i32, - (0x1 as i32 | (0x100 as i32 | 0x200 as i32)) as i64, - 0 as *mut libc::c_void, - ); - /* Enable the session cache because it's a prerequisite for the "new session" - * callback. Use the "external storage" mode to prevent OpenSSL from creating - * an internal session cache. - */ - SSL_CTX_sess_set_new_cb( - (*backend).ctx, - Some(ossl_new_session_cb as unsafe extern "C" fn(*mut SSL, *mut SSL_SESSION) -> i32), - ); - /* give application a chance to interfere with SSL set up. */ - if ((*data).set.ssl.fsslctx).is_some() { - Curl_set_in_callback(data, 1 as i32 != 0); - result = (Some(((*data).set.ssl.fsslctx).expect("non-null function pointer"))) - .expect("non-null function pointer")( - data, - (*backend).ctx as *mut libc::c_void, - (*data).set.ssl.fsslctxp, - ); - Curl_set_in_callback(data, 0 as i32 != 0); - if result as u64 != 0 { - Curl_failf( - data, - b"error signaled by ssl ctx callback\0" as *const u8 as *const libc::c_char, - ); - return result; - } - } - /* Let's make an SSL structure */ - if !((*backend).handle).is_null() { - SSL_free((*backend).handle); - } - (*backend).handle = SSL_new((*backend).ctx); - if ((*backend).handle).is_null() { - Curl_failf( - data, - b"SSL: couldn't create a context (handle)!\0" as *const u8 as *const libc::c_char, - ); - return CURLE_OUT_OF_MEMORY; - } - if ((*conn).ssl_config).verifystatus() != 0 { - SSL_ctrl( - (*backend).handle, - 65 as i32, - 1 as i64, - 0 as *mut libc::c_void, - ); - } - SSL_set_connect_state((*backend).handle); - (*backend).server_cert = 0 as *mut X509; - if 0 as i32 - == inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in_addr as *mut libc::c_void, - ) - && sni as i32 != 0 - { - let mut nlen: size_t = strlen(hostname); - if nlen as i64 >= (*data).set.buffer_size { - /* this is seriously messed up */ - return CURLE_SSL_CONNECT_ERROR; - } - /* RFC 6066 section 3 says the SNI field is case insensitive, but browsers - send the data lowercase and subsequently there are now numerous servers - out there that don't work unless the name is lowercased */ - Curl_strntolower((*data).state.buffer, hostname, nlen); - *((*data).state.buffer).offset(nlen as isize) = 0 as libc::c_char; - if SSL_ctrl( - (*backend).handle, - 55 as i32, - 0 as i64, - (*data).state.buffer as *mut libc::c_void, - ) == 0 - { - /* Informational message */ - Curl_infof( - data, - b"WARNING: failed to configure server name indication (SNI) TLS extension\0" - as *const u8 as *const libc::c_char, - ); - } - } - } - - ossl_associate_connection(data, conn, sockindex); - Curl_ssl_sessionid_lock(data); - if !Curl_ssl_getsessionid( - data, - conn, - if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0, - &mut ssl_sessionid, - 0 as *mut size_t, - sockindex, - ) { - unsafe { - /* we got a session id, use it! */ - if SSL_set_session((*backend).handle, ssl_sessionid as *mut SSL_SESSION) == 0 { - Curl_ssl_sessionid_unlock(data); - /* pass the raw socket into the SSL layers */ - Curl_failf( - data, - b"SSL: SSL_set_session failed: %s\0" as *const u8 as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - return CURLE_SSL_CONNECT_ERROR; - } - /* Informational message */ - Curl_infof( - data, - b"SSL re-using session ID\0" as *const u8 as *const libc::c_char, - ); - } - } - Curl_ssl_sessionid_unlock(data); - #[cfg(not(CURL_DISABLE_PROXY))] - if unsafe { ((*conn).proxy_ssl[sockindex as usize]).use_0() } != 0 { - let bio: *mut BIO = unsafe { BIO_new(BIO_f_ssl()) }; - let mut handle: *mut SSL = - unsafe { (*(*conn).proxy_ssl[sockindex as usize].backend).handle }; - unsafe { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ssl_connection_complete as u32 == (*conn).proxy_ssl[sockindex as usize].state as u32 - { - } else { - __assert_fail( + SSL_CTX_sess_set_new_cb( + (*backend).ctx, + Some(ossl_new_session_cb as unsafe extern "C" fn(*mut SSL, *mut SSL_SESSION) -> i32), + ); + /* give application a chance to interfere with SSL set up. */ + if ((*data).set.ssl.fsslctx).is_some() { + Curl_set_in_callback(data, 1 as i32 != 0); + result = (Some(((*data).set.ssl.fsslctx).expect("non-null function pointer"))) + .expect("non-null function pointer")( + data, + (*backend).ctx as *mut libc::c_void, + (*data).set.ssl.fsslctxp, + ); + Curl_set_in_callback(data, 0 as i32 != 0); + if result as u64 != 0 { + Curl_failf( + data, + b"error signaled by ssl ctx callback\0" as *const u8 as *const libc::c_char, + ); + return result; + } + } + /* Let's make an SSL structure */ + if !((*backend).handle).is_null() { + SSL_free((*backend).handle); + } + (*backend).handle = SSL_new((*backend).ctx); + if ((*backend).handle).is_null() { + Curl_failf( + data, + b"SSL: couldn't create a context (handle)!\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OUT_OF_MEMORY; + } + if ((*conn).ssl_config).verifystatus() != 0 { + SSL_ctrl( + (*backend).handle, + 65 as i32, + 1 as i64, + 0 as *mut libc::c_void, + ); + } + SSL_set_connect_state((*backend).handle); + (*backend).server_cert = 0 as *mut X509; + if 0 as i32 + == inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in_addr as *mut libc::c_void, + ) + && sni as i32 != 0 + { + let mut nlen: size_t = strlen(hostname); + if nlen as i64 >= (*data).set.buffer_size { + /* this is seriously messed up */ + return CURLE_SSL_CONNECT_ERROR; + } + /* RFC 6066 section 3 says the SNI field is case insensitive, but browsers + send the data lowercase and subsequently there are now numerous servers + out there that don't work unless the name is lowercased */ + Curl_strntolower((*data).state.buffer, hostname, nlen); + *((*data).state.buffer).offset(nlen as isize) = 0 as libc::c_char; + if SSL_ctrl( + (*backend).handle, + 55 as i32, + 0 as i64, + (*data).state.buffer as *mut libc::c_void, + ) == 0 + { + /* Informational message */ + Curl_infof( + data, + b"WARNING: failed to configure server name indication (SNI) TLS extension\0" + as *const u8 as *const libc::c_char, + ); + } + } + } + + ossl_associate_connection(data, conn, sockindex); + Curl_ssl_sessionid_lock(data); + if !Curl_ssl_getsessionid( + data, + conn, + if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0, + &mut ssl_sessionid, + 0 as *mut size_t, + sockindex, + ) { + unsafe { + /* we got a session id, use it! */ + if SSL_set_session((*backend).handle, ssl_sessionid as *mut SSL_SESSION) == 0 { + Curl_ssl_sessionid_unlock(data); + /* pass the raw socket into the SSL layers */ + Curl_failf( + data, + b"SSL: SSL_set_session failed: %s\0" as *const u8 as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + Curl_infof( + data, + b"SSL re-using session ID\0" as *const u8 as *const libc::c_char, + ); + } + } + Curl_ssl_sessionid_unlock(data); + #[cfg(not(CURL_DISABLE_PROXY))] + if unsafe { ((*conn).proxy_ssl[sockindex as usize]).use_0() } != 0 { + let bio: *mut BIO = unsafe { BIO_new(BIO_f_ssl()) }; + let mut handle: *mut SSL = + unsafe { (*(*conn).proxy_ssl[sockindex as usize].backend).handle }; + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ssl_connection_complete as u32 == (*conn).proxy_ssl[sockindex as usize].state as u32 + { + } else { + __assert_fail( b"ssl_connection_complete == conn->proxy_ssl[sockindex].state\0" as *const u8 as *const libc::c_char, b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, @@ -3991,11 +3991,11 @@ )) .as_ptr(), ); - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !handle.is_null() { - } else { - __assert_fail( + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !handle.is_null() { + } else { + __assert_fail( b"handle != ((void*)0)\0" as *const u8 as *const libc::c_char, b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, 3265 as u32, @@ -4004,11 +4004,11 @@ )) .as_ptr(), ); - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if !bio.is_null() { - } else { - __assert_fail( + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if !bio.is_null() { + } else { + __assert_fail( b"bio != ((void*)0)\0" as *const u8 as *const libc::c_char, b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, 3266 as u32, @@ -4017,26 +4017,26 @@ )) .as_ptr(), ); - } - BIO_ctrl(bio, 109 as i32, 0 as i64, handle as *mut libc::c_void); - SSL_set_bio((*backend).handle, bio, bio); - } - } else if unsafe { SSL_set_fd((*backend).handle, sockfd) == 0 } { - unsafe { - Curl_failf( - data, - b"SSL: SSL_set_fd failed: %s\0" as *const u8 as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - } - return CURLE_SSL_CONNECT_ERROR; - } + } + BIO_ctrl(bio, 109 as i32, 0 as i64, handle as *mut libc::c_void); + SSL_set_bio((*backend).handle, bio, bio); + } + } else if unsafe { SSL_set_fd((*backend).handle, sockfd) == 0 } { + unsafe { + Curl_failf( + data, + b"SSL: SSL_set_fd failed: %s\0" as *const u8 as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + return CURLE_SSL_CONNECT_ERROR; + } - unsafe { + unsafe { #[cfg(CURL_DISABLE_PROXY)] if SSL_set_fd((*backend).handle, sockfd) == 0 { /* pass the raw socket into the SSL layers */ @@ -4049,32 +4049,32 @@ ::std::mem::size_of::<[libc::c_char; 256]>() as u64, ), ); - return CURLE_SSL_CONNECT_ERROR; + return CURLE_SSL_CONNECT_ERROR; + } + (*connssl).connecting_state = ssl_connect_2; } - (*connssl).connecting_state = ssl_connect_2; - } - return CURLE_OK; - } - - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_connect_step2( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) -> CURLcode { - let mut err: i32 = 0; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } - as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - unsafe { - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ssl_connect_2 as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 - { - } else { - __assert_fail( + return CURLE_OK; +} + +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_connect_step2( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut err: i32 = 0; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } + as *mut ssl_connect_data; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ssl_connect_2 as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 + { + } else { + __assert_fail( b"ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state || ssl_connect_2_writing == connssl->connecting_state\0" as *const u8 as *const libc::c_char, b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, @@ -4087,2435 +4087,2434 @@ )) .as_ptr(), ); - } - ERR_clear_error(); - - err = SSL_connect((*backend).handle); - } - /* 1 is fine - 0 is "not successful but was shut down controlled" - <0 is "handshake was not successful, because a fatal error occurred" */ - // TODO - // #[cfg(HAVE_KEYLOG_CALLBACK)] - if 1 as i32 != err { - let mut detail: i32 = unsafe { SSL_get_error((*backend).handle, err) }; - if 2 as i32 == detail { - unsafe { - (*connssl).connecting_state = ssl_connect_2_reading; - } - return CURLE_OK; - } - if 3 as i32 == detail { - unsafe { - (*connssl).connecting_state = ssl_connect_2_writing; - } - return CURLE_OK; - } - // TODO if的条件编译 - #[cfg(SSL_ERROR_WANT_ASYNC)] - let SSL_ERROR_WANT_ASYNC_flag_3 = true; - #[cfg(not(SSL_ERROR_WANT_ASYNC))] - let SSL_ERROR_WANT_ASYNC_flag_3 = false; - if 9 as i32 == detail && SSL_ERROR_WANT_ASYNC_flag_3 { - unsafe { - (*connssl).connecting_state = ssl_connect_2; - } - return CURLE_OK; - } else { - /* untreated error */ - let mut errdetail: u64 = 0; - let mut error_buffer: [libc::c_char; 256] = unsafe { - *::std::mem::transmute::< + } + ERR_clear_error(); + + err = SSL_connect((*backend).handle); + } + /* 1 is fine + 0 is "not successful but was shut down controlled" + <0 is "handshake was not successful, because a fatal error occurred" */ + // TODO + // #[cfg(HAVE_KEYLOG_CALLBACK)] + if 1 as i32 != err { + let mut detail: i32 = unsafe { SSL_get_error((*backend).handle, err) }; + if 2 as i32 == detail { + unsafe { + (*connssl).connecting_state = ssl_connect_2_reading; + } + return CURLE_OK; + } + if 3 as i32 == detail { + unsafe { + (*connssl).connecting_state = ssl_connect_2_writing; + } + return CURLE_OK; + } + // TODO if的条件编译 + #[cfg(SSL_ERROR_WANT_ASYNC)] + let SSL_ERROR_WANT_ASYNC_flag_3 = true; + #[cfg(not(SSL_ERROR_WANT_ASYNC))] + let SSL_ERROR_WANT_ASYNC_flag_3 = false; + if 9 as i32 == detail && SSL_ERROR_WANT_ASYNC_flag_3 { + unsafe { + (*connssl).connecting_state = ssl_connect_2; + } + return CURLE_OK; + } else { + /* untreated error */ + let mut errdetail: u64 = 0; + let mut error_buffer: [libc::c_char; 256] = unsafe { + *::std::mem::transmute::< &[u8; 256], &mut [libc::c_char; 256], >( b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", ) - }; - let mut result: CURLcode = CURLE_OK; - let mut lerr: i64 = 0; - let mut lib: i32 = 0; - let mut reason: i32 = 0; - /* the connection failed, we're not waiting for anything else. */ - unsafe { - (*connssl).connecting_state = ssl_connect_2; - } - /* Get the earliest error code from the thread's error queue and remove - the entry. */ - errdetail = unsafe { ERR_get_error() }; - /* Extract which lib and reason */ - lib = (errdetail >> 24 as i64 & 0xff as i64 as u64) as i32; - reason = (errdetail & 0xfff as u64) as i32; - if lib == 20 as i32 && (reason == 134 as i32 || reason == 1045 as i32) { - result = CURLE_PEER_FAILED_VERIFICATION; - lerr = unsafe { SSL_get_verify_result((*backend).handle) }; - if lerr != 0 as i64 { - #[cfg(not(CURL_DISABLE_PROXY))] - if true { - *if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) - as usize] - .state as u32 - } - { - unsafe { &mut (*data).set.proxy_ssl.certverifyresult } - } else { - unsafe { &mut (*data).set.ssl.certverifyresult } - } = lerr; - } - #[cfg(CURL_DISABLE_PROXY)] - if true { - unsafe { - (*data).set.ssl.certverifyresult = lerr; - } - } - unsafe { - curl_msnprintf( - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - b"SSL certificate problem: %s\0" as *const u8 as *const libc::c_char, - X509_verify_cert_error_string(lerr), - ); - } - } else { - /* strcpy() is fine here as long as the string fits within - error_buffer */ - unsafe { - strcpy( - error_buffer.as_mut_ptr(), - b"SSL certificate verification failed\0" as *const u8 - as *const libc::c_char, - ); - } - } - // else if的条件编译 - /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on - OpenSSL version above v1.1.1, not LibreSSL nor BoringSSL */ - } else if lib == 20 as i32 && reason == 1116 as i32 { - /* If client certificate is required, communicate the - error to client */ - result = CURLE_SSL_CLIENTCERT; - ossl_strerror( - errdetail, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } else { - result = CURLE_SSL_CONNECT_ERROR; - ossl_strerror( - errdetail, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - /* detail is already set to the SSL error above */ - - /* If we e.g. use SSLv2 request-method and the server doesn't like us - * (RST connection, etc.), OpenSSL gives no explanation whatsoever and - * the SO_ERROR is also lost. - */ - if CURLE_SSL_CONNECT_ERROR as u32 == result as u32 && errdetail == 0 as u64 { - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).http_proxy.host.name - } else { - (*conn).host.name - }; - #[cfg(CURL_DISABLE_PROXY)] - let hostname: *const libc::c_char = (*conn).host.name; - #[cfg(not(CURL_DISABLE_PROXY))] - let port: i64 = (if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).port - } else { - (*conn).remote_port - }) as i64; - #[cfg(CURL_DISABLE_PROXY)] - let port: i64 = (*conn).remote_port as i64; - let mut extramsg: [libc::c_char; 80] = *::std::mem::transmute::< + }; + let mut result: CURLcode = CURLE_OK; + let mut lerr: i64 = 0; + let mut lib: i32 = 0; + let mut reason: i32 = 0; + /* the connection failed, we're not waiting for anything else. */ + unsafe { + (*connssl).connecting_state = ssl_connect_2; + } + /* Get the earliest error code from the thread's error queue and remove + the entry. */ + errdetail = unsafe { ERR_get_error() }; + /* Extract which lib and reason */ + lib = (errdetail >> 24 as i64 & 0xff as i64 as u64) as i32; + reason = (errdetail & 0xfff as u64) as i32; + if lib == 20 as i32 && (reason == 134 as i32 || reason == 1045 as i32) { + result = CURLE_PEER_FAILED_VERIFICATION; + lerr = unsafe { SSL_get_verify_result((*backend).handle) }; + if lerr != 0 as i64 { + #[cfg(not(CURL_DISABLE_PROXY))] + if true { + *if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) + as usize] + .state as u32 + } + { + unsafe { &mut (*data).set.proxy_ssl.certverifyresult } + } else { + unsafe { &mut (*data).set.ssl.certverifyresult } + } = lerr; + } + #[cfg(CURL_DISABLE_PROXY)] + if true { + unsafe { + (*data).set.ssl.certverifyresult = lerr; + } + } + unsafe { + curl_msnprintf( + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + b"SSL certificate problem: %s\0" as *const u8 as *const libc::c_char, + X509_verify_cert_error_string(lerr), + ); + } + } else { + /* strcpy() is fine here as long as the string fits within + error_buffer */ + unsafe { + strcpy( + error_buffer.as_mut_ptr(), + b"SSL certificate verification failed\0" as *const u8 + as *const libc::c_char, + ); + } + } + // else if的条件编译 + /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on + OpenSSL version above v1.1.1, not LibreSSL nor BoringSSL */ + } else if lib == 20 as i32 && reason == 1116 as i32 { + /* If client certificate is required, communicate the + error to client */ + result = CURLE_SSL_CLIENTCERT; + ossl_strerror( + errdetail, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } else { + result = CURLE_SSL_CONNECT_ERROR; + ossl_strerror( + errdetail, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + /* detail is already set to the SSL error above */ + + /* If we e.g. use SSLv2 request-method and the server doesn't like us + * (RST connection, etc.), OpenSSL gives no explanation whatsoever and + * the SO_ERROR is also lost. + */ + if CURLE_SSL_CONNECT_ERROR as u32 == result as u32 && errdetail == 0 as u64 { + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).http_proxy.host.name + } else { + (*conn).host.name + }; + #[cfg(CURL_DISABLE_PROXY)] + let hostname: *const libc::c_char = (*conn).host.name; + #[cfg(not(CURL_DISABLE_PROXY))] + let port: i64 = (if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).port + } else { + (*conn).remote_port + }) as i64; + #[cfg(CURL_DISABLE_PROXY)] + let port: i64 = (*conn).remote_port as i64; + let mut extramsg: [libc::c_char; 80] = *::std::mem::transmute::< &[u8; 80], &mut [libc::c_char; 80], >( b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", ); - let mut sockerr: i32 = *__errno_location(); - if sockerr != 0 && detail == 5 as i32 { - Curl_strerror( - sockerr, - extramsg.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 80]>() as u64, - ); - } - Curl_failf( - data, - b"OpenSSL SSL_connect: %s in connection to %s:%ld \0" as *const u8 - as *const libc::c_char, - if extramsg[0 as usize] as i32 != 0 { - extramsg.as_mut_ptr() as *const libc::c_char - } else { - SSL_ERROR_to_str(detail) - }, - hostname, - port, - ); - } - return result; - } - /* Could be a CERT problem */ - unsafe { - Curl_failf( - data, - b"%s\0" as *const u8 as *const libc::c_char, - error_buffer.as_mut_ptr(), - ); - } - return result; - } - } else { - unsafe { - /* we connected fine, we're not waiting for anything else. */ - (*connssl).connecting_state = ssl_connect_3; - /* Informational message */ - Curl_infof( - data, - b"SSL connection using %s / %s\0" as *const u8 as *const libc::c_char, - SSL_get_version((*backend).handle), - SSL_CIPHER_get_name(SSL_get_current_cipher((*backend).handle)), - ); - /* Sets data and len to negotiated protocol, len is 0 if no protocol was - * negotiated - */ - #[cfg(HAS_APLN)] - if ((*conn).bits).tls_enable_alpn() != 0 { - let mut neg_protocol: *const u8 = 0 as *const u8; - let mut len: u32 = 0; - SSL_get0_alpn_selected((*backend).handle, &mut neg_protocol, &mut len); - if len != 0 { - Curl_infof( - data, - b"ALPN, server accepted to use %.*s\0" as *const u8 as *const libc::c_char, - len, - neg_protocol, - ); - // TODO if的条件编译 - #[cfg(USE_HTTP2)] - let USE_HTTP2_flag = true; - #[cfg(not(USE_HTTP2))] - let USE_HTTP2_flag = false; - if len == 2 as u32 - && USE_HTTP2_flag - && memcmp( - b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, - neg_protocol as *const libc::c_void, - len as u64, - ) == 0 - { - (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; - } else if len == 8 as u32 - && memcmp( - b"http/1.1\0" as *const u8 as *const libc::c_char - as *const libc::c_void, - neg_protocol as *const libc::c_void, - 8 as u64, - ) == 0 - { - (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; - } - } else { - Curl_infof( - data, - b"ALPN, server did not agree to a protocol\0" as *const u8 - as *const libc::c_char, - ); - } - Curl_multiuse_state( - data, - if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as i32 { - 2 as i32 - } else { - -(1 as i32) - }, - ); - } - } - return CURLE_OK; - }; - } - - #[cfg(USE_OPENSSL)] - extern "C" fn asn1_object_dump( - mut a: *mut ASN1_OBJECT, - mut buf: *mut libc::c_char, - mut len: size_t, - ) -> i32 { - let mut i: i32 = 0; - let mut ilen: i32 = 0; - ilen = len as i32; - if ilen < 0 as i32 { - return 1 as i32; /* buffer too big */ - } - i = unsafe { i2t_ASN1_OBJECT(buf, ilen, a) }; - if i >= ilen { - return 1 as i32; /* buffer too small */ - } - return 0 as i32; - } - // TODO-3474-参数列表有条件编译 - #[cfg(all(USE_OPENSSL, HAVE_OPAQUE_RSA_DSA_DH))] - extern "C" fn pubkey_show( - mut data: *mut Curl_easy, - mut mem: *mut BIO, - mut num: i32, - mut type_0: *const libc::c_char, - mut name: *const libc::c_char, - mut bn: *const BIGNUM, - ) { - let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; - let mut namebuf: [libc::c_char; 32] = [0; 32]; - unsafe { - curl_msnprintf( - namebuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 32]>() as u64, - b"%s(%s)\0" as *const u8 as *const libc::c_char, - type_0, - name, - ); - } - if !bn.is_null() { - unsafe { - BN_print(mem, bn); - } - } - let mut info_len: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len(data, num, namebuf.as_mut_ptr(), ptr, info_len as size_t); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - } - - #[cfg(USE_OPENSSL)] - extern "C" fn X509V3_ext( - mut data: *mut Curl_easy, - mut certnum: i32, - mut exts: *const stack_st_X509_EXTENSION, - ) { - let mut i: i32 = 0; - if sk_X509_EXTENSION_num(exts) <= 0 as i32 { - /* no extensions, bail out */ - return; - } - i = 0 as i32; - while i < sk_X509_EXTENSION_num(exts) { - let mut obj: *mut ASN1_OBJECT = 0 as *mut ASN1_OBJECT; - let mut ext: *mut X509_EXTENSION = sk_X509_EXTENSION_value(exts, i); - let mut biomem: *mut BUF_MEM = 0 as *mut BUF_MEM; - let mut namebuf: [libc::c_char; 128] = [0; 128]; - let mut bio_out: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; - if bio_out.is_null() { - return; - } - obj = unsafe { X509_EXTENSION_get_object(ext) }; - asn1_object_dump( - obj, - namebuf.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 128]>() as u64, - ); - if unsafe { X509V3_EXT_print(bio_out, ext, 0 as u64, 0 as i32) } == 0 { - unsafe { ASN1_STRING_print(bio_out, X509_EXTENSION_get_data(ext) as *mut ASN1_STRING) }; - } - unsafe { - BIO_ctrl( - bio_out, - 115 as i32, - 0 as i64, - &mut biomem as *mut *mut BUF_MEM as *mut libc::c_char as *mut libc::c_void, - ); - Curl_ssl_push_certinfo_len( - data, - certnum, - namebuf.as_mut_ptr(), - (*biomem).data, - (*biomem).length, - ); - BIO_free(bio_out); - } - i += 1; - } - } - - #[cfg(USE_OPENSSL)] - extern "C" fn get_cert_chain( - mut data: *mut Curl_easy, - mut connssl: *mut ssl_connect_data, - ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut sk: *mut stack_st_X509 = 0 as *mut stack_st_X509; - let mut i: i32 = 0; - let mut numcerts: numcert_t = 0; - let mut mem: *mut BIO = 0 as *mut BIO; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - sk = unsafe { SSL_get_peer_cert_chain((*backend).handle) }; - if sk.is_null() { - return CURLE_OUT_OF_MEMORY; - } - numcerts = sk_X509_num(sk); - result = Curl_ssl_init_certinfo(data, numcerts); - if result as u64 != 0 { - return result; - } - mem = unsafe { BIO_new(BIO_s_mem()) }; - i = 0 as i32; - while i < numcerts { - let mut num: *mut ASN1_INTEGER = 0 as *mut ASN1_INTEGER; - let mut x: *mut X509 = sk_X509_value(sk, i); - let mut pubkey: *mut EVP_PKEY = 0 as *mut EVP_PKEY; - let mut j: i32 = 0; - let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; - let mut psig: *const ASN1_BIT_STRING = 0 as *const ASN1_BIT_STRING; - unsafe { - X509_NAME_print_ex( - mem, - X509_get_subject_name(x), - 0 as i32, - (1 as i32 - | 2 as i32 - | 4 as i32 - | 0x10 as i32 - | 0x100 as i32 - | 0x200 as i32 - | 8 as i32 - | (2 as i32) << 16 as i32 - | (1 as i32) << 23 as i32 - | 0 as i32) as u64, - ); - let mut info_len: i64 = BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ); - - Curl_ssl_push_certinfo_len( - data, - i, - b"Subject\0" as *const u8 as *const libc::c_char, - ptr, - info_len as size_t, - ); - } - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - unsafe { - X509_NAME_print_ex( - mem, - X509_get_issuer_name(x), - 0 as i32, - (1 as i32 - | 2 as i32 - | 4 as i32 - | 0x10 as i32 - | 0x100 as i32 - | 0x200 as i32 - | 8 as i32 - | (2 as i32) << 16 as i32 - | (1 as i32) << 23 as i32 - | 0 as i32) as u64, - ); - } - let mut info_len_0: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Issuer\0" as *const u8 as *const libc::c_char, - ptr, - info_len_0 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - unsafe { - BIO_printf( - mem, - b"%lx\0" as *const u8 as *const libc::c_char, - X509_get_version(x), - ); - } - let mut info_len_1: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Version\0" as *const u8 as *const libc::c_char, - ptr, - info_len_1 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - num = unsafe { X509_get_serialNumber(x) }; - if unsafe { (*num).type_0 } == 2 as i32 | 0x100 as i32 { - unsafe { - BIO_puts(mem, b"-\0" as *const u8 as *const libc::c_char); - } - } - j = 0 as i32; - while j < unsafe { (*num).length } { - unsafe { - BIO_printf( - mem, - b"%02x\0" as *const u8 as *const libc::c_char, - *((*num).data).offset(j as isize) as i32, - ); - } - j += 1; - } - let mut info_len_2: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Serial Number\0" as *const u8 as *const libc::c_char, - ptr, - info_len_2 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - - if cfg!(all(HAVE_X509_GET0_SIGNATURE, HAVE_X509_GET0_EXTENSIONS)) { - let mut sigalg: *const X509_ALGOR = 0 as *const X509_ALGOR; - let mut xpubkey: *mut X509_PUBKEY = 0 as *mut X509_PUBKEY; - let mut pubkeyoid: *mut ASN1_OBJECT = 0 as *mut ASN1_OBJECT; - unsafe { - X509_get0_signature(&mut psig, &mut sigalg, x); - } - if !sigalg.is_null() { - unsafe { - i2a_ASN1_OBJECT(mem, (*sigalg).algorithm); - } - let mut info_len_3: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Signature Algorithm\0" as *const u8 as *const libc::c_char, - ptr, - info_len_3 as size_t, - ); - 1 as i32 - != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - } - xpubkey = unsafe { X509_get_X509_PUBKEY(x) }; - if !xpubkey.is_null() { - unsafe { - X509_PUBKEY_get0_param( - &mut pubkeyoid, - 0 as *mut *const u8, - 0 as *mut i32, - 0 as *mut *mut X509_ALGOR, - xpubkey, - ); - if !pubkeyoid.is_null() { - i2a_ASN1_OBJECT(mem, pubkeyoid); - let mut info_len_4: i64 = BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ); - Curl_ssl_push_certinfo_len( - data, - i, - b"Public Key Algorithm\0" as *const u8 as *const libc::c_char, - ptr, - info_len_4 as size_t, - ); - 1 as i32 - != BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32; - } - } - } - unsafe { - X509V3_ext(data, i, X509_get0_extensions(x)); - } - } else { - // before OpenSSL 1.0.2 - } - unsafe { - ASN1_TIME_print(mem, X509_get0_notBefore(x)); - } - let mut info_len_5: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Start date\0" as *const u8 as *const libc::c_char, - ptr, - info_len_5 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - unsafe { - ASN1_TIME_print(mem, X509_get0_notAfter(x)); - } - let mut info_len_6: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Expire date\0" as *const u8 as *const libc::c_char, - ptr, - info_len_6 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - - pubkey = unsafe { X509_get_pubkey(x) }; - if pubkey.is_null() { - unsafe { - Curl_infof( - data, - b" Unable to load public key\0" as *const u8 as *const libc::c_char, - ); - } - } else { - let mut pktype: i32 = 0; - match () { - #[cfg(HAVE_OPAQUE_EVP_PKEY)] - _ => { - pktype = unsafe { EVP_PKEY_id(pubkey) }; - } - #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - _ => {} - } - // #[cfg(HAVE_OPAQUE_EVP_PKEY)] - // pktype = EVP_PKEY_id(pubkey); - // TODO - 3652 - // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - match pktype { - 6 => { - #[cfg(HAVE_OPAQUE_EVP_PKEY)] - let mut rsa: *mut RSA = unsafe { EVP_PKEY_get0_RSA(pubkey) }; - // TODO - 3652 - // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] - if true { - let mut n: *const BIGNUM = 0 as *const BIGNUM; - let mut e: *const BIGNUM = 0 as *const BIGNUM; - unsafe { - RSA_get0_key(rsa, &mut n, &mut e, 0 as *mut *const BIGNUM); - } - - BIO_printf( - mem, - b"%d\0" as *const u8 as *const libc::c_char, - BN_num_bits(n), - ); - - let mut info_len_7: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ) - }; - unsafe { - Curl_ssl_push_certinfo_len( - data, - i, - b"RSA Public Key\0" as *const u8 as *const libc::c_char, - ptr, - info_len_7 as size_t, - ); - } - 1 as i32 - != unsafe { - BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 - }; - unsafe { - pubkey_show( - data, - mem, - i, - b"rsa\0" as *const u8 as *const libc::c_char, - b"n\0" as *const u8 as *const libc::c_char, - n, - ); - pubkey_show( - data, - mem, - i, - b"rsa\0" as *const u8 as *const libc::c_char, - b"e\0" as *const u8 as *const libc::c_char, - e, - ); - } - } - #[cfg(not(HAVE_OPAQUE_RSA_DSA_DH))] - if true { - // TODO - 3678 - } - } - 116 => { - if cfg!(not(OPENSSL_NO_DSA)) { - #[cfg(HAVE_OPAQUE_EVP_PKEY)] - let mut dsa: *mut DSA = unsafe { EVP_PKEY_get0_DSA(pubkey) }; - // TODO - 3691 - // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] - if true { - let mut p: *const BIGNUM = 0 as *const BIGNUM; - let mut q: *const BIGNUM = 0 as *const BIGNUM; - let mut g: *const BIGNUM = 0 as *const BIGNUM; - let mut pub_key: *const BIGNUM = 0 as *const BIGNUM; - unsafe { - DSA_get0_pqg(dsa, &mut p, &mut q, &mut g); - DSA_get0_key(dsa, &mut pub_key, 0 as *mut *const BIGNUM); - pubkey_show( - data, - mem, - i, - b"dsa\0" as *const u8 as *const libc::c_char, - b"p\0" as *const u8 as *const libc::c_char, - p, - ); - pubkey_show( - data, - mem, - i, - b"dsa\0" as *const u8 as *const libc::c_char, - b"q\0" as *const u8 as *const libc::c_char, - q, - ); - pubkey_show( - data, - mem, - i, - b"dsa\0" as *const u8 as *const libc::c_char, - b"g\0" as *const u8 as *const libc::c_char, - g, - ); - pubkey_show( - data, - mem, - i, - b"dsa\0" as *const u8 as *const libc::c_char, - b"pub_key\0" as *const u8 as *const libc::c_char, - pub_key, - ); - } - } - #[cfg(not(HAVE_OPAQUE_RSA_DSA_DH))] - if true { - // cfg!(not(HAVE_OPAQUE_RSA_DSA_DH)) - } - } - } - 28 => { - #[cfg(HAVE_OPAQUE_EVP_PKEY)] - let mut dh: *mut DH = unsafe { EVP_PKEY_get0_DH(pubkey) }; - // TODO - // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] - if true { - let mut p_0: *const BIGNUM = 0 as *const BIGNUM; - let mut q_0: *const BIGNUM = 0 as *const BIGNUM; - let mut g_0: *const BIGNUM = 0 as *const BIGNUM; - let mut pub_key_0: *const BIGNUM = 0 as *const BIGNUM; - unsafe { - DH_get0_pqg(dh, &mut p_0, &mut q_0, &mut g_0); - DH_get0_key(dh, &mut pub_key_0, 0 as *mut *const BIGNUM); - pubkey_show( - data, - mem, - i, - b"dh\0" as *const u8 as *const libc::c_char, - b"p\0" as *const u8 as *const libc::c_char, - p_0, - ); - pubkey_show( - data, - mem, - i, - b"dh\0" as *const u8 as *const libc::c_char, - b"q\0" as *const u8 as *const libc::c_char, - q_0, - ); - pubkey_show( - data, - mem, - i, - b"dh\0" as *const u8 as *const libc::c_char, - b"g\0" as *const u8 as *const libc::c_char, - g_0, - ); - pubkey_show( - data, - mem, - i, - b"dh\0" as *const u8 as *const libc::c_char, - b"pub_key\0" as *const u8 as *const libc::c_char, - pub_key_0, - ); - } - } - // TODO - #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] - if true { - // TODO - 3471 - } - } - _ => {} - } - unsafe { - EVP_PKEY_free(pubkey); - } - } - if !psig.is_null() { - j = 0 as i32; - while j < unsafe { (*psig).length } { - unsafe { - BIO_printf( - mem, - b"%02x:\0" as *const u8 as *const libc::c_char, - *((*psig).data).offset(j as isize) as i32, - ); - } - j += 1; - } - let mut info_len_8: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Signature\0" as *const u8 as *const libc::c_char, - ptr, - info_len_8 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - } - unsafe { - PEM_write_bio_X509(mem, x); - } - let mut info_len_9: i64 = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, - ) - }; - Curl_ssl_push_certinfo_len( - data, - i, - b"Cert\0" as *const u8 as *const libc::c_char, - ptr, - info_len_9 as size_t, - ); - 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; - i += 1; - } - unsafe { - BIO_free(mem); - } - return CURLE_OK; - } - - /* - * Heavily modified from: - * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL - */ - #[cfg(USE_OPENSSL)] - extern "C" fn pkp_pin_peer_pubkey( - mut data: *mut Curl_easy, - mut cert: *mut X509, - mut pinnedpubkey: *const libc::c_char, - ) -> CURLcode { - /* Scratch */ - let mut len1: i32 = 0 as i32; - let mut len2: i32 = 0 as i32; - let mut buff1: *mut u8 = 0 as *mut u8; - let mut temp: *mut u8 = 0 as *mut u8; - /* Result is returned to caller */ - let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - /* if a path wasn't specified, don't pin */ - if pinnedpubkey.is_null() { - return CURLE_OK; - } - if cert.is_null() { - return result; - } - /* Begin Gyrations to get the subjectPublicKeyInfo */ - /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */ - len1 = unsafe { i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), 0 as *mut *mut u8) }; - if !(len1 < 1 as i32) { - match () { - #[cfg(not(CURLDEBUG))] - _ => { - temp = unsafe { - Curl_cmalloc.expect("non-null function pointer")(len1 as size_t) as *mut u8 - }; - } - #[cfg(CURLDEBUG)] - _ => { - temp = unsafe { - curl_dbg_malloc( - len1 as size_t, - 3798 as i32, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - ) - } as *mut u8; - } - } - buff1 = temp; - if !buff1.is_null() { - len2 = unsafe { i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &mut temp) }; - /* - * These checks are verifying we got back the same values as when we - * sized the buffer. It's pretty weak since they should always be the - * same. But it gives us something to test. - */ - if !(len1 != len2 - || temp.is_null() - || unsafe { temp.offset_from(buff1) } as i64 != len1 as i64) - { - /* End Gyrations */ - - /* The one good exit point */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1 as size_t); - } - } - } - if !buff1.is_null() { - #[cfg(not(CURLDEBUG))] - unsafe { - Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void); - } - - #[cfg(CURLDEBUG)] - unsafe { - curl_dbg_free( - buff1 as *mut libc::c_void, - 3820 as i32, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - ); - } - } - return result; - } - - /* - * Get the server cert, verify it and show it, etc., only call failf() if the - * 'strict' argument is TRUE as otherwise all this is for informational - * purposes only! - * - * We check certificates to authenticate the server; otherwise we risk - * man-in-the-middle attack. - */ - #[cfg(USE_OPENSSL)] - extern "C" fn servercert( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut connssl: *mut ssl_connect_data, - mut strict: bool, - ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut rc: i32 = 0; - let mut lerr: i64 = 0; - let mut issuer: *mut X509 = 0 as *mut X509; - let mut fp: *mut BIO = 0 as *mut BIO; - let mut error_buffer: [libc::c_char; 256] = unsafe { - *::std::mem::transmute::< + let mut sockerr: i32 = *__errno_location(); + if sockerr != 0 && detail == 5 as i32 { + Curl_strerror( + sockerr, + extramsg.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 80]>() as u64, + ); + } + Curl_failf( + data, + b"OpenSSL SSL_connect: %s in connection to %s:%ld \0" as *const u8 + as *const libc::c_char, + if extramsg[0 as usize] as i32 != 0 { + extramsg.as_mut_ptr() as *const libc::c_char + } else { + SSL_ERROR_to_str(detail) + }, + hostname, + port, + ); + } + return result; + } + /* Could be a CERT problem */ + unsafe { + Curl_failf( + data, + b"%s\0" as *const u8 as *const libc::c_char, + error_buffer.as_mut_ptr(), + ); + } + return result; + } + } else { + unsafe { + /* we connected fine, we're not waiting for anything else. */ + (*connssl).connecting_state = ssl_connect_3; + /* Informational message */ + Curl_infof( + data, + b"SSL connection using %s / %s\0" as *const u8 as *const libc::c_char, + SSL_get_version((*backend).handle), + SSL_CIPHER_get_name(SSL_get_current_cipher((*backend).handle)), + ); + /* Sets data and len to negotiated protocol, len is 0 if no protocol was + * negotiated + */ + #[cfg(HAS_APLN)] + if ((*conn).bits).tls_enable_alpn() != 0 { + let mut neg_protocol: *const u8 = 0 as *const u8; + let mut len: u32 = 0; + SSL_get0_alpn_selected((*backend).handle, &mut neg_protocol, &mut len); + if len != 0 { + Curl_infof( + data, + b"ALPN, server accepted to use %.*s\0" as *const u8 as *const libc::c_char, + len, + neg_protocol, + ); + // TODO if的条件编译 + #[cfg(USE_HTTP2)] + let USE_HTTP2_flag = true; + #[cfg(not(USE_HTTP2))] + let USE_HTTP2_flag = false; + if len == 2 as u32 + && USE_HTTP2_flag + && memcmp( + b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, + neg_protocol as *const libc::c_void, + len as u64, + ) == 0 + { + (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; + } else if len == 8 as u32 + && memcmp( + b"http/1.1\0" as *const u8 as *const libc::c_char + as *const libc::c_void, + neg_protocol as *const libc::c_void, + 8 as u64, + ) == 0 + { + (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; + } + } else { + Curl_infof( + data, + b"ALPN, server did not agree to a protocol\0" as *const u8 + as *const libc::c_char, + ); + } + Curl_multiuse_state( + data, + if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as i32 { + 2 as i32 + } else { + -(1 as i32) + }, + ); + } + } + return CURLE_OK; + }; +} + +#[cfg(USE_OPENSSL)] +extern "C" fn asn1_object_dump( + mut a: *mut ASN1_OBJECT, + mut buf: *mut libc::c_char, + mut len: size_t, +) -> i32 { + let mut i: i32 = 0; + let mut ilen: i32 = 0; + ilen = len as i32; + if ilen < 0 as i32 { + return 1 as i32; /* buffer too big */ + } + i = unsafe { i2t_ASN1_OBJECT(buf, ilen, a) }; + if i >= ilen { + return 1 as i32; /* buffer too small */ + } + return 0 as i32; +} +// TODO-3474-参数列表有条件编译 +#[cfg(all(USE_OPENSSL, HAVE_OPAQUE_RSA_DSA_DH))] +extern "C" fn pubkey_show( + mut data: *mut Curl_easy, + mut mem: *mut BIO, + mut num: i32, + mut type_0: *const libc::c_char, + mut name: *const libc::c_char, + mut bn: *const BIGNUM, +) { + let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut namebuf: [libc::c_char; 32] = [0; 32]; + unsafe { + curl_msnprintf( + namebuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 32]>() as u64, + b"%s(%s)\0" as *const u8 as *const libc::c_char, + type_0, + name, + ); + } + if !bn.is_null() { + unsafe { + BN_print(mem, bn); + } + } + let mut info_len: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len(data, num, namebuf.as_mut_ptr(), ptr, info_len as size_t); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; +} + +#[cfg(USE_OPENSSL)] +extern "C" fn X509V3_ext( + mut data: *mut Curl_easy, + mut certnum: i32, + mut exts: *const stack_st_X509_EXTENSION, +) { + let mut i: i32 = 0; + if sk_X509_EXTENSION_num(exts) <= 0 as i32 { + /* no extensions, bail out */ + return; + } + i = 0 as i32; + while i < sk_X509_EXTENSION_num(exts) { + let mut obj: *mut ASN1_OBJECT = 0 as *mut ASN1_OBJECT; + let mut ext: *mut X509_EXTENSION = sk_X509_EXTENSION_value(exts, i); + let mut biomem: *mut BUF_MEM = 0 as *mut BUF_MEM; + let mut namebuf: [libc::c_char; 128] = [0; 128]; + let mut bio_out: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; + if bio_out.is_null() { + return; + } + obj = unsafe { X509_EXTENSION_get_object(ext) }; + asn1_object_dump( + obj, + namebuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 128]>() as u64, + ); + if unsafe { X509V3_EXT_print(bio_out, ext, 0 as u64, 0 as i32) } == 0 { + unsafe { ASN1_STRING_print(bio_out, X509_EXTENSION_get_data(ext) as *mut ASN1_STRING) }; + } + unsafe { + BIO_ctrl( + bio_out, + 115 as i32, + 0 as i64, + &mut biomem as *mut *mut BUF_MEM as *mut libc::c_char as *mut libc::c_void, + ); + Curl_ssl_push_certinfo_len( + data, + certnum, + namebuf.as_mut_ptr(), + (*biomem).data, + (*biomem).length, + ); + BIO_free(bio_out); + } + i += 1; + } +} + +#[cfg(USE_OPENSSL)] +extern "C" fn get_cert_chain( + mut data: *mut Curl_easy, + mut connssl: *mut ssl_connect_data, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut sk: *mut stack_st_X509 = 0 as *mut stack_st_X509; + let mut i: i32 = 0; + let mut numcerts: numcert_t = 0; + let mut mem: *mut BIO = 0 as *mut BIO; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + sk = unsafe { SSL_get_peer_cert_chain((*backend).handle) }; + if sk.is_null() { + return CURLE_OUT_OF_MEMORY; + } + numcerts = sk_X509_num(sk); + result = Curl_ssl_init_certinfo(data, numcerts); + if result as u64 != 0 { + return result; + } + mem = unsafe { BIO_new(BIO_s_mem()) }; + i = 0 as i32; + while i < numcerts { + let mut num: *mut ASN1_INTEGER = 0 as *mut ASN1_INTEGER; + let mut x: *mut X509 = sk_X509_value(sk, i); + let mut pubkey: *mut EVP_PKEY = 0 as *mut EVP_PKEY; + let mut j: i32 = 0; + let mut ptr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut psig: *const ASN1_BIT_STRING = 0 as *const ASN1_BIT_STRING; + unsafe { + X509_NAME_print_ex( + mem, + X509_get_subject_name(x), + 0 as i32, + (1 as i32 + | 2 as i32 + | 4 as i32 + | 0x10 as i32 + | 0x100 as i32 + | 0x200 as i32 + | 8 as i32 + | (2 as i32) << 16 as i32 + | (1 as i32) << 23 as i32 + | 0 as i32) as u64, + ); + let mut info_len: i64 = BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ); + + Curl_ssl_push_certinfo_len( + data, + i, + b"Subject\0" as *const u8 as *const libc::c_char, + ptr, + info_len as size_t, + ); + } + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + unsafe { + X509_NAME_print_ex( + mem, + X509_get_issuer_name(x), + 0 as i32, + (1 as i32 + | 2 as i32 + | 4 as i32 + | 0x10 as i32 + | 0x100 as i32 + | 0x200 as i32 + | 8 as i32 + | (2 as i32) << 16 as i32 + | (1 as i32) << 23 as i32 + | 0 as i32) as u64, + ); + } + let mut info_len_0: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Issuer\0" as *const u8 as *const libc::c_char, + ptr, + info_len_0 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + unsafe { + BIO_printf( + mem, + b"%lx\0" as *const u8 as *const libc::c_char, + X509_get_version(x), + ); + } + let mut info_len_1: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Version\0" as *const u8 as *const libc::c_char, + ptr, + info_len_1 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + num = unsafe { X509_get_serialNumber(x) }; + if unsafe { (*num).type_0 } == 2 as i32 | 0x100 as i32 { + unsafe { + BIO_puts(mem, b"-\0" as *const u8 as *const libc::c_char); + } + } + j = 0 as i32; + while j < unsafe { (*num).length } { + unsafe { + BIO_printf( + mem, + b"%02x\0" as *const u8 as *const libc::c_char, + *((*num).data).offset(j as isize) as i32, + ); + } + j += 1; + } + let mut info_len_2: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Serial Number\0" as *const u8 as *const libc::c_char, + ptr, + info_len_2 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + + if cfg!(all(HAVE_X509_GET0_SIGNATURE, HAVE_X509_GET0_EXTENSIONS)) { + let mut sigalg: *const X509_ALGOR = 0 as *const X509_ALGOR; + let mut xpubkey: *mut X509_PUBKEY = 0 as *mut X509_PUBKEY; + let mut pubkeyoid: *mut ASN1_OBJECT = 0 as *mut ASN1_OBJECT; + unsafe { + X509_get0_signature(&mut psig, &mut sigalg, x); + } + if !sigalg.is_null() { + unsafe { + i2a_ASN1_OBJECT(mem, (*sigalg).algorithm); + } + let mut info_len_3: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Signature Algorithm\0" as *const u8 as *const libc::c_char, + ptr, + info_len_3 as size_t, + ); + 1 as i32 + != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + } + xpubkey = unsafe { X509_get_X509_PUBKEY(x) }; + if !xpubkey.is_null() { + unsafe { + X509_PUBKEY_get0_param( + &mut pubkeyoid, + 0 as *mut *const u8, + 0 as *mut i32, + 0 as *mut *mut X509_ALGOR, + xpubkey, + ); + if !pubkeyoid.is_null() { + i2a_ASN1_OBJECT(mem, pubkeyoid); + let mut info_len_4: i64 = BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ); + Curl_ssl_push_certinfo_len( + data, + i, + b"Public Key Algorithm\0" as *const u8 as *const libc::c_char, + ptr, + info_len_4 as size_t, + ); + 1 as i32 + != BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32; + } + } + } + unsafe { + X509V3_ext(data, i, X509_get0_extensions(x)); + } + } else { + // before OpenSSL 1.0.2 + } + unsafe { + ASN1_TIME_print(mem, X509_get0_notBefore(x)); + } + let mut info_len_5: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Start date\0" as *const u8 as *const libc::c_char, + ptr, + info_len_5 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + unsafe { + ASN1_TIME_print(mem, X509_get0_notAfter(x)); + } + let mut info_len_6: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Expire date\0" as *const u8 as *const libc::c_char, + ptr, + info_len_6 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + + pubkey = unsafe { X509_get_pubkey(x) }; + if pubkey.is_null() { + unsafe { + Curl_infof( + data, + b" Unable to load public key\0" as *const u8 as *const libc::c_char, + ); + } + } else { + let mut pktype: i32 = 0; + match () { + #[cfg(HAVE_OPAQUE_EVP_PKEY)] + _ => { + pktype = unsafe { EVP_PKEY_id(pubkey) }; + } + #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + _ => {} + } + // #[cfg(HAVE_OPAQUE_EVP_PKEY)] + // pktype = EVP_PKEY_id(pubkey); + // TODO - 3652 + // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + match pktype { + 6 => { + #[cfg(HAVE_OPAQUE_EVP_PKEY)] + let mut rsa: *mut RSA = unsafe { EVP_PKEY_get0_RSA(pubkey) }; + // TODO - 3652 + // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] + if true { + let mut n: *const BIGNUM = 0 as *const BIGNUM; + let mut e: *const BIGNUM = 0 as *const BIGNUM; + unsafe { + RSA_get0_key(rsa, &mut n, &mut e, 0 as *mut *const BIGNUM); + } + + BIO_printf( + mem, + b"%d\0" as *const u8 as *const libc::c_char, + BN_num_bits(n), + ); + + let mut info_len_7: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ) + }; + unsafe { + Curl_ssl_push_certinfo_len( + data, + i, + b"RSA Public Key\0" as *const u8 as *const libc::c_char, + ptr, + info_len_7 as size_t, + ); + } + 1 as i32 + != unsafe { + BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 + }; + unsafe { + pubkey_show( + data, + mem, + i, + b"rsa\0" as *const u8 as *const libc::c_char, + b"n\0" as *const u8 as *const libc::c_char, + n, + ); + pubkey_show( + data, + mem, + i, + b"rsa\0" as *const u8 as *const libc::c_char, + b"e\0" as *const u8 as *const libc::c_char, + e, + ); + } + } + #[cfg(not(HAVE_OPAQUE_RSA_DSA_DH))] + if true { + // TODO - 3678 + } + } + 116 => { + if cfg!(not(OPENSSL_NO_DSA)) { + #[cfg(HAVE_OPAQUE_EVP_PKEY)] + let mut dsa: *mut DSA = unsafe { EVP_PKEY_get0_DSA(pubkey) }; + // TODO - 3691 + // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] + if true { + let mut p: *const BIGNUM = 0 as *const BIGNUM; + let mut q: *const BIGNUM = 0 as *const BIGNUM; + let mut g: *const BIGNUM = 0 as *const BIGNUM; + let mut pub_key: *const BIGNUM = 0 as *const BIGNUM; + unsafe { + DSA_get0_pqg(dsa, &mut p, &mut q, &mut g); + DSA_get0_key(dsa, &mut pub_key, 0 as *mut *const BIGNUM); + pubkey_show( + data, + mem, + i, + b"dsa\0" as *const u8 as *const libc::c_char, + b"p\0" as *const u8 as *const libc::c_char, + p, + ); + pubkey_show( + data, + mem, + i, + b"dsa\0" as *const u8 as *const libc::c_char, + b"q\0" as *const u8 as *const libc::c_char, + q, + ); + pubkey_show( + data, + mem, + i, + b"dsa\0" as *const u8 as *const libc::c_char, + b"g\0" as *const u8 as *const libc::c_char, + g, + ); + pubkey_show( + data, + mem, + i, + b"dsa\0" as *const u8 as *const libc::c_char, + b"pub_key\0" as *const u8 as *const libc::c_char, + pub_key, + ); + } + } + #[cfg(not(HAVE_OPAQUE_RSA_DSA_DH))] + if true { + // cfg!(not(HAVE_OPAQUE_RSA_DSA_DH)) + } + } + } + 28 => { + #[cfg(HAVE_OPAQUE_EVP_PKEY)] + let mut dh: *mut DH = unsafe { EVP_PKEY_get0_DH(pubkey) }; + // TODO + // #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + #[cfg(HAVE_OPAQUE_RSA_DSA_DH)] + if true { + let mut p_0: *const BIGNUM = 0 as *const BIGNUM; + let mut q_0: *const BIGNUM = 0 as *const BIGNUM; + let mut g_0: *const BIGNUM = 0 as *const BIGNUM; + let mut pub_key_0: *const BIGNUM = 0 as *const BIGNUM; + unsafe { + DH_get0_pqg(dh, &mut p_0, &mut q_0, &mut g_0); + DH_get0_key(dh, &mut pub_key_0, 0 as *mut *const BIGNUM); + pubkey_show( + data, + mem, + i, + b"dh\0" as *const u8 as *const libc::c_char, + b"p\0" as *const u8 as *const libc::c_char, + p_0, + ); + pubkey_show( + data, + mem, + i, + b"dh\0" as *const u8 as *const libc::c_char, + b"q\0" as *const u8 as *const libc::c_char, + q_0, + ); + pubkey_show( + data, + mem, + i, + b"dh\0" as *const u8 as *const libc::c_char, + b"g\0" as *const u8 as *const libc::c_char, + g_0, + ); + pubkey_show( + data, + mem, + i, + b"dh\0" as *const u8 as *const libc::c_char, + b"pub_key\0" as *const u8 as *const libc::c_char, + pub_key_0, + ); + } + } + // TODO + #[cfg(not(HAVE_OPAQUE_EVP_PKEY))] + if true { + // TODO - 3471 + } + } + _ => {} + } + unsafe { + EVP_PKEY_free(pubkey); + } + } + if !psig.is_null() { + j = 0 as i32; + while j < unsafe { (*psig).length } { + unsafe { + BIO_printf( + mem, + b"%02x:\0" as *const u8 as *const libc::c_char, + *((*psig).data).offset(j as isize) as i32, + ); + } + j += 1; + } + let mut info_len_8: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Signature\0" as *const u8 as *const libc::c_char, + ptr, + info_len_8 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + } + unsafe { + PEM_write_bio_X509(mem, x); + } + let mut info_len_9: i64 = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *mut libc::c_char as *mut libc::c_char as *mut libc::c_void, + ) + }; + Curl_ssl_push_certinfo_len( + data, + i, + b"Cert\0" as *const u8 as *const libc::c_char, + ptr, + info_len_9 as size_t, + ); + 1 as i32 != unsafe { BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void) as i32 }; + i += 1; + } + unsafe { + BIO_free(mem); + } + return CURLE_OK; +} + +/* + * Heavily modified from: + * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL + */ +#[cfg(USE_OPENSSL)] +extern "C" fn pkp_pin_peer_pubkey( + mut data: *mut Curl_easy, + mut cert: *mut X509, + mut pinnedpubkey: *const libc::c_char, +) -> CURLcode { + /* Scratch */ + let mut len1: i32 = 0 as i32; + let mut len2: i32 = 0 as i32; + let mut buff1: *mut u8 = 0 as *mut u8; + let mut temp: *mut u8 = 0 as *mut u8; + /* Result is returned to caller */ + let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + /* if a path wasn't specified, don't pin */ + if pinnedpubkey.is_null() { + return CURLE_OK; + } + if cert.is_null() { + return result; + } + /* Begin Gyrations to get the subjectPublicKeyInfo */ + /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */ + len1 = unsafe { i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), 0 as *mut *mut u8) }; + if !(len1 < 1 as i32) { + match () { + #[cfg(not(CURLDEBUG))] + _ => { + temp = unsafe { + Curl_cmalloc.expect("non-null function pointer")(len1 as size_t) as *mut u8 + }; + } + #[cfg(CURLDEBUG)] + _ => { + temp = unsafe { + curl_dbg_malloc( + len1 as size_t, + 3798 as i32, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + ) + } as *mut u8; + } + } + buff1 = temp; + if !buff1.is_null() { + len2 = unsafe { i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &mut temp) }; + /* + * These checks are verifying we got back the same values as when we + * sized the buffer. It's pretty weak since they should always be the + * same. But it gives us something to test. + */ + if !(len1 != len2 + || temp.is_null() + || unsafe { temp.offset_from(buff1) } as i64 != len1 as i64) + { + /* End Gyrations */ + + /* The one good exit point */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1 as size_t); + } + } + } + if !buff1.is_null() { + #[cfg(not(CURLDEBUG))] + unsafe { + Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void); + } + + #[cfg(CURLDEBUG)] + unsafe { + curl_dbg_free( + buff1 as *mut libc::c_void, + 3820 as i32, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + ); + } + } + return result; +} + +/* + * Get the server cert, verify it and show it, etc., only call failf() if the + * 'strict' argument is TRUE as otherwise all this is for informational + * purposes only! + * + * We check certificates to authenticate the server; otherwise we risk + * man-in-the-middle attack. + */ +#[cfg(USE_OPENSSL)] +extern "C" fn servercert( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut connssl: *mut ssl_connect_data, + mut strict: bool, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut rc: i32 = 0; + let mut lerr: i64 = 0; + let mut issuer: *mut X509 = 0 as *mut X509; + let mut fp: *mut BIO = 0 as *mut BIO; + let mut error_buffer: [libc::c_char; 256] = unsafe { + *::std::mem::transmute::< &[u8; 256], &mut [libc::c_char; 256], >( b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", ) - }; - let mut buffer: [libc::c_char; 2048] = [0; 2048]; - let mut ptr: *const libc::c_char = 0 as *const libc::c_char; - let mut mem: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - if unsafe { ((*data).set.ssl).certinfo() } != 0 { - /* we've been asked to gather certificate info! */ - get_cert_chain(data, connssl); - } - unsafe { - (*backend).server_cert = SSL_get_peer_certificate((*backend).handle); - } - if unsafe { ((*backend).server_cert).is_null() } { - unsafe { - BIO_free(mem); - } - if !strict { - return CURLE_OK; - } - unsafe { - Curl_failf( - data, - b"SSL: couldn't get peer certificate!\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_PEER_FAILED_VERIFICATION; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_IS_PROXY_void = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype } as u32 - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - b"Proxy\0" as *const u8 as *const libc::c_char - } else { - b"Server\0" as *const u8 as *const libc::c_char - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_IS_PROXY_void = if 0 as i32 != 0 { - b"Proxy\0" as *const u8 as *const libc::c_char - } else { - b"Server\0" as *const u8 as *const libc::c_char - }; - unsafe { - Curl_infof( - data, - b"%s certificate:\0" as *const u8 as *const libc::c_char, - SSL_IS_PROXY_void, - ); - } - rc = unsafe { - x509_name_oneline( - X509_get_subject_name((*backend).server_cert), - buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 2048]>() as u64, - ) - }; - unsafe { - Curl_infof( - data, - b" subject: %s\0" as *const u8 as *const libc::c_char, - if rc != 0 { - b"[NONE]\0" as *const u8 as *const libc::c_char - } else { - buffer.as_mut_ptr() as *const libc::c_char - }, - ); - } - // DONE - 3869 - if cfg!(not(CURL_DISABLE_VERBOSE_STRINGS)) { - let mut len: i64 = 0; - unsafe { - ASN1_TIME_print(mem, X509_get0_notBefore((*backend).server_cert)); - } - len = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *const libc::c_char as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ) - }; - unsafe { - Curl_infof( - data, - b" start date: %.*s\0" as *const u8 as *const libc::c_char, - len as i32, - ptr, - ); - BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void); - ASN1_TIME_print(mem, X509_get0_notAfter((*backend).server_cert)); - } - len = unsafe { - BIO_ctrl( - mem, - 3 as i32, - 0 as i64, - &mut ptr as *mut *const libc::c_char as *mut *mut libc::c_char as *mut libc::c_char - as *mut libc::c_void, - ) - }; - unsafe { - Curl_infof( - data, - b" expire date: %.*s\0" as *const u8 as *const libc::c_char, - len as i32, - ptr, - ); - BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void); - BIO_free(mem); - } - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifyhost = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype } as u32 - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*conn).proxy_ssl_config).verifyhost() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifyhost() as i32 } - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifyhost = unsafe { ((*conn).ssl_config).verifyhost() != 0 }; - - if SSL_CONN_CONFIG_verifyhost { - result = unsafe { verifyhost(data, conn, (*backend).server_cert) }; - if result as u64 != 0 { - unsafe { - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return result; - } - } - rc = unsafe { - x509_name_oneline( - X509_get_issuer_name((*backend).server_cert), - buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 2048]>() as u64, - ) - }; - if rc != 0 { - if strict { - unsafe { - Curl_failf( - data, - b"SSL: couldn't get X509-issuer name!\0" as *const u8 as *const libc::c_char, - ); - } - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else { - unsafe { - Curl_infof( - data, - b" issuer: %s\0" as *const u8 as *const libc::c_char, - buffer.as_mut_ptr(), - ); - } - /* We could do all sorts of certificate verification stuff here before - deallocating the certificate. */ - - /* e.g. match issuer name with provided issuer certificate */ - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_issuercert = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).proxy_ssl_config.issuercert } - } else { - unsafe { (*conn).ssl_config.issuercert } - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_issuercert = unsafe { (*conn).ssl_config.issuercert }; - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_issuercert_blob = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*conn).proxy_ssl_config.issuercert_blob } - } else { - unsafe { (*conn).ssl_config.issuercert_blob } - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_issuercert_blob = unsafe { (*conn).ssl_config.issuercert_blob }; - if !(SSL_CONN_CONFIG_issuercert).is_null() || !(SSL_CONN_CONFIG_issuercert_blob).is_null() { - if !(SSL_CONN_CONFIG_issuercert_blob).is_null() { - fp = unsafe { - BIO_new_mem_buf( - (*SSL_CONN_CONFIG_issuercert_blob).data, - (*SSL_CONN_CONFIG_issuercert_blob).len as i32, - ) - }; - } else { - fp = unsafe { BIO_new(BIO_s_file()) }; - if fp.is_null() { - unsafe { - Curl_failf( - data, - b"BIO_new return NULL, OpenSSL error %s\0" as *const u8 - as *const libc::c_char, - ossl_strerror( - ERR_get_error(), - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return CURLE_OUT_OF_MEMORY; - } - if unsafe { - BIO_ctrl( - fp, - 108 as i32, - (0x1 as i32 | 0x2 as i32) as i64, - SSL_CONN_CONFIG_issuercert as *mut libc::c_void, - ) - } as i32 - <= 0 as i32 - { - if strict { - unsafe { - Curl_failf( - data, - b"SSL: Unable to open issuer cert (%s)\0" as *const u8 - as *const libc::c_char, - SSL_CONN_CONFIG_issuercert, - ); - } - } - unsafe { - BIO_free(fp); - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return CURLE_SSL_ISSUER_ERROR; - } - } - issuer = - unsafe { PEM_read_bio_X509(fp, 0 as *mut *mut X509, None, 0 as *mut libc::c_void) }; - if issuer.is_null() { - if strict { - unsafe { - Curl_failf( - data, - b"SSL: Unable to read issuer cert (%s)\0" as *const u8 - as *const libc::c_char, - SSL_CONN_CONFIG_issuercert, - ); - } - } - unsafe { - BIO_free(fp); - X509_free(issuer); - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return CURLE_SSL_ISSUER_ERROR; - } - if unsafe { X509_check_issued(issuer, (*backend).server_cert) } != 0 as i32 { - if strict { - unsafe { - Curl_failf( - data, - b"SSL: Certificate issuer check failed (%s)\0" as *const u8 - as *const libc::c_char, - SSL_CONN_CONFIG_issuercert, - ); - } - } - unsafe { - BIO_free(fp); - X509_free(issuer); - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return CURLE_SSL_ISSUER_ERROR; - } - unsafe { - Curl_infof( - data, - b" SSL certificate issuer check ok (%s)\0" as *const u8 as *const libc::c_char, - SSL_CONN_CONFIG_issuercert, - ); - BIO_free(fp); - X509_free(issuer); - } - } - lerr = unsafe { SSL_get_verify_result((*backend).handle) }; - #[cfg(not(CURL_DISABLE_PROXY))] - if true { - *if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } - { - unsafe { &mut (*data).set.proxy_ssl.certverifyresult } - } else { - unsafe { &mut (*data).set.ssl.certverifyresult } - } = lerr; - } - #[cfg(CURL_DISABLE_PROXY)] - unsafe { - (*data).set.ssl.certverifyresult = lerr; - } - if lerr != 0 as i64 { - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifypeer = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifypeer() as i32 } - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifypeer = unsafe { ((*conn).ssl_config).verifystatus() } != 0; - if SSL_CONN_CONFIG_verifypeer { - /* We probably never reach this, because SSL_connect() will fail - and we return earlier if verifypeer is set? */ - if strict { - unsafe { - Curl_failf( - data, - b"SSL certificate verify result: %s (%ld)\0" as *const u8 - as *const libc::c_char, - X509_verify_cert_error_string(lerr), - lerr, - ); - } - } - result = CURLE_PEER_FAILED_VERIFICATION; - } else { - unsafe { - Curl_infof( - data, - b" SSL certificate verify result: %s (%ld), continuing anyway.\0" - as *const u8 as *const libc::c_char, - X509_verify_cert_error_string(lerr), - lerr, - ); - } - } - } else { - unsafe { - Curl_infof( - data, - b" SSL certificate verify ok.\0" as *const u8 as *const libc::c_char, - ); - } - } - } - // DONE - 3986 - #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP), not(CURL_DISABLE_PROXY)))] - let SSL_CONN_CONFIG_verifystatus = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*conn).proxy_ssl_config).verifystatus() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifystatus() as i32 } - } != 0; - #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP), CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifystatus = unsafe { ((*conn).ssl_config).verifystatus() } != 0; - #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP)))] - if SSL_CONN_CONFIG_verifystatus { - result = verifystatus(data, connssl); - if result as u64 != 0 { - unsafe { - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - } - return result; - } - } - if !strict { - /* when not strict, we don't bother about the verify cert problems */ - result = CURLE_OK; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_PINNED_PUB_KEY_void = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as usize] } - } else { - unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] } - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_PINNED_PUB_KEY_void = unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] }; - ptr = SSL_PINNED_PUB_KEY_void; - if result as u64 == 0 && !ptr.is_null() { - result = unsafe { pkp_pin_peer_pubkey(data, (*backend).server_cert, ptr) }; - if result as u64 != 0 { - unsafe { - Curl_failf( - data, - b"SSL: public key does not match pinned public key!\0" as *const u8 - as *const libc::c_char, - ); - } - } - } - unsafe { - X509_free((*backend).server_cert); - (*backend).server_cert = 0 as *mut X509; - (*connssl).connecting_state = ssl_connect_done; - } - return result; - } - - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_connect_step3( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if ssl_connect_3 as u32 == unsafe { (*connssl).connecting_state as u32 } { - } else { - unsafe { - __assert_fail( - b"ssl_connect_3 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 4022 as u32, - (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( - b"CURLcode ossl_connect_step3(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - } - - #[cfg(not(CURL_DISABLE_PROXY))] - let servercert_value_result = servercert( - data, - conn, - connssl, - (if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } - { - unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifypeer() as i32 } - }) != 0 - || (if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } - { - unsafe { ((*conn).proxy_ssl_config).verifyhost() as i32 } - } else { - unsafe { ((*conn).ssl_config).verifyhost() as i32 } - }) != 0, - ); - #[cfg(CURL_DISABLE_PROXY)] - let servercert_value_result = servercert( - data, - conn, - connssl, - unsafe { ((*conn).ssl_config).verifypeer() } as i32 != 0 - || unsafe { ((*conn).ssl_config).verifyhost() } as i32 != 0, - ); - /* - * We check certificates to authenticate the server; otherwise we risk - * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to - * verify the peer, ignore faults and failures from the server cert - * operations. - */ - result = servercert_value_result; - if result as u64 == 0 { - unsafe { - (*connssl).connecting_state = ssl_connect_done; - } - } - return result; - } - - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_connect_common( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut nonblocking: bool, - mut done: *mut bool, - ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } - as *mut ssl_connect_data; - let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; - let mut what: i32 = 0; - /* check if the connection has already been established */ - if ssl_connection_complete as u32 == unsafe { (*connssl).state as u32 } { - unsafe { - *done = 1 as i32 != 0; - } - return CURLE_OK; - } - if ssl_connect_1 as u32 == unsafe { (*connssl).connecting_state as u32 } { - /* Find out how much more time we're allowed */ - let timeout_ms: timediff_t = - unsafe { Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0) }; - if timeout_ms < 0 as i64 { - /* no need to continue if time is already up */ - unsafe { - Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - ); - } - return CURLE_OPERATION_TIMEDOUT; - } - result = ossl_connect_step1(data, conn, sockindex); - if result as u64 != 0 { - return result; - } - } - unsafe { - while ssl_connect_2 as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 - { - /* check allowed time left */ - let timeout_ms_0: timediff_t = Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0); - if timeout_ms_0 < 0 as i64 { - /* no need to continue if time already is up */ - Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - ); - return CURLE_OPERATION_TIMEDOUT; - } - /* if ssl is expecting something, check if it's available. */ - if (*connssl).connecting_state as u32 == ssl_connect_2_reading as u32 - || (*connssl).connecting_state as u32 == ssl_connect_2_writing as u32 - { - let mut writefd: curl_socket_t = - if ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 { - sockfd - } else { - -(1 as i32) - }; - let mut readfd: curl_socket_t = - if ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 { - sockfd - } else { - -(1 as i32) - }; - what = Curl_socket_check( - readfd, - -(1 as i32), - writefd, - if nonblocking as i32 != 0 { - 0 as i64 - } else { - timeout_ms_0 - }, - ); - if what < 0 as i32 { - /* fatal error */ - Curl_failf( - data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, - *__errno_location(), - ); - return CURLE_SSL_CONNECT_ERROR; - } - if 0 as i32 == what { - if nonblocking { - *done = 0 as i32 != 0; - return CURLE_OK; - } - /* timeout */ - Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - ); - return CURLE_OPERATION_TIMEDOUT; - } - /* socket is readable or writable */ - } - /* Run transaction, and return to the caller if it failed or if this - * connection is done nonblocking and this loop would execute again. This - * permits the owner of a multi handle to abort a connection attempt - * before step2 has completed while ensuring that a client using select() - * or epoll() will always have a valid fdset to wait on. - */ - result = ossl_connect_step2(data, conn, sockindex); - if result as u32 != 0 - || nonblocking as i32 != 0 - && (ssl_connect_2 as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 - || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32) - { - return result; - } - } - } /* repeat step2 until all transactions are done. */ - - if ssl_connect_3 as u32 == unsafe { (*connssl).connecting_state as u32 } { - result = ossl_connect_step3(data, conn, sockindex); - if result as u64 != 0 { - return result; - } - } - if ssl_connect_done as u32 == unsafe { (*connssl).connecting_state as u32 } { - unsafe { - (*connssl).state = ssl_connection_complete; - (*conn).recv[sockindex as usize] = Some(ossl_recv as Curl_recv); - (*conn).send[sockindex as usize] = Some(ossl_send as Curl_send); - *done = 1 as i32 != 0; - } - } else { - unsafe { - *done = 0 as i32 != 0; - } - } - /* Reset our connect state machine */ - unsafe { - (*connssl).connecting_state = ssl_connect_1; - } - return CURLE_OK; - } - - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_connect_nonblocking( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut done: *mut bool, - ) -> CURLcode { - return ossl_connect_common(data, conn, sockindex, 1 as i32 != 0, done); - } - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_connect( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) -> CURLcode { - let mut result: CURLcode = CURLE_OK; - let mut done: bool = 0 as i32 != 0; - result = ossl_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done); - if result as u64 != 0 { - return result; - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if done { - } else { - unsafe { - __assert_fail( - b"done\0" as *const u8 as *const libc::c_char, - b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, - 4170 as u32, - (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( - b"CURLcode ossl_connect(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - } - return CURLE_OK; - } - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_data_pending(mut conn: *const connectdata, mut connindex: i32) -> bool { - unsafe { - let mut connssl: *const ssl_connect_data = - &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data; - if !((*(*connssl).backend).handle).is_null() - && SSL_pending((*(*connssl).backend).handle) != 0 - { - return 1 as i32 != 0; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let mut proxyssl: *const ssl_connect_data = - &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data; - #[cfg(not(CURL_DISABLE_PROXY))] - if !((*(*proxyssl).backend).handle).is_null() - && SSL_pending((*(*proxyssl).backend).handle) != 0 - { - return 1 as i32 != 0; - } - return 0 as i32 != 0; - } - } - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_send( - mut data: *mut Curl_easy, - mut sockindex: i32, - mut mem: *const libc::c_void, - mut len: size_t, - mut curlcode: *mut CURLcode, - ) -> ssize_t { - /* SSL_write() is said to return 'int' while write() and send() returns - 'size_t' */ - let mut err: i32 = 0; - let mut error_buffer: [libc::c_char; 256] = [0; 256]; - let mut sslerror: u64 = 0; - let mut memlen: i32 = 0; - let mut rc: i32 = 0; - let mut conn: *mut connectdata = unsafe { (*data).conn }; - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - unsafe { - ERR_clear_error(); - } - const INT_MAX: size_t = 2147483647 as size_t; - memlen = if len > INT_MAX { - INT_MAX as i32 - } else { - len as i32 - }; - unsafe { - (*(*conn).ssl[0 as usize].backend).logger = data; - } - rc = unsafe { SSL_write((*backend).handle, mem, memlen) }; - if rc <= 0 as i32 { - err = unsafe { SSL_get_error((*backend).handle, rc) }; - match err { - 2 | 3 => { - /* The operation did not complete; the same TLS/SSL I/O function - should be called again later. This is basically an EWOULDBLOCK - equivalent. */ - unsafe { - *curlcode = CURLE_AGAIN; - } - return -(1 as i32) as ssize_t; - } - 5 => { - let mut sockerr: i32 = unsafe { *__errno_location() }; - sslerror = unsafe { ERR_get_error() }; - if sslerror != 0 { - ossl_strerror( - sslerror, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } else if sockerr != 0 { - unsafe { - Curl_strerror( - sockerr, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - } else { - unsafe { - strncpy( - error_buffer.as_mut_ptr(), - SSL_ERROR_to_str(err), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - error_buffer[(::std::mem::size_of::<[libc::c_char; 256]>() as u64) - .wrapping_sub(1 as u64) as usize] = '\0' as i32 as libc::c_char; - } - unsafe { - Curl_failf( - data, - b"OpenSSL SSL_write: %s, errno %d\0" as *const u8 as *const libc::c_char, - error_buffer.as_mut_ptr(), - sockerr, - ); - *curlcode = CURLE_SEND_ERROR; - } - return -(1 as i32) as ssize_t; - } - 1 => { - /* A failure in the SSL library occurred, usually a protocol error. - The OpenSSL error queue contains more information on the error. */ - sslerror = unsafe { ERR_get_error() }; - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let CURL_DISABLE_PROXY_flag_4 = (*conn).proxy_ssl[sockindex as usize].state - as u32 - == ssl_connection_complete as u32; - #[cfg(CURL_DISABLE_PROXY)] - let CURL_DISABLE_PROXY_flag_4 = true; - if (sslerror >> 24 as i64 & 0xff as u64) as i32 == 20 as i32 - && (sslerror & 0xfff as u64) as i32 == 128 as i32 - && (*conn).ssl[sockindex as usize].state as u32 - == ssl_connection_complete as u32 - && CURL_DISABLE_PROXY_flag_4 - { - let mut ver: [libc::c_char; 120] = [0; 120]; - ossl_version( - ver.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 120]>() as u64, - ); - Curl_failf( - data, - b"Error: %s does not support double SSL tunneling.\0" as *const u8 - as *const libc::c_char, - ver.as_mut_ptr(), - ); - } else { - Curl_failf( - data, - b"SSL_write() error: %s\0" as *const u8 as *const libc::c_char, - ossl_strerror( - sslerror, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ), - ); - } - - *curlcode = CURLE_SEND_ERROR; - } - return -(1 as i32) as ssize_t; - } - _ => {} - } - /* a true error */ - unsafe { - Curl_failf( - data, - b"OpenSSL SSL_write: %s, errno %d\0" as *const u8 as *const libc::c_char, - SSL_ERROR_to_str(err), - *__errno_location(), - ); - *curlcode = CURLE_SEND_ERROR; - } - return -(1 as i32) as ssize_t; - } - unsafe { - *curlcode = CURLE_OK; - } - return rc as ssize_t; - } - - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_recv( - mut data: *mut Curl_easy, - mut num: i32, - mut buf: *mut libc::c_char, - mut buffersize: size_t, - mut curlcode: *mut CURLcode, - ) -> ssize_t { - let mut error_buffer: [libc::c_char; 256] = [0; 256]; - let mut sslerror: u64 = 0; - let mut nread: ssize_t = 0; - let mut buffsize: i32 = 0; - let mut conn: *mut connectdata = unsafe { (*data).conn }; - let mut connssl: *mut ssl_connect_data = - unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) } as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - unsafe { - ERR_clear_error(); - } - const INT_MAX: size_t = 2147483647 as size_t; - buffsize = if buffersize > INT_MAX { - INT_MAX as i32 - } else { - buffersize as i32 - }; - unsafe { - (*(*conn).ssl[0 as usize].backend).logger = data; - nread = SSL_read((*backend).handle, buf as *mut libc::c_void, buffsize) as ssize_t; - } - if nread <= 0 as i64 { - let mut err: i32 = unsafe { SSL_get_error((*backend).handle, nread as i32) }; - match err { - 0 => {} - 6 => { - if num == 0 as i32 { - #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] - unsafe { - Curl_conncontrol(conn, 1 as i32); - } - - #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] - unsafe { - Curl_conncontrol( - conn, - 1 as i32, - b"TLS close_notify\0" as *const u8 as *const libc::c_char, - ); - } - } - } - 2 | 3 => { - unsafe { - *curlcode = CURLE_AGAIN; - } - return -(1 as i32) as ssize_t; - } - _ => { - sslerror = unsafe { ERR_get_error() }; - if nread < 0 as i64 || sslerror != 0 { - let mut sockerr: i32 = unsafe { *__errno_location() }; - if sslerror != 0 { - ossl_strerror( - sslerror, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } else if sockerr != 0 && err == 5 as i32 { - unsafe { - Curl_strerror( - sockerr, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - } else { - unsafe { - strncpy( - error_buffer.as_mut_ptr(), - SSL_ERROR_to_str(err), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } - error_buffer[(::std::mem::size_of::<[libc::c_char; 256]>() as u64) - .wrapping_sub(1 as u64) - as usize] = '\0' as i32 as libc::c_char; - } - unsafe { - Curl_failf( - data, - b"OpenSSL SSL_read: %s, errno %d\0" as *const u8 as *const libc::c_char, - error_buffer.as_mut_ptr(), - sockerr, - ); - *curlcode = CURLE_RECV_ERROR; - } - return -(1 as i32) as ssize_t; - /* For debug builds be a little stricter and error on any - SSL_ERROR_SYSCALL. For example a server may have closed the connection - abruptly without a close_notify alert. For compatibility with older - peers we don't do this by default. #4624 - - We can use this to gauge how many users may be affected, and - if it goes ok eventually transition to allow in dev and release with - the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ - #[cfg(DEBUGBUILD)] - unsafe { - if err == 5 as i32 { - let mut sockerr_0: i32 = *__errno_location(); - if sockerr_0 != 0 { - Curl_strerror( - sockerr_0, - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - ); - } else { - curl_msnprintf( - error_buffer.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 256]>() as u64, - b"Connection closed abruptly\0" as *const u8 - as *const libc::c_char, - ); - } - Curl_failf( + }; + let mut buffer: [libc::c_char; 2048] = [0; 2048]; + let mut ptr: *const libc::c_char = 0 as *const libc::c_char; + let mut mem: *mut BIO = unsafe { BIO_new(BIO_s_mem()) }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + if unsafe { ((*data).set.ssl).certinfo() } != 0 { + /* we've been asked to gather certificate info! */ + get_cert_chain(data, connssl); + } + unsafe { + (*backend).server_cert = SSL_get_peer_certificate((*backend).handle); + } + if unsafe { ((*backend).server_cert).is_null() } { + unsafe { + BIO_free(mem); + } + if !strict { + return CURLE_OK; + } + unsafe { + Curl_failf( + data, + b"SSL: couldn't get peer certificate!\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_PEER_FAILED_VERIFICATION; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_IS_PROXY_void = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype } as u32 + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + b"Proxy\0" as *const u8 as *const libc::c_char + } else { + b"Server\0" as *const u8 as *const libc::c_char + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_IS_PROXY_void = if 0 as i32 != 0 { + b"Proxy\0" as *const u8 as *const libc::c_char + } else { + b"Server\0" as *const u8 as *const libc::c_char + }; + unsafe { + Curl_infof( + data, + b"%s certificate:\0" as *const u8 as *const libc::c_char, + SSL_IS_PROXY_void, + ); + } + rc = unsafe { + x509_name_oneline( + X509_get_subject_name((*backend).server_cert), + buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 2048]>() as u64, + ) + }; + unsafe { + Curl_infof( + data, + b" subject: %s\0" as *const u8 as *const libc::c_char, + if rc != 0 { + b"[NONE]\0" as *const u8 as *const libc::c_char + } else { + buffer.as_mut_ptr() as *const libc::c_char + }, + ); + } + // DONE - 3869 + if cfg!(not(CURL_DISABLE_VERBOSE_STRINGS)) { + let mut len: i64 = 0; + unsafe { + ASN1_TIME_print(mem, X509_get0_notBefore((*backend).server_cert)); + } + len = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *const libc::c_char as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ) + }; + unsafe { + Curl_infof( + data, + b" start date: %.*s\0" as *const u8 as *const libc::c_char, + len as i32, + ptr, + ); + BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void); + ASN1_TIME_print(mem, X509_get0_notAfter((*backend).server_cert)); + } + len = unsafe { + BIO_ctrl( + mem, + 3 as i32, + 0 as i64, + &mut ptr as *mut *const libc::c_char as *mut *mut libc::c_char as *mut libc::c_char + as *mut libc::c_void, + ) + }; + unsafe { + Curl_infof( + data, + b" expire date: %.*s\0" as *const u8 as *const libc::c_char, + len as i32, + ptr, + ); + BIO_ctrl(mem, 1 as i32, 0 as i64, 0 as *mut libc::c_void); + BIO_free(mem); + } + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifyhost = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype } as u32 + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*conn).proxy_ssl_config).verifyhost() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifyhost() as i32 } + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifyhost = unsafe { ((*conn).ssl_config).verifyhost() != 0 }; + + if SSL_CONN_CONFIG_verifyhost { + result = unsafe { verifyhost(data, conn, (*backend).server_cert) }; + if result as u64 != 0 { + unsafe { + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return result; + } + } + rc = unsafe { + x509_name_oneline( + X509_get_issuer_name((*backend).server_cert), + buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 2048]>() as u64, + ) + }; + if rc != 0 { + if strict { + unsafe { + Curl_failf( + data, + b"SSL: couldn't get X509-issuer name!\0" as *const u8 as *const libc::c_char, + ); + } + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else { + unsafe { + Curl_infof( + data, + b" issuer: %s\0" as *const u8 as *const libc::c_char, + buffer.as_mut_ptr(), + ); + } + /* We could do all sorts of certificate verification stuff here before + deallocating the certificate. */ + + /* e.g. match issuer name with provided issuer certificate */ + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_issuercert = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.issuercert } + } else { + unsafe { (*conn).ssl_config.issuercert } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_issuercert = unsafe { (*conn).ssl_config.issuercert }; + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_issuercert_blob = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*conn).proxy_ssl_config.issuercert_blob } + } else { + unsafe { (*conn).ssl_config.issuercert_blob } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_issuercert_blob = unsafe { (*conn).ssl_config.issuercert_blob }; + if !(SSL_CONN_CONFIG_issuercert).is_null() || !(SSL_CONN_CONFIG_issuercert_blob).is_null() { + if !(SSL_CONN_CONFIG_issuercert_blob).is_null() { + fp = unsafe { + BIO_new_mem_buf( + (*SSL_CONN_CONFIG_issuercert_blob).data, + (*SSL_CONN_CONFIG_issuercert_blob).len as i32, + ) + }; + } else { + fp = unsafe { BIO_new(BIO_s_file()) }; + if fp.is_null() { + unsafe { + Curl_failf( + data, + b"BIO_new return NULL, OpenSSL error %s\0" as *const u8 + as *const libc::c_char, + ossl_strerror( + ERR_get_error(), + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return CURLE_OUT_OF_MEMORY; + } + if unsafe { + BIO_ctrl( + fp, + 108 as i32, + (0x1 as i32 | 0x2 as i32) as i64, + SSL_CONN_CONFIG_issuercert as *mut libc::c_void, + ) + } as i32 + <= 0 as i32 + { + if strict { + unsafe { + Curl_failf( + data, + b"SSL: Unable to open issuer cert (%s)\0" as *const u8 + as *const libc::c_char, + SSL_CONN_CONFIG_issuercert, + ); + } + } + unsafe { + BIO_free(fp); + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return CURLE_SSL_ISSUER_ERROR; + } + } + issuer = + unsafe { PEM_read_bio_X509(fp, 0 as *mut *mut X509, None, 0 as *mut libc::c_void) }; + if issuer.is_null() { + if strict { + unsafe { + Curl_failf( + data, + b"SSL: Unable to read issuer cert (%s)\0" as *const u8 + as *const libc::c_char, + SSL_CONN_CONFIG_issuercert, + ); + } + } + unsafe { + BIO_free(fp); + X509_free(issuer); + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return CURLE_SSL_ISSUER_ERROR; + } + if unsafe { X509_check_issued(issuer, (*backend).server_cert) } != 0 as i32 { + if strict { + unsafe { + Curl_failf( + data, + b"SSL: Certificate issuer check failed (%s)\0" as *const u8 + as *const libc::c_char, + SSL_CONN_CONFIG_issuercert, + ); + } + } + unsafe { + BIO_free(fp); + X509_free(issuer); + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return CURLE_SSL_ISSUER_ERROR; + } + unsafe { + Curl_infof( + data, + b" SSL certificate issuer check ok (%s)\0" as *const u8 as *const libc::c_char, + SSL_CONN_CONFIG_issuercert, + ); + BIO_free(fp); + X509_free(issuer); + } + } + lerr = unsafe { SSL_get_verify_result((*backend).handle) }; + #[cfg(not(CURL_DISABLE_PROXY))] + if true { + *if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } + { + unsafe { &mut (*data).set.proxy_ssl.certverifyresult } + } else { + unsafe { &mut (*data).set.ssl.certverifyresult } + } = lerr; + } + #[cfg(CURL_DISABLE_PROXY)] + unsafe { + (*data).set.ssl.certverifyresult = lerr; + } + if lerr != 0 as i64 { + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifypeer = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifypeer() as i32 } + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifypeer = unsafe { ((*conn).ssl_config).verifystatus() } != 0; + if SSL_CONN_CONFIG_verifypeer { + /* We probably never reach this, because SSL_connect() will fail + and we return earlier if verifypeer is set? */ + if strict { + unsafe { + Curl_failf( + data, + b"SSL certificate verify result: %s (%ld)\0" as *const u8 + as *const libc::c_char, + X509_verify_cert_error_string(lerr), + lerr, + ); + } + } + result = CURLE_PEER_FAILED_VERIFICATION; + } else { + unsafe { + Curl_infof( + data, + b" SSL certificate verify result: %s (%ld), continuing anyway.\0" + as *const u8 as *const libc::c_char, + X509_verify_cert_error_string(lerr), + lerr, + ); + } + } + } else { + unsafe { + Curl_infof( + data, + b" SSL certificate verify ok.\0" as *const u8 as *const libc::c_char, + ); + } + } + } + // DONE - 3986 + #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP), not(CURL_DISABLE_PROXY)))] + let SSL_CONN_CONFIG_verifystatus = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*conn).proxy_ssl_config).verifystatus() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifystatus() as i32 } + } != 0; + #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP), CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifystatus = unsafe { ((*conn).ssl_config).verifystatus() } != 0; + #[cfg(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP)))] + if SSL_CONN_CONFIG_verifystatus { + result = verifystatus(data, connssl); + if result as u64 != 0 { + unsafe { + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + } + return result; + } + } + if !strict { + /* when not strict, we don't bother about the verify cert problems */ + result = CURLE_OK; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_PINNED_PUB_KEY_void = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as usize] } + } else { + unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] } + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_PINNED_PUB_KEY_void = unsafe { (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] }; + ptr = SSL_PINNED_PUB_KEY_void; + if result as u64 == 0 && !ptr.is_null() { + result = unsafe { pkp_pin_peer_pubkey(data, (*backend).server_cert, ptr) }; + if result as u64 != 0 { + unsafe { + Curl_failf( + data, + b"SSL: public key does not match pinned public key!\0" as *const u8 + as *const libc::c_char, + ); + } + } + } + unsafe { + X509_free((*backend).server_cert); + (*backend).server_cert = 0 as *mut X509; + (*connssl).connecting_state = ssl_connect_done; + } + return result; +} + +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_connect_step3( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if ssl_connect_3 as u32 == unsafe { (*connssl).connecting_state as u32 } { + } else { + unsafe { + __assert_fail( + b"ssl_connect_3 == connssl->connecting_state\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 4022 as u32, + (*::std::mem::transmute::<&[u8; 75], &[libc::c_char; 75]>( + b"CURLcode ossl_connect_step3(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + + #[cfg(not(CURL_DISABLE_PROXY))] + let servercert_value_result = servercert( + data, + conn, + connssl, + (if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } + { + unsafe { ((*conn).proxy_ssl_config).verifypeer() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifypeer() as i32 } + }) != 0 + || (if CURLPROXY_HTTPS as u32 == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } + { + unsafe { ((*conn).proxy_ssl_config).verifyhost() as i32 } + } else { + unsafe { ((*conn).ssl_config).verifyhost() as i32 } + }) != 0, + ); + #[cfg(CURL_DISABLE_PROXY)] + let servercert_value_result = servercert( + data, + conn, + connssl, + unsafe { ((*conn).ssl_config).verifypeer() } as i32 != 0 + || unsafe { ((*conn).ssl_config).verifyhost() } as i32 != 0, + ); + /* + * We check certificates to authenticate the server; otherwise we risk + * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to + * verify the peer, ignore faults and failures from the server cert + * operations. + */ + result = servercert_value_result; + if result as u64 == 0 { + unsafe { + (*connssl).connecting_state = ssl_connect_done; + } + } + return result; +} + +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_connect_common( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut nonblocking: bool, + mut done: *mut bool, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) } + as *mut ssl_connect_data; + let mut sockfd: curl_socket_t = unsafe { (*conn).sock[sockindex as usize] }; + let mut what: i32 = 0; + /* check if the connection has already been established */ + if ssl_connection_complete as u32 == unsafe { (*connssl).state as u32 } { + unsafe { + *done = 1 as i32 != 0; + } + return CURLE_OK; + } + if ssl_connect_1 as u32 == unsafe { (*connssl).connecting_state as u32 } { + /* Find out how much more time we're allowed */ + let timeout_ms: timediff_t = + unsafe { Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0) }; + if timeout_ms < 0 as i64 { + /* no need to continue if time is already up */ + unsafe { + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + } + return CURLE_OPERATION_TIMEDOUT; + } + result = ossl_connect_step1(data, conn, sockindex); + if result as u64 != 0 { + return result; + } + } + unsafe { + while ssl_connect_2 as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 + { + /* check allowed time left */ + let timeout_ms_0: timediff_t = Curl_timeleft(data, 0 as *mut curltime, 1 as i32 != 0); + if timeout_ms_0 < 0 as i64 { + /* no need to continue if time already is up */ + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OPERATION_TIMEDOUT; + } + /* if ssl is expecting something, check if it's available. */ + if (*connssl).connecting_state as u32 == ssl_connect_2_reading as u32 + || (*connssl).connecting_state as u32 == ssl_connect_2_writing as u32 + { + let mut writefd: curl_socket_t = + if ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 { + sockfd + } else { + -(1 as i32) + }; + let mut readfd: curl_socket_t = + if ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 { + sockfd + } else { + -(1 as i32) + }; + what = Curl_socket_check( + readfd, + -(1 as i32), + writefd, + if nonblocking as i32 != 0 { + 0 as i64 + } else { + timeout_ms_0 + }, + ); + if what < 0 as i32 { + /* fatal error */ + Curl_failf( + data, + b"select/poll on SSL socket, errno: %d\0" as *const u8 + as *const libc::c_char, + *__errno_location(), + ); + return CURLE_SSL_CONNECT_ERROR; + } + if 0 as i32 == what { + if nonblocking { + *done = 0 as i32 != 0; + return CURLE_OK; + } + /* timeout */ + Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + ); + return CURLE_OPERATION_TIMEDOUT; + } + /* socket is readable or writable */ + } + /* Run transaction, and return to the caller if it failed or if this + * connection is done nonblocking and this loop would execute again. This + * permits the owner of a multi handle to abort a connection attempt + * before step2 has completed while ensuring that a client using select() + * or epoll() will always have a valid fdset to wait on. + */ + result = ossl_connect_step2(data, conn, sockindex); + if result as u32 != 0 + || nonblocking as i32 != 0 + && (ssl_connect_2 as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 + || ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32) + { + return result; + } + } + } /* repeat step2 until all transactions are done. */ + + if ssl_connect_3 as u32 == unsafe { (*connssl).connecting_state as u32 } { + result = ossl_connect_step3(data, conn, sockindex); + if result as u64 != 0 { + return result; + } + } + if ssl_connect_done as u32 == unsafe { (*connssl).connecting_state as u32 } { + unsafe { + (*connssl).state = ssl_connection_complete; + (*conn).recv[sockindex as usize] = Some(ossl_recv as Curl_recv); + (*conn).send[sockindex as usize] = Some(ossl_send as Curl_send); + *done = 1 as i32 != 0; + } + } else { + unsafe { + *done = 0 as i32 != 0; + } + } + /* Reset our connect state machine */ + unsafe { + (*connssl).connecting_state = ssl_connect_1; + } + return CURLE_OK; +} + +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_connect_nonblocking( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut done: *mut bool, +) -> CURLcode { + return ossl_connect_common(data, conn, sockindex, 1 as i32 != 0, done); +} +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_connect( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut done: bool = 0 as i32 != 0; + result = ossl_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done); + if result as u64 != 0 { + return result; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if done { + } else { + unsafe { + __assert_fail( + b"done\0" as *const u8 as *const libc::c_char, + b"vtls/openssl.c\0" as *const u8 as *const libc::c_char, + 4170 as u32, + (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( + b"CURLcode ossl_connect(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + ); + } + } + return CURLE_OK; +} +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_data_pending(mut conn: *const connectdata, mut connindex: i32) -> bool { + unsafe { + let mut connssl: *const ssl_connect_data = + &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data; + if !((*(*connssl).backend).handle).is_null() + && SSL_pending((*(*connssl).backend).handle) != 0 + { + return 1 as i32 != 0; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let mut proxyssl: *const ssl_connect_data = + &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data; + #[cfg(not(CURL_DISABLE_PROXY))] + if !((*(*proxyssl).backend).handle).is_null() + && SSL_pending((*(*proxyssl).backend).handle) != 0 + { + return 1 as i32 != 0; + } + return 0 as i32 != 0; + } +} +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_send( + mut data: *mut Curl_easy, + mut sockindex: i32, + mut mem: *const libc::c_void, + mut len: size_t, + mut curlcode: *mut CURLcode, +) -> ssize_t { + /* SSL_write() is said to return 'int' while write() and send() returns + 'size_t' */ + let mut err: i32 = 0; + let mut error_buffer: [libc::c_char; 256] = [0; 256]; + let mut sslerror: u64 = 0; + let mut memlen: i32 = 0; + let mut rc: i32 = 0; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + ERR_clear_error(); + } + const INT_MAX: size_t = 2147483647 as size_t; + memlen = if len > INT_MAX { + INT_MAX as i32 + } else { + len as i32 + }; + unsafe { + (*(*conn).ssl[0 as usize].backend).logger = data; + } + rc = unsafe { SSL_write((*backend).handle, mem, memlen) }; + if rc <= 0 as i32 { + err = unsafe { SSL_get_error((*backend).handle, rc) }; + match err { + 2 | 3 => { + /* The operation did not complete; the same TLS/SSL I/O function + should be called again later. This is basically an EWOULDBLOCK + equivalent. */ + unsafe { + *curlcode = CURLE_AGAIN; + } + return -(1 as i32) as ssize_t; + } + 5 => { + let mut sockerr: i32 = unsafe { *__errno_location() }; + sslerror = unsafe { ERR_get_error() }; + if sslerror != 0 { + ossl_strerror( + sslerror, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } else if sockerr != 0 { + unsafe { + Curl_strerror( + sockerr, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + } else { + unsafe { + strncpy( + error_buffer.as_mut_ptr(), + SSL_ERROR_to_str(err), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + error_buffer[(::std::mem::size_of::<[libc::c_char; 256]>() as u64) + .wrapping_sub(1 as u64) as usize] = '\0' as i32 as libc::c_char; + } + unsafe { + Curl_failf( + data, + b"OpenSSL SSL_write: %s, errno %d\0" as *const u8 as *const libc::c_char, + error_buffer.as_mut_ptr(), + sockerr, + ); + *curlcode = CURLE_SEND_ERROR; + } + return -(1 as i32) as ssize_t; + } + 1 => { + /* A failure in the SSL library occurred, usually a protocol error. + The OpenSSL error queue contains more information on the error. */ + sslerror = unsafe { ERR_get_error() }; + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let CURL_DISABLE_PROXY_flag_4 = (*conn).proxy_ssl[sockindex as usize].state + as u32 + == ssl_connection_complete as u32; + #[cfg(CURL_DISABLE_PROXY)] + let CURL_DISABLE_PROXY_flag_4 = true; + if (sslerror >> 24 as i64 & 0xff as u64) as i32 == 20 as i32 + && (sslerror & 0xfff as u64) as i32 == 128 as i32 + && (*conn).ssl[sockindex as usize].state as u32 + == ssl_connection_complete as u32 + && CURL_DISABLE_PROXY_flag_4 + { + let mut ver: [libc::c_char; 120] = [0; 120]; + ossl_version( + ver.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 120]>() as u64, + ); + Curl_failf( + data, + b"Error: %s does not support double SSL tunneling.\0" as *const u8 + as *const libc::c_char, + ver.as_mut_ptr(), + ); + } else { + Curl_failf( + data, + b"SSL_write() error: %s\0" as *const u8 as *const libc::c_char, + ossl_strerror( + sslerror, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ), + ); + } + + *curlcode = CURLE_SEND_ERROR; + } + return -(1 as i32) as ssize_t; + } + _ => {} + } + /* a true error */ + unsafe { + Curl_failf( + data, + b"OpenSSL SSL_write: %s, errno %d\0" as *const u8 as *const libc::c_char, + SSL_ERROR_to_str(err), + *__errno_location(), + ); + *curlcode = CURLE_SEND_ERROR; + } + return -(1 as i32) as ssize_t; + } + unsafe { + *curlcode = CURLE_OK; + } + return rc as ssize_t; +} + +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_recv( + mut data: *mut Curl_easy, + mut num: i32, + mut buf: *mut libc::c_char, + mut buffersize: size_t, + mut curlcode: *mut CURLcode, +) -> ssize_t { + let mut error_buffer: [libc::c_char; 256] = [0; 256]; + let mut sslerror: u64 = 0; + let mut nread: ssize_t = 0; + let mut buffsize: i32 = 0; + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut connssl: *mut ssl_connect_data = + unsafe { &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) } as *mut ssl_connect_data; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + unsafe { + ERR_clear_error(); + } + const INT_MAX: size_t = 2147483647 as size_t; + buffsize = if buffersize > INT_MAX { + INT_MAX as i32 + } else { + buffersize as i32 + }; + unsafe { + (*(*conn).ssl[0 as usize].backend).logger = data; + nread = SSL_read((*backend).handle, buf as *mut libc::c_void, buffsize) as ssize_t; + } + if nread <= 0 as i64 { + let mut err: i32 = unsafe { SSL_get_error((*backend).handle, nread as i32) }; + match err { + 0 => {} + 6 => { + if num == 0 as i32 { + #[cfg(not(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS))))] + unsafe { + Curl_conncontrol(conn, 1 as i32); + } + + #[cfg(all(DEBUGBUILD, not(CURL_DISABLE_VERBOSE_STRINGS)))] + unsafe { + Curl_conncontrol( + conn, + 1 as i32, + b"TLS close_notify\0" as *const u8 as *const libc::c_char, + ); + } + } + } + 2 | 3 => { + unsafe { + *curlcode = CURLE_AGAIN; + } + return -(1 as i32) as ssize_t; + } + _ => { + sslerror = unsafe { ERR_get_error() }; + if nread < 0 as i64 || sslerror != 0 { + let mut sockerr: i32 = unsafe { *__errno_location() }; + if sslerror != 0 { + ossl_strerror( + sslerror, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } else if sockerr != 0 && err == 5 as i32 { + unsafe { + Curl_strerror( + sockerr, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + } else { + unsafe { + strncpy( + error_buffer.as_mut_ptr(), + SSL_ERROR_to_str(err), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } + error_buffer[(::std::mem::size_of::<[libc::c_char; 256]>() as u64) + .wrapping_sub(1 as u64) + as usize] = '\0' as i32 as libc::c_char; + } + unsafe { + Curl_failf( + data, + b"OpenSSL SSL_read: %s, errno %d\0" as *const u8 as *const libc::c_char, + error_buffer.as_mut_ptr(), + sockerr, + ); + *curlcode = CURLE_RECV_ERROR; + } + return -(1 as i32) as ssize_t; + /* For debug builds be a little stricter and error on any + SSL_ERROR_SYSCALL. For example a server may have closed the connection + abruptly without a close_notify alert. For compatibility with older + peers we don't do this by default. #4624 + + We can use this to gauge how many users may be affected, and + if it goes ok eventually transition to allow in dev and release with + the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ + #[cfg(DEBUGBUILD)] + unsafe { + if err == 5 as i32 { + let mut sockerr_0: i32 = *__errno_location(); + if sockerr_0 != 0 { + Curl_strerror( + sockerr_0, + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + ); + } else { + curl_msnprintf( + error_buffer.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 256]>() as u64, + b"Connection closed abruptly\0" as *const u8 + as *const libc::c_char, + ); + } + Curl_failf( data, b"OpenSSL SSL_read: %s, errno %d (Fatal because this is a curl debug build)\0" as *const u8 as *const libc::c_char, error_buffer.as_mut_ptr(), sockerr_0, ); - *curlcode = CURLE_RECV_ERROR; - return -(1 as i32) as ssize_t; - } - } - } - } - } - } - return nread; - } - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_version(mut buffer: *mut libc::c_char, mut size: size_t) -> size_t { - // TODO 这里有一个很长的条件编译 - // if cfg!(LIBRESSL_VERSION_NUMBER){ - // if cfg!(LIBRESSL_VERSION_NUMBER_LT_0X2070100FL){ - // /* - // return msnprintf(buffer, size, "%s/%lx.%lx.%lx", - // OSSL_PACKAGE, - // (LIBRESSL_VERSION_NUMBER>>28)&0xf, - // (LIBRESSL_VERSION_NUMBER>>20)&0xff, - // (LIBRESSL_VERSION_NUMBER>>12)&0xff); - // */ - // } - // else{ - // /* - // char *p; - // int count; - // const char *ver = OpenSSL_version(OPENSSL_VERSION); - // const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ - // if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) { - // ver += sizeof(expected) - 1; - // } - // count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); - // for(p = buffer; *p; ++p) { - // if(ISSPACE(*p)) - // *p = '_'; - // } - // return count; - // */ - // } - // } - // else if cfg!(OPENSSL_IS_BORINGSSL){ - // // return msnprintf(buffer, size, OSSL_PACKAGE); - - // } - // else if cfg!(all(HAVE_OPENSSL_VERSION, OPENSSL_VERSION_STRING)){ - // /* - // return msnprintf(buffer, size, "%s/%s", - // OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); - // */ - // } - //else{ - /* not LibreSSL, BoringSSL and not using OpenSSL_version */ - let mut sub: [libc::c_char; 3] = [0; 3]; - let mut ssleay_value: u64 = 0; - sub[2 as i32 as usize] = '\0' as libc::c_char; - sub[1 as i32 as usize] = '\0' as libc::c_char; - ssleay_value = unsafe { OpenSSL_version_num() }; - if ssleay_value < 0x906000 as u64 { - ssleay_value = 0x1010106f as u64; - sub[0 as usize] = '\0' as libc::c_char; - } else if ssleay_value & 0xff0 as i32 as u64 != 0 { - let mut minor_ver: i32 = (ssleay_value >> 4 as i32 & 0xff as u64) as i32; - if minor_ver > 26 as i32 { - /* handle extended version introduced for 0.9.8za */ - sub[1 as usize] = - ((minor_ver - 1 as i32) % 26 as i32 + 'a' as i32 + 1 as i32) as libc::c_char; - sub[0 as usize] = 'z' as libc::c_char; - } else { - sub[0 as usize] = (minor_ver + 'a' as i32 - 1 as i32) as libc::c_char; - } - } else { - sub[0 as usize] = '\0' as libc::c_char; - } - #[cfg(not(OPENSSL_FIPS))] - return unsafe { - curl_msnprintf( - buffer, - size, - b"%s/%lx.%lx.%lx%s\0" as *const u8 as *const libc::c_char, - b"OpenSSL\0" as *const u8 as *const libc::c_char, - ssleay_value >> 28 as i32 & 0xf as u64, - ssleay_value >> 20 as i32 & 0xff as u64, - ssleay_value >> 12 as i32 & 0xff as u64, - sub.as_mut_ptr(), - ) as size_t - }; - #[cfg(OPENSSL_FIPS)] - return unsafe { - curl_msnprintf( - buffer, - size, - b"%s/%lx.%lx.%lx%s\0" as *const u8 as *const libc::c_char, - b"-fips\0" as *const u8 as *const libc::c_char, - b"OpenSSL\0" as *const u8 as *const libc::c_char, - ssleay_value >> 28 as i32 & 0xf as u64, - ssleay_value >> 20 as i32 & 0xff as u64, - ssleay_value >> 12 as i32 & 0xff as u64, - sub.as_mut_ptr(), - ) as size_t - }; - //} - } - /* can be called with data == NULL */ - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_random( - mut data: *mut Curl_easy, - mut entropy: *mut u8, - mut length: size_t, - ) -> CURLcode { - let mut rc: i32 = 0; - if !data.is_null() { - if ossl_seed(data) as u64 != 0 { - /* Initiate the seed if not already done */ - return CURLE_FAILED_INIT; /* couldn't seed for some reason */ - } - } else if !rand_enough() { - return CURLE_FAILED_INIT; - } - /* RAND_bytes() returns 1 on success, 0 otherwise. */ - rc = unsafe { RAND_bytes(entropy, curlx_uztosi(length)) }; - return (if rc == 1 as i32 { - CURLE_OK as i32 - } else { - CURLE_FAILED_INIT as i32 - }) as CURLcode; - } - - #[cfg(not(OPENSSL_NO_SHA256))] - extern "C" fn ossl_sha256sum( - mut tmp: *const u8, - mut tmplen: size_t, - mut sha256sum: *mut u8, - mut unused: size_t, - ) -> CURLcode { - let mut mdctx: *mut EVP_MD_CTX = 0 as *mut EVP_MD_CTX; - let mut len: u32 = 0 as u32; - mdctx = unsafe { EVP_MD_CTX_new() }; - if mdctx.is_null() { - return CURLE_OUT_OF_MEMORY; - } - unsafe { - EVP_DigestInit(mdctx, EVP_sha256()); - EVP_DigestUpdate(mdctx, tmp as *const libc::c_void, tmplen); - EVP_DigestFinal_ex(mdctx, sha256sum, &mut len); - EVP_MD_CTX_free(mdctx); - } - return CURLE_OK; - } - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_cert_status_request() -> bool { - // TODO - 4475 - if cfg!(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP))) { - return 1 as i32 != 0; - } else { - return 0 as i32 != 0; - } - } - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_get_internals( - mut connssl: *mut ssl_connect_data, - mut info: CURLINFO, - ) -> *mut libc::c_void { - unsafe { - let mut backend: *mut ssl_backend_data = (*connssl).backend; - return if info as u32 == CURLINFO_TLS_SESSION as u32 { - (*backend).ctx as *mut libc::c_void - } else { - (*backend).handle as *mut libc::c_void - }; - } - } - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_associate_connection( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - ) { - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - if unsafe { ((*backend).handle).is_null() } { - /* If we don't have SSL context, do nothing. */ - return; - } - unsafe { - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*data).set.proxy_ssl.primary).sessionid() as i32 - } else { - ((*data).set.ssl.primary).sessionid() as i32 - } != 0; - - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = ((*data).set.ssl.primary).sessionid() != 0; - - if SSL_SET_OPTION_primary_sessionid { - let mut data_idx: i32 = ossl_get_ssl_data_index(); - let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); - let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); - let mut proxy_idx: i32 = ossl_get_proxy_index(); - if data_idx >= 0 as i32 - && connectdata_idx >= 0 as i32 - && sockindex_idx >= 0 as i32 - && proxy_idx >= 0 as i32 - { - /* Store the data needed for the "new session" callback. - * The sockindex is stored as a pointer to an array element. */ - - SSL_set_ex_data((*backend).handle, data_idx, data as *mut libc::c_void); - SSL_set_ex_data( - (*backend).handle, - connectdata_idx, - conn as *mut libc::c_void, - ); - SSL_set_ex_data( - (*backend).handle, - sockindex_idx, - ((*conn).sock).as_mut_ptr().offset(sockindex as isize) as *mut libc::c_void, - ); - #[cfg(not(CURL_DISABLE_PROXY))] - SSL_set_ex_data( - (*backend).handle, - proxy_idx, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - 1 as *mut libc::c_void - } else { - 0 as *mut libc::c_void - }, - ); - // TODO - 4516 - #[cfg(CURL_DISABLE_PROXY)] - SSL_set_ex_data((*backend).handle, proxy_idx, 0 as *mut libc::c_void); - } - } - } - } - - /* - * Starting with TLS 1.3, the ossl_new_session_cb callback gets called after - * the handshake. If the transfer that sets up the callback gets killed before - * this callback arrives, we must make sure to properly clear the data to - * avoid UAF problems. A future optimization could be to instead store another - * transfer that might still be using the same connection. - */ - #[cfg(USE_OPENSSL)] - extern "C" fn ossl_disassociate_connection(mut data: *mut Curl_easy, mut sockindex: i32) { - let mut conn: *mut connectdata = unsafe { (*data).conn }; - let mut connssl: *mut ssl_connect_data = unsafe { - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data - }; - let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; - /* If we don't have SSL context, do nothing. */ - if unsafe { ((*backend).handle).is_null() } { - return; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 - == unsafe { (*conn).http_proxy.proxytype as u32 } - && ssl_connection_complete as u32 - != unsafe { - (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - } { - unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } - } else { - unsafe { ((*data).set.ssl.primary).sessionid() as i32 } - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() } != 0; - if SSL_SET_OPTION_primary_sessionid { - let mut data_idx: i32 = ossl_get_ssl_data_index(); - let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); - let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); - let mut proxy_idx: i32 = ossl_get_proxy_index(); - if data_idx >= 0 as i32 - && connectdata_idx >= 0 as i32 - && sockindex_idx >= 0 as i32 - && proxy_idx >= 0 as i32 - { - /* Disable references to data in "new session" callback to avoid - * accessing a stale pointer. */ - unsafe { - SSL_set_ex_data((*backend).handle, data_idx, 0 as *mut libc::c_void); - SSL_set_ex_data((*backend).handle, connectdata_idx, 0 as *mut libc::c_void); - SSL_set_ex_data((*backend).handle, sockindex_idx, 0 as *mut libc::c_void); - SSL_set_ex_data((*backend).handle, proxy_idx, 0 as *mut libc::c_void); - } - } - } - } - - #[no_mangle] - pub static mut Curl_ssl_openssl: Curl_ssl = Curl_ssl { - info: { - curl_ssl_backend { - id: CURLSSLBACKEND_OPENSSL, - name: b"openssl\0" as *const u8 as *const libc::c_char, - } - }, - supports: ((1 as i32) << 0 as i32 - | (1 as i32) << 6 as i32 - | (1 as i32) << 1 as i32 - | (1 as i32) << 2 as i32 - | (1 as i32) << 3 as i32 - | (1 as i32) << 5 as i32 - | (1 as i32) << 4 as i32) as u32, - sizeof_ssl_backend_data: ::std::mem::size_of::() as u64, - init: Some(ossl_init as unsafe extern "C" fn() -> i32), - cleanup: Some(ossl_cleanup as unsafe extern "C" fn() -> ()), - version: Some(ossl_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t), - check_cxn: Some(ossl_check_cxn as unsafe extern "C" fn(*mut connectdata) -> i32), - shut_down: Some( - ossl_shutdown as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> i32, - ), - data_pending: Some(ossl_data_pending as unsafe extern "C" fn(*const connectdata, i32) -> bool), - random: Some(ossl_random as unsafe extern "C" fn(*mut Curl_easy, *mut u8, size_t) -> CURLcode), - cert_status_request: Some(ossl_cert_status_request as unsafe extern "C" fn() -> bool), - connect_blocking: Some( - ossl_connect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> CURLcode, - ), - connect_nonblocking: Some( - ossl_connect_nonblocking - as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32, *mut bool) -> CURLcode, - ), - getsock: Some( - Curl_ssl_getsock as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> i32, - ), - get_internals: Some( - ossl_get_internals - as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, - ), - close_one: Some( - ossl_close as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), - ), - close_all: Some(ossl_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), - session_free: Some(ossl_session_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), - set_engine: Some( - ossl_set_engine as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, - ), - set_engine_default: Some( - ossl_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, - ), - engines_list: Some( - ossl_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, - ), - false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), - sha256sum: Some( - ossl_sha256sum as unsafe extern "C" fn(*const u8, size_t, *mut u8, size_t) -> CURLcode, - ), - associate_connection: Some( - ossl_associate_connection - as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), - ), - disassociate_connection: Some( - ossl_disassociate_connection as unsafe extern "C" fn(*mut Curl_easy, i32) -> (), - ), - }; - \ No newline at end of file + *curlcode = CURLE_RECV_ERROR; + return -(1 as i32) as ssize_t; + } + } + } + } + } + } + return nread; +} +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_version(mut buffer: *mut libc::c_char, mut size: size_t) -> size_t { + // TODO 这里有一个很长的条件编译 + // if cfg!(LIBRESSL_VERSION_NUMBER){ + // if cfg!(LIBRESSL_VERSION_NUMBER_LT_0X2070100FL){ + // /* + // return msnprintf(buffer, size, "%s/%lx.%lx.%lx", + // OSSL_PACKAGE, + // (LIBRESSL_VERSION_NUMBER>>28)&0xf, + // (LIBRESSL_VERSION_NUMBER>>20)&0xff, + // (LIBRESSL_VERSION_NUMBER>>12)&0xff); + // */ + // } + // else{ + // /* + // char *p; + // int count; + // const char *ver = OpenSSL_version(OPENSSL_VERSION); + // const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ + // if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) { + // ver += sizeof(expected) - 1; + // } + // count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); + // for(p = buffer; *p; ++p) { + // if(ISSPACE(*p)) + // *p = '_'; + // } + // return count; + // */ + // } + // } + // else if cfg!(OPENSSL_IS_BORINGSSL){ + // // return msnprintf(buffer, size, OSSL_PACKAGE); + + // } + // else if cfg!(all(HAVE_OPENSSL_VERSION, OPENSSL_VERSION_STRING)){ + // /* + // return msnprintf(buffer, size, "%s/%s", + // OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); + // */ + // } + //else{ + /* not LibreSSL, BoringSSL and not using OpenSSL_version */ + let mut sub: [libc::c_char; 3] = [0; 3]; + let mut ssleay_value: u64 = 0; + sub[2 as i32 as usize] = '\0' as libc::c_char; + sub[1 as i32 as usize] = '\0' as libc::c_char; + ssleay_value = unsafe { OpenSSL_version_num() }; + if ssleay_value < 0x906000 as u64 { + ssleay_value = 0x1010106f as u64; + sub[0 as usize] = '\0' as libc::c_char; + } else if ssleay_value & 0xff0 as i32 as u64 != 0 { + let mut minor_ver: i32 = (ssleay_value >> 4 as i32 & 0xff as u64) as i32; + if minor_ver > 26 as i32 { + /* handle extended version introduced for 0.9.8za */ + sub[1 as usize] = + ((minor_ver - 1 as i32) % 26 as i32 + 'a' as i32 + 1 as i32) as libc::c_char; + sub[0 as usize] = 'z' as libc::c_char; + } else { + sub[0 as usize] = (minor_ver + 'a' as i32 - 1 as i32) as libc::c_char; + } + } else { + sub[0 as usize] = '\0' as libc::c_char; + } + #[cfg(not(OPENSSL_FIPS))] + return unsafe { + curl_msnprintf( + buffer, + size, + b"%s/%lx.%lx.%lx%s\0" as *const u8 as *const libc::c_char, + b"OpenSSL\0" as *const u8 as *const libc::c_char, + ssleay_value >> 28 as i32 & 0xf as u64, + ssleay_value >> 20 as i32 & 0xff as u64, + ssleay_value >> 12 as i32 & 0xff as u64, + sub.as_mut_ptr(), + ) as size_t + }; + #[cfg(OPENSSL_FIPS)] + return unsafe { + curl_msnprintf( + buffer, + size, + b"%s/%lx.%lx.%lx%s\0" as *const u8 as *const libc::c_char, + b"-fips\0" as *const u8 as *const libc::c_char, + b"OpenSSL\0" as *const u8 as *const libc::c_char, + ssleay_value >> 28 as i32 & 0xf as u64, + ssleay_value >> 20 as i32 & 0xff as u64, + ssleay_value >> 12 as i32 & 0xff as u64, + sub.as_mut_ptr(), + ) as size_t + }; + //} +} +/* can be called with data == NULL */ +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_random( + mut data: *mut Curl_easy, + mut entropy: *mut u8, + mut length: size_t, +) -> CURLcode { + let mut rc: i32 = 0; + if !data.is_null() { + if ossl_seed(data) as u64 != 0 { + /* Initiate the seed if not already done */ + return CURLE_FAILED_INIT; /* couldn't seed for some reason */ + } + } else if !rand_enough() { + return CURLE_FAILED_INIT; + } + /* RAND_bytes() returns 1 on success, 0 otherwise. */ + rc = unsafe { RAND_bytes(entropy, curlx_uztosi(length)) }; + return (if rc == 1 as i32 { + CURLE_OK as i32 + } else { + CURLE_FAILED_INIT as i32 + }) as CURLcode; +} + +#[cfg(not(OPENSSL_NO_SHA256))] +extern "C" fn ossl_sha256sum( + mut tmp: *const u8, + mut tmplen: size_t, + mut sha256sum: *mut u8, + mut unused: size_t, +) -> CURLcode { + let mut mdctx: *mut EVP_MD_CTX = 0 as *mut EVP_MD_CTX; + let mut len: u32 = 0 as u32; + mdctx = unsafe { EVP_MD_CTX_new() }; + if mdctx.is_null() { + return CURLE_OUT_OF_MEMORY; + } + unsafe { + EVP_DigestInit(mdctx, EVP_sha256()); + EVP_DigestUpdate(mdctx, tmp as *const libc::c_void, tmplen); + EVP_DigestFinal_ex(mdctx, sha256sum, &mut len); + EVP_MD_CTX_free(mdctx); + } + return CURLE_OK; +} +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_cert_status_request() -> bool { + // TODO - 4475 + if cfg!(all(not(OPENSSL_NO_TLSEXT), not(OPENSSL_NO_OCSP))) { + return 1 as i32 != 0; + } else { + return 0 as i32 != 0; + } +} +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_get_internals( + mut connssl: *mut ssl_connect_data, + mut info: CURLINFO, +) -> *mut libc::c_void { + unsafe { + let mut backend: *mut ssl_backend_data = (*connssl).backend; + return if info as u32 == CURLINFO_TLS_SESSION as u32 { + (*backend).ctx as *mut libc::c_void + } else { + (*backend).handle as *mut libc::c_void + }; + } +} +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_associate_connection( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, +) { + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + if unsafe { ((*backend).handle).is_null() } { + /* If we don't have SSL context, do nothing. */ + return; + } + unsafe { + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*data).set.proxy_ssl.primary).sessionid() as i32 + } else { + ((*data).set.ssl.primary).sessionid() as i32 + } != 0; + + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = ((*data).set.ssl.primary).sessionid() != 0; + + if SSL_SET_OPTION_primary_sessionid { + let mut data_idx: i32 = ossl_get_ssl_data_index(); + let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); + let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); + let mut proxy_idx: i32 = ossl_get_proxy_index(); + if data_idx >= 0 as i32 + && connectdata_idx >= 0 as i32 + && sockindex_idx >= 0 as i32 + && proxy_idx >= 0 as i32 + { + /* Store the data needed for the "new session" callback. + * The sockindex is stored as a pointer to an array element. */ + + SSL_set_ex_data((*backend).handle, data_idx, data as *mut libc::c_void); + SSL_set_ex_data( + (*backend).handle, + connectdata_idx, + conn as *mut libc::c_void, + ); + SSL_set_ex_data( + (*backend).handle, + sockindex_idx, + ((*conn).sock).as_mut_ptr().offset(sockindex as isize) as *mut libc::c_void, + ); + #[cfg(not(CURL_DISABLE_PROXY))] + SSL_set_ex_data( + (*backend).handle, + proxy_idx, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + 1 as *mut libc::c_void + } else { + 0 as *mut libc::c_void + }, + ); + // TODO - 4516 + #[cfg(CURL_DISABLE_PROXY)] + SSL_set_ex_data((*backend).handle, proxy_idx, 0 as *mut libc::c_void); + } + } + } +} + +/* + * Starting with TLS 1.3, the ossl_new_session_cb callback gets called after + * the handshake. If the transfer that sets up the callback gets killed before + * this callback arrives, we must make sure to properly clear the data to + * avoid UAF problems. A future optimization could be to instead store another + * transfer that might still be using the same connection. + */ +#[cfg(USE_OPENSSL)] +extern "C" fn ossl_disassociate_connection(mut data: *mut Curl_easy, mut sockindex: i32) { + let mut conn: *mut connectdata = unsafe { (*data).conn }; + let mut connssl: *mut ssl_connect_data = unsafe { + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data + }; + let mut backend: *mut ssl_backend_data = unsafe { (*connssl).backend }; + /* If we don't have SSL context, do nothing. */ + if unsafe { ((*backend).handle).is_null() } { + return; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 + == unsafe { (*conn).http_proxy.proxytype as u32 } + && ssl_connection_complete as u32 + != unsafe { + (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + } { + unsafe { ((*data).set.proxy_ssl.primary).sessionid() as i32 } + } else { + unsafe { ((*data).set.ssl.primary).sessionid() as i32 } + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = unsafe { ((*data).set.ssl.primary).sessionid() } != 0; + if SSL_SET_OPTION_primary_sessionid { + let mut data_idx: i32 = ossl_get_ssl_data_index(); + let mut connectdata_idx: i32 = ossl_get_ssl_conn_index(); + let mut sockindex_idx: i32 = ossl_get_ssl_sockindex_index(); + let mut proxy_idx: i32 = ossl_get_proxy_index(); + if data_idx >= 0 as i32 + && connectdata_idx >= 0 as i32 + && sockindex_idx >= 0 as i32 + && proxy_idx >= 0 as i32 + { + /* Disable references to data in "new session" callback to avoid + * accessing a stale pointer. */ + unsafe { + SSL_set_ex_data((*backend).handle, data_idx, 0 as *mut libc::c_void); + SSL_set_ex_data((*backend).handle, connectdata_idx, 0 as *mut libc::c_void); + SSL_set_ex_data((*backend).handle, sockindex_idx, 0 as *mut libc::c_void); + SSL_set_ex_data((*backend).handle, proxy_idx, 0 as *mut libc::c_void); + } + } + } +} + +#[no_mangle] +pub static mut Curl_ssl_openssl: Curl_ssl = Curl_ssl { + info: { + curl_ssl_backend { + id: CURLSSLBACKEND_OPENSSL, + name: b"openssl\0" as *const u8 as *const libc::c_char, + } + }, + supports: ((1 as i32) << 0 as i32 + | (1 as i32) << 6 as i32 + | (1 as i32) << 1 as i32 + | (1 as i32) << 2 as i32 + | (1 as i32) << 3 as i32 + | (1 as i32) << 5 as i32 + | (1 as i32) << 4 as i32) as u32, + sizeof_ssl_backend_data: ::std::mem::size_of::() as u64, + init: Some(ossl_init as unsafe extern "C" fn() -> i32), + cleanup: Some(ossl_cleanup as unsafe extern "C" fn() -> ()), + version: Some(ossl_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t), + check_cxn: Some(ossl_check_cxn as unsafe extern "C" fn(*mut connectdata) -> i32), + shut_down: Some( + ossl_shutdown as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> i32, + ), + data_pending: Some(ossl_data_pending as unsafe extern "C" fn(*const connectdata, i32) -> bool), + random: Some(ossl_random as unsafe extern "C" fn(*mut Curl_easy, *mut u8, size_t) -> CURLcode), + cert_status_request: Some(ossl_cert_status_request as unsafe extern "C" fn() -> bool), + connect_blocking: Some( + ossl_connect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> CURLcode, + ), + connect_nonblocking: Some( + ossl_connect_nonblocking + as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32, *mut bool) -> CURLcode, + ), + getsock: Some( + Curl_ssl_getsock as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> i32, + ), + get_internals: Some( + ossl_get_internals + as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, + ), + close_one: Some( + ossl_close as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), + ), + close_all: Some(ossl_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), + session_free: Some(ossl_session_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), + set_engine: Some( + ossl_set_engine as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, + ), + set_engine_default: Some( + ossl_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, + ), + engines_list: Some( + ossl_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, + ), + false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), + sha256sum: Some( + ossl_sha256sum as unsafe extern "C" fn(*const u8, size_t, *mut u8, size_t) -> CURLcode, + ), + associate_connection: Some( + ossl_associate_connection + as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), + ), + disassociate_connection: Some( + ossl_disassociate_connection as unsafe extern "C" fn(*mut Curl_easy, i32) -> (), + ), +}; diff --git a/rust/rust_project/src/vtls/rustls.rs b/rust/rust_project/src/vtls/rustls.rs index 5a265b8..17b6283 100644 --- a/rust/rust_project/src/vtls/rustls.rs +++ b/rust/rust_project/src/vtls/rustls.rs @@ -8,16 +8,16 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: Drug, + * Author: Drug, * Create: 2022-10-31 * Description: support rustls backend ******************************************************************************/ use ::libc; // use c2rust_bitfields::BitfieldStruct; +use crate::src::vtls::vtls::*; use rust_ffi::src::ffi_alias::type_alias::*; use rust_ffi::src::ffi_fun::fun_call::*; use rust_ffi::src::ffi_struct::struct_define::*; -use crate::src::vtls::vtls::*; // #[derive(Copy, Clone)] // #[repr(C)] // pub struct ssl_backend_data { @@ -40,9 +40,8 @@ unsafe extern "C" fn cr_data_pending( mut conn: *const connectdata, mut sockindex: libc::c_int, ) -> bool { - let mut connssl: *const ssl_connect_data = &*((*conn).ssl) - .as_ptr() - .offset(sockindex as isize) as *const ssl_connect_data; + let mut connssl: *const ssl_connect_data = + &*((*conn).ssl).as_ptr().offset(sockindex as isize) as *const ssl_connect_data; let mut backend: *mut ssl_backend_data = (*connssl).backend; return (*backend).data_pending; } @@ -101,9 +100,8 @@ unsafe extern "C" fn cr_recv( mut err: *mut CURLcode, ) -> ssize_t { let mut conn: *mut connectdata = (*data).conn; - let connssl: *mut ssl_connect_data = &mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data; + let connssl: *mut ssl_connect_data = + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; let backend: *mut ssl_backend_data = (*connssl).backend; let rconn: *mut rustls_connection = (*backend).conn; let mut n: size_t = 0 as libc::c_int as size_t; @@ -123,8 +121,8 @@ unsafe extern "C" fn cr_recv( *mut uintptr_t, ) -> libc::c_int, ), - &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) - as *mut curl_socket_t as *mut libc::c_void, + &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) as *mut curl_socket_t + as *mut libc::c_void, &mut tls_bytes_read, ); if io_error == 11 as libc::c_int || io_error == 11 as libc::c_int { @@ -191,9 +189,7 @@ unsafe extern "C" fn cr_recv( { *err = CURLE_OK; return 0 as libc::c_int as ssize_t; - } else if rresult as libc::c_uint - != RUSTLS_RESULT_OK as libc::c_int as libc::c_uint - { + } else if rresult as libc::c_uint != RUSTLS_RESULT_OK as libc::c_int as libc::c_uint { Curl_failf( data, b"error in rustls_connection_read\0" as *const u8 as *const libc::c_char, @@ -210,12 +206,11 @@ unsafe extern "C" fn cr_recv( } else { Curl_infof( data, - b"cr_recv copied out %ld bytes of plaintext\0" as *const u8 - as *const libc::c_char, + b"cr_recv copied out %ld bytes of plaintext\0" as *const u8 as *const libc::c_char, n, ); - plain_bytes_copied = (plain_bytes_copied as libc::c_ulong).wrapping_add(n) - as size_t as size_t; + plain_bytes_copied = + (plain_bytes_copied as libc::c_ulong).wrapping_add(n) as size_t as size_t; } } if plain_bytes_copied == 0 as libc::c_int as libc::c_ulong { @@ -232,9 +227,8 @@ unsafe extern "C" fn cr_send( mut err: *mut CURLcode, ) -> ssize_t { let mut conn: *mut connectdata = (*data).conn; - let connssl: *mut ssl_connect_data = &mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data; + let connssl: *mut ssl_connect_data = + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; let backend: *mut ssl_backend_data = (*connssl).backend; let rconn: *mut rustls_connection = (*backend).conn; let mut plainwritten: size_t = 0 as libc::c_int as size_t; @@ -265,8 +259,7 @@ unsafe extern "C" fn cr_send( if plainwritten == 0 as libc::c_int as libc::c_ulong { Curl_failf( data, - b"EOF in rustls_connection_write\0" as *const u8 - as *const libc::c_char, + b"EOF in rustls_connection_write\0" as *const u8 as *const libc::c_char, ); *err = CURLE_WRITE_ERROR; return -(1 as libc::c_int) as ssize_t; @@ -285,8 +278,8 @@ unsafe extern "C" fn cr_send( *mut uintptr_t, ) -> libc::c_int, ), - &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) - as *mut curl_socket_t as *mut libc::c_void, + &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) as *mut curl_socket_t + as *mut libc::c_void, &mut tlswritten, ); if io_error == 11 as libc::c_int || io_error == 11 as libc::c_int { @@ -323,8 +316,8 @@ unsafe extern "C" fn cr_send( b"cr_send wrote %ld bytes to network\0" as *const u8 as *const libc::c_char, tlswritten, ); - tlswritten_total = (tlswritten_total as libc::c_ulong).wrapping_add(tlswritten) - as size_t as size_t; + tlswritten_total = + (tlswritten_total as libc::c_ulong).wrapping_add(tlswritten) as size_t as size_t; } return plainwritten as ssize_t; } @@ -365,19 +358,17 @@ unsafe extern "C" fn cr_init_backend( backend: *mut ssl_backend_data, ) -> CURLcode { let mut rconn: *mut rustls_connection = (*backend).conn; - let mut config_builder: *mut rustls_client_config_builder = 0 - as *mut rustls_client_config_builder; - let ssl_cafile: *const libc::c_char = if CURLPROXY_HTTPS as libc::c_int - as libc::c_uint == (*conn).http_proxy.proxytype as libc::c_uint + let mut config_builder: *mut rustls_client_config_builder = + 0 as *mut rustls_client_config_builder; + let ssl_cafile: *const libc::c_char = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint + == (*conn).http_proxy.proxytype as libc::c_uint && ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] + != (*conn).proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] == -(1 as libc::c_int) + { + 0 as libc::c_int + } else { + 1 as libc::c_int + }) as usize] .state as libc::c_uint { (*conn).proxy_ssl_config.CAfile @@ -387,14 +378,12 @@ unsafe extern "C" fn cr_init_backend( let verifypeer: bool = if CURLPROXY_HTTPS as libc::c_int as libc::c_uint == (*conn).http_proxy.proxytype as libc::c_uint && ssl_connection_complete as libc::c_int as libc::c_uint - != (*conn) - .proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] - == -(1 as libc::c_int) - { - 0 as libc::c_int - } else { - 1 as libc::c_int - }) as usize] + != (*conn).proxy_ssl[(if (*conn).sock[1 as libc::c_int as usize] == -(1 as libc::c_int) + { + 0 as libc::c_int + } else { + 1 as libc::c_int + }) as usize] .state as libc::c_uint { ((*conn).proxy_ssl_config).verifypeer() as libc::c_int @@ -408,8 +397,7 @@ unsafe extern "C" fn cr_init_backend( let mut alpn: [rustls_slice_bytes; 2] = [ { let mut init = rustls_slice_bytes { - data: b"http/1.1\0" as *const u8 as *const libc::c_char - as *const uint8_t, + data: b"http/1.1\0" as *const u8 as *const libc::c_char as *const uint8_t, len: 8 as libc::c_int as size_t, }; init @@ -444,33 +432,24 @@ unsafe extern "C" fn cr_init_backend( ), ); if cr_hostname_is_ip(hostname) { - rustls_client_config_builder_set_enable_sni( - config_builder, - 0 as libc::c_int != 0, - ); + rustls_client_config_builder_set_enable_sni(config_builder, 0 as libc::c_int != 0); hostname = b"example.invalid\0" as *const u8 as *const libc::c_char; } } else if !ssl_cafile.is_null() { - result = rustls_client_config_builder_load_roots_from_file( - config_builder, - ssl_cafile, - ) as libc::c_int; + result = rustls_client_config_builder_load_roots_from_file(config_builder, ssl_cafile) + as libc::c_int; if result != RUSTLS_RESULT_OK as libc::c_int { Curl_failf( data, - b"failed to load trusted certificates\0" as *const u8 - as *const libc::c_char, - ); - rustls_client_config_free( - rustls_client_config_builder_build(config_builder), + b"failed to load trusted certificates\0" as *const u8 as *const libc::c_char, ); + rustls_client_config_free(rustls_client_config_builder_build(config_builder)); return CURLE_SSL_CACERT_BADFILE; } } let ref mut fresh0 = (*backend).config; *fresh0 = rustls_client_config_builder_build(config_builder); - result = rustls_client_connection_new((*backend).config, hostname, &mut rconn) - as libc::c_int; + result = rustls_client_connection_new((*backend).config, hostname, &mut rconn) as libc::c_int; if result != RUSTLS_RESULT_OK as libc::c_int { rustls_error( result as rustls_result, @@ -502,8 +481,7 @@ unsafe extern "C" fn cr_set_negotiated_alpn( if protocol.is_null() { Curl_infof( data, - b"ALPN, server did not agree to a protocol\0" as *const u8 - as *const libc::c_char, + b"ALPN, server did not agree to a protocol\0" as *const u8 as *const libc::c_char, ); return; } @@ -515,17 +493,19 @@ unsafe extern "C" fn cr_set_negotiated_alpn( len, ) { - Curl_infof(data, b"ALPN, negotiated h2\0" as *const u8 as *const libc::c_char); + Curl_infof( + data, + b"ALPN, negotiated h2\0" as *const u8 as *const libc::c_char, + ); (*conn).negnpn = CURL_HTTP_VERSION_2_0 as libc::c_int; } else if len == 8 as libc::c_int as libc::c_ulong - && 0 as libc::c_int - == memcmp( - b"http/1.1\0" as *const u8 as *const libc::c_char - as *const libc::c_void, - protocol as *const libc::c_void, - len, - ) - { + && 0 as libc::c_int + == memcmp( + b"http/1.1\0" as *const u8 as *const libc::c_char as *const libc::c_void, + protocol as *const libc::c_void, + len, + ) + { Curl_infof( data, b"ALPN, negotiated http/1.1\0" as *const u8 as *const libc::c_char, @@ -534,8 +514,7 @@ unsafe extern "C" fn cr_set_negotiated_alpn( } else { Curl_infof( data, - b"ALPN, negotiated an unrecognized protocol\0" as *const u8 - as *const libc::c_char, + b"ALPN, negotiated an unrecognized protocol\0" as *const u8 as *const libc::c_char, ); } Curl_multiuse_state( @@ -553,9 +532,8 @@ unsafe extern "C" fn cr_connect_nonblocking( mut sockindex: libc::c_int, mut done: *mut bool, ) -> CURLcode { - let connssl: *mut ssl_connect_data = &mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data; + let connssl: *mut ssl_connect_data = + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; let mut sockfd: curl_socket_t = (*conn).sock[sockindex as usize]; let backend: *mut ssl_backend_data = (*connssl).backend; let mut rconn: *mut rustls_connection = 0 as *mut rustls_connection; @@ -566,9 +544,7 @@ unsafe extern "C" fn cr_connect_nonblocking( let mut wants_write: bool = false; let mut writefd: curl_socket_t = 0; let mut readfd: curl_socket_t = 0; - if ssl_connection_none as libc::c_int as libc::c_uint - == (*connssl).state as libc::c_uint - { + if ssl_connection_none as libc::c_int as libc::c_uint == (*connssl).state as libc::c_uint { result = cr_init_backend(data, conn, (*connssl).backend) as libc::c_int; if result != CURLE_OK as libc::c_int { return result as CURLcode; @@ -578,7 +554,10 @@ unsafe extern "C" fn cr_connect_nonblocking( rconn = (*backend).conn; loop { if !rustls_connection_is_handshaking(rconn) { - Curl_infof(data, b"Done handshaking\0" as *const u8 as *const libc::c_char); + Curl_infof( + data, + b"Done handshaking\0" as *const u8 as *const libc::c_char, + ); (*connssl).state = ssl_connection_complete; cr_set_negotiated_alpn(data, conn, rconn); let ref mut fresh2 = (*conn).recv[sockindex as usize]; @@ -627,8 +606,7 @@ unsafe extern "C" fn cr_connect_nonblocking( if what < 0 as libc::c_int { Curl_failf( data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, + b"select/poll on SSL socket, errno: %d\0" as *const u8 as *const libc::c_char, *__errno_location(), ); return CURLE_SSL_CONNECT_ERROR; @@ -636,8 +614,7 @@ unsafe extern "C" fn cr_connect_nonblocking( if 0 as libc::c_int == what { Curl_infof( data, - b"Curl_socket_check: %s would block\0" as *const u8 - as *const libc::c_char, + b"Curl_socket_check: %s would block\0" as *const u8 as *const libc::c_char, if wants_read as libc::c_int != 0 && wants_write as libc::c_int != 0 { b"writing and reading\0" as *const u8 as *const libc::c_char } else if wants_write as libc::c_int != 0 { @@ -652,8 +629,7 @@ unsafe extern "C" fn cr_connect_nonblocking( if wants_write { Curl_infof( data, - b"rustls_connection wants us to write_tls.\0" as *const u8 - as *const libc::c_char, + b"rustls_connection wants us to write_tls.\0" as *const u8 as *const libc::c_char, ); cr_send( data, @@ -668,14 +644,13 @@ unsafe extern "C" fn cr_connect_nonblocking( b"writing would block\0" as *const u8 as *const libc::c_char, ); } else if tmperr as libc::c_uint != CURLE_OK as libc::c_int as libc::c_uint { - return tmperr + return tmperr; } } if wants_read { Curl_infof( data, - b"rustls_connection wants us to read_tls.\0" as *const u8 - as *const libc::c_char, + b"rustls_connection wants us to read_tls.\0" as *const u8 as *const libc::c_char, ); cr_recv( data, @@ -690,24 +665,21 @@ unsafe extern "C" fn cr_connect_nonblocking( b"reading would block\0" as *const u8 as *const libc::c_char, ); } else if tmperr as libc::c_uint != CURLE_OK as libc::c_int as libc::c_uint { - if tmperr as libc::c_uint - == CURLE_READ_ERROR as libc::c_int as libc::c_uint - { - return CURLE_SSL_CONNECT_ERROR + if tmperr as libc::c_uint == CURLE_READ_ERROR as libc::c_int as libc::c_uint { + return CURLE_SSL_CONNECT_ERROR; } else { - return tmperr + return tmperr; } } } - }; + } } unsafe extern "C" fn cr_getsock( mut conn: *mut connectdata, mut socks: *mut curl_socket_t, ) -> libc::c_int { - let connssl: *mut ssl_connect_data = &mut *((*conn).ssl) - .as_mut_ptr() - .offset(0 as libc::c_int as isize) as *mut ssl_connect_data; + let connssl: *mut ssl_connect_data = + &mut *((*conn).ssl).as_mut_ptr().offset(0 as libc::c_int as isize) as *mut ssl_connect_data; let mut sockfd: curl_socket_t = (*conn).sock[0 as libc::c_int as usize]; let backend: *mut ssl_backend_data = (*connssl).backend; let mut rconn: *mut rustls_connection = (*backend).conn; @@ -733,9 +705,8 @@ unsafe extern "C" fn cr_close( mut conn: *mut connectdata, mut sockindex: libc::c_int, ) { - let mut connssl: *mut ssl_connect_data = &mut *((*conn).ssl) - .as_mut_ptr() - .offset(sockindex as isize) as *mut ssl_connect_data; + let mut connssl: *mut ssl_connect_data = + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; let mut backend: *mut ssl_backend_data = (*connssl).backend; let mut tmperr: CURLcode = CURLE_OK; let mut n: ssize_t = 0 as libc::c_int as ssize_t; @@ -777,17 +748,14 @@ pub static mut Curl_ssl_rustls: Curl_ssl = unsafe { init }, supports: ((1 as libc::c_int) << 5 as libc::c_int) as libc::c_uint, - sizeof_ssl_backend_data: ::std::mem::size_of::() - as libc::c_ulong, + sizeof_ssl_backend_data: ::std::mem::size_of::() as libc::c_ulong, init: Some(Curl_none_init as unsafe extern "C" fn() -> libc::c_int), cleanup: Some(Curl_none_cleanup as unsafe extern "C" fn() -> ()), version: Some( - rustls_version - as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t, + rustls_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t, ), check_cxn: Some( - Curl_none_check_cxn - as unsafe extern "C" fn(*mut connectdata) -> libc::c_int, + Curl_none_check_cxn as unsafe extern "C" fn(*mut connectdata) -> libc::c_int, ), shut_down: Some( Curl_none_shutdown @@ -798,16 +766,11 @@ pub static mut Curl_ssl_rustls: Curl_ssl = unsafe { ) -> libc::c_int, ), data_pending: Some( - cr_data_pending - as unsafe extern "C" fn(*const connectdata, libc::c_int) -> bool, + cr_data_pending as unsafe extern "C" fn(*const connectdata, libc::c_int) -> bool, ), random: Some( Curl_none_random - as unsafe extern "C" fn( - *mut Curl_easy, - *mut libc::c_uchar, - size_t, - ) -> CURLcode, + as unsafe extern "C" fn(*mut Curl_easy, *mut libc::c_uchar, size_t) -> CURLcode, ), cert_status_request: Some( Curl_none_cert_status_request as unsafe extern "C" fn() -> bool, @@ -831,46 +794,29 @@ pub static mut Curl_ssl_rustls: Curl_ssl = unsafe { ), getsock: Some( cr_getsock - as unsafe extern "C" fn( - *mut connectdata, - *mut curl_socket_t, - ) -> libc::c_int, + as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> libc::c_int, ), get_internals: Some( cr_get_internals - as unsafe extern "C" fn( - *mut ssl_connect_data, - CURLINFO, - ) -> *mut libc::c_void, + as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, ), close_one: Some( cr_close - as unsafe extern "C" fn( - *mut Curl_easy, - *mut connectdata, - libc::c_int, - ) -> (), - ), - close_all: Some( - Curl_none_close_all as unsafe extern "C" fn(*mut Curl_easy) -> (), + as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, libc::c_int) -> (), ), + close_all: Some(Curl_none_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), session_free: Some( Curl_none_session_free as unsafe extern "C" fn(*mut libc::c_void) -> (), ), set_engine: Some( Curl_none_set_engine - as unsafe extern "C" fn( - *mut Curl_easy, - *const libc::c_char, - ) -> CURLcode, + as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, ), set_engine_default: Some( - Curl_none_set_engine_default - as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, + Curl_none_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, ), engines_list: Some( - Curl_none_engines_list - as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, + Curl_none_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, ), false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), sha256sum: None, -- Gitee