✓ProveIt
Examples / Report #3583983 Saved analysis

CVE-2026-3783: token leak with redirect and netrc

curl · 2026-03-0313.9s analysis · $0.023 in model calls

What the report claims

When using --oauth2-bearer with --netrc and curl follows a redirect, the bearer token leaks to the redirect target because the netrc bypass at lib/http.c:822 skips Curl_auth_allowed_to_host() for bearer tokens.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2026-3783 token leak with redirect and netrc

Shown for comparison after analysis. The pipeline did not see this label.

ProveIt's finding

Code supports the claim

The code supports the reported flaw. A maintainer should review its impact and decide what to do next.

Why this finding?
  • The netrc bypass at lib/http.c:822-827 unconditionally skips Curl_auth_allowed_to_host() when conn->bits.netrc is set
  • The bearer token output path in output_auth_headers (lib/http.c:705-713) has no host check of its own
  • Redirect handling (lib/http.c:1254-1257) clears user/password but not STRING_BEARER or authhost->picked
  • Custom -H Authorization headers are correctly protected at lib/http.c:1828-1833 without a netrc bypass, confirming the inconsistency
  • A user with --oauth2-bearer and --netrc (including a 'default' netrc entry matching all hosts) will leak their token to any redirect target
How this analysis ran 6 claims · 5 citations verified

Checked against curl master on 2026-03-03 (7079f1d39c16). Dev evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.

1 · Grounding
partially grounded
no model · 27 references checked out, 3 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
6 claims · 3399 tokens · $0.0003
3 · Evidence
12 code snippets
real curl source at 7079f1d39c16 · 4 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
17948 tokens · 10.7s · $0.0232
5 · Receipts
5 of 5 citations verified
every citation must point at code the judge was shown
Review a draft reply to the reporter

Edit and verify before sending.

Thank you for the detailed report and reproduction. The code confirms the netrc bypass at lib/http.c:822-827 skips the host check, the bearer path at lib/http.c:705-713 lacks its own check, and redirects don't clear the bearer token. This is a valid token leak. We will prepare a fix along the lines of your Option A (adding Curl_auth_allowed_to_host() inside the bearer block) or Option B (excluding bearer from the netrc bypass).

Inspect all claims and source code 6 claims · 12 code excerpts

Report claims

C1flaw supported

The netrc bypass at lib/http.c:822 skips Curl_auth_allowed_to_host() allowing bearer tokens to leak to redirect targets

Read the reasoning

The code at lib/http.c:822-827 explicitly shows that when conn->bits.netrc is set, the Curl_auth_allowed_to_host() check is bypassed via OR condition, allowing output_auth_headers to be called for any host.

C2location supported

The bearer token output path at lib/http.c:704-714 does not perform Curl_auth_allowed_to_host() check

Read the reasoning

In output_auth_headers, the CURLAUTH_BEARER case (lines 705-713) lacks any host authorization check, unlike other auth types that are gated by the caller's check at line 822.

C3trigger supported

Using --oauth2-bearer with --netrc and following a redirect causes the token to be sent to the redirect target

Read the reasoning

The redirect handling code frees user/password credentials but leaves the bearer token string and the picked auth method intact, so the token remains available for the next request.

C4impact supported

Bearer token is leaked to the redirect target host

Read the reasoning

The three code locations form a complete path: netrc bypass allows auth headers to be generated for the redirect host, the bearer output path emits the token without verifying the host, and the redirect logic fails to clear the token.

C5reproduction not verifiable

Test with curl --oauth2-bearer "SECRET_TOKEN" --netrc-file /tmp/test-netrc -L http://127.0.0.1:8080/redirect shows token in redirect server request

Read the reasoning

The reproduction script is external to curl's codebase; the provided code supports the described behavior but the test execution cannot be verified from source alone.

C6reproduction supported

Custom -H Authorization header is correctly stripped via lib/http.c:1828-1833 which uses Curl_auth_allowed_to_host() WITHOUT netrc bypass

Read the reasoning

The custom header output path correctly calls Curl_auth_allowed_to_host() without any netrc exception, confirming the report's three-way comparison.

Deterministic checks that failed

  • line none of Curl_auth_allowed_to_host, output_auth_headers, Curl_checkheaders, STRCONST appear near line 444 at 7079f1d39c16; it reads: 'const char *oauth_bearer ='
  • line none of Curl_auth_allowed_to_host, output_auth_headers, Curl_checkheaders, STRCONST appear near line 444 at 7079f1d39c16; it reads: 'const char *oauth_bearer ='
  • quote 1 of 3 quoted lines appear nowhere in curl, e.g. '|| (conn->bits.netrc && !(authhost->picked & CURLAUTH_BEARER'

What the report says about other projects

not addressed The Dec 2025 SASL fix (commit 1a822275d3, PR #19933) patched lib/curl_sasl.c but left the HTTP bearer path at lib/http.c:704-714 unprotected

Read the original report (excerpt)

Full report on HackerOne ↗

##Summary When `--oauth2-bearer` is used with `--netrc` and curl follows a redirect, the bearer token leaks to the redirect target. The netrc bypass at `http.c:822` skips `Curl_auth_allowed_to_host()`, allowing the token through. This is an incomplete fix for CVE-2025-14524 — the Dec 2025 SASL fix patched `curl_sasl.c` but missed the HTTP bearer path. This is an incomplete fix for the same vulnerability class as CVE-2025-14524. The Dec 2025 SASL bearer fix (commit `1a822275d3`, PR #19933) patched `lib/curl_sasl.c` but left the HTTP bearer path at `lib/http.c:704-714` unprotected. ## Version curl 8.10.1 (confirmed), also present in current master `d9c2c64337`. All versions supporting `--oauth2-bearer` with `--netrc` are affected. **The netrc bypass** (`lib/http.c:820-827`): ```c if(Curl_auth_allowed_to_host(data) #ifndef CURL_DISABLE_NETRC || conn->bits.netrc // <-- bypasses host check entirely #endif ) result = output_auth_headers(data, conn, authhost, request, path, FALSE); ``` **Bearer output with no host check** (`lib/http.c:704-714`): ```c if(authstatus->picked == CURLAUTH_BEARER) { if(!proxy && data->set.str[STRING_BEARER] && !Curl_checkheaders(data, STRCONST("Authorization"))) { auth = "Bearer"; result = http_output_bearer(data); // No Curl_auth_allowed_to_host() check here } } ``` **Custom -H Authorization IS correctly protected** (`lib/http.c:1828-1833`): ```c if((curlx_str_casecompare(&name, "Authorization") || curlx_str_casecompare(&name, "Cookie")) && !Curl_auth_allowed_to_host(data)) ; // Stripped - note: NO netrc bypass in this path ``` **Redirect path does NOT clear bearer** (`lib/http.c:1254-1257`): ```c if(clear) { Curl_safefree(data->state.aptr.user); Curl_safefree(data->state.aptr.passwd); // STRING_BEARER is NOT cleared // authhost->picked is NOT reset } ``` **SASL fix that missed the HTTP path** (`lib/curl_sasl.c:444-446`, commit `1a822275d3`): ```c const char *oauth_bearer = (!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ? data->set.str[STRING_BEARER] : NULL; ``` ## Reproduction Create a `.netrc` file with a default entry: ```bash echo "default login testuser password testpass" > /tmp/test-netrc ``` Save as `redirect_servers.py`: ```python import socket, threading, time def server_b(port): s = s …

Source code

lib/http.clines 795–852 · lines 822-822 cited by the report; lines 820-827 cited by the report
795 want one, and if this is one single bit it will be used instantly. */
796 authhost->picked = authhost->want;
797
798 if(authproxy->want && !authproxy->picked)
799 /* The app has selected one or more methods, but none has been picked so
800 far by a proxy round-trip. Then we set the picked one to the want one,
801 and if this is one single bit it will be used instantly. */
802 authproxy->picked = authproxy->want;
803
804#ifndef CURL_DISABLE_PROXY
805 /* Send proxy authentication header if needed */
806 if(conn->bits.httpproxy &&
807 (conn->bits.tunnel_proxy == (curl_bit)proxytunnel)) {
808 result = output_auth_headers(data, conn, authproxy, request, path, TRUE);
809 if(result)
810 return result;
811 }
812 else
813#else
814 (void)proxytunnel;
815#endif /* CURL_DISABLE_PROXY */
816 /* we have no proxy so let's pretend we are done authenticating
817 with it */
818 authproxy->done = TRUE;
819
820 /* To prevent the user+password to get sent to other than the original host
821 due to a location-follow */
822 if(Curl_auth_allowed_to_host(data)
C1: The condition at lines 822-827 shows: if(Curl_auth_allowed_to_host(data) || conn->bits.netrc) — the netrc bit bypasses the host check entirely
C4: Combined effect: netrc bypass (C1) + bearer path lacks host check (C2) + bearer not cleared on redirect (C3) = token sent to redirect target
823#ifndef CURL_DISABLE_NETRC
824 || conn->bits.netrc
825#endif
826 )
827 result = output_auth_headers(data, conn, authhost, request, path, FALSE);
828 else
829 authhost->done = TRUE;
830
831 if(((authhost->multipass && !authhost->done) ||
832 (authproxy->multipass && !authproxy->done)) &&
833 (httpreq != HTTPREQ_GET) &&
834 (httpreq != HTTPREQ_HEAD)) {
835 /* Auth is required and we are not authenticated yet. Make a PUT or POST
836 with content-length zero as a "probe". */
837 data->req.authneg = TRUE;
838 }
839 else
840 data->req.authneg = FALSE;
841
842 return result;
843}
844
845#else
846/* when disabled */
847CURLcode Curl_http_output_auth(struct Curl_easy *data,
848 struct connectdata *conn,
849 const char *request,
850 Curl_HttpReq httpreq,
851 const char *path,
852 bool proxytunnel)
lib/http.clines 627–741 · lines 704-714 cited by the report; definition of output_auth_headers
627static CURLcode output_auth_headers(struct Curl_easy *data,
628 struct connectdata *conn,
629 struct auth *authstatus,
630 const char *request,
631 const char *path,
632 bool proxy)
633{
634 const char *auth = NULL;
635 CURLcode result = CURLE_OK;
636 (void)conn;
637
638#ifdef CURL_DISABLE_DIGEST_AUTH
639 (void)request;
640 (void)path;
641#endif
642#ifndef CURL_DISABLE_AWS
643 if((authstatus->picked == CURLAUTH_AWS_SIGV4) && !proxy) {
644 /* this method is never for proxy */
645 auth = "AWS_SIGV4";
646 result = Curl_output_aws_sigv4(data);
647 if(result)
648 return result;
649 }
650 else
651#endif
652#ifdef USE_SPNEGO
653 if(authstatus->picked == CURLAUTH_NEGOTIATE) {
654 auth = "Negotiate";
655 result = Curl_output_negotiate(data, conn, proxy);
656 if(result)
657 return result;
658 }
659 else
660#endif
661#ifdef USE_NTLM
662 if(authstatus->picked == CURLAUTH_NTLM) {
663 auth = "NTLM";
664 result = Curl_output_ntlm(data, proxy);
665 if(result)
666 return result;
667 }
668 else
669#endif
670#ifndef CURL_DISABLE_DIGEST_AUTH
671 if(authstatus->picked == CURLAUTH_DIGEST) {
672 auth = "Digest";
673 result = Curl_output_digest(data,
674 proxy,
675 (const unsigned char *)request,
676 (const unsigned char *)path);
677 if(result)
678 return result;
679 }
680 else
681#endif
682#ifndef CURL_DISABLE_BASIC_AUTH
683 if(authstatus->picked == CURLAUTH_BASIC) {
684 /* Basic */
685 if(
686#ifndef CURL_DISABLE_PROXY
687 (proxy && conn->bits.proxy_user_passwd &&
688 !Curl_checkProxyheaders(data, conn,
689 STRCONST("Proxy-authorization"))) ||
690#endif
691 (!proxy && data->state.aptr.user &&
692 !Curl_checkheaders(data, STRCONST("Authorization")))) {
693 auth = "Basic";
694 result = http_output_basic(data, proxy);
695 if(result)
696 return result;
697 }
698
699 /* NOTE: this function should set 'done' TRUE, as the other auth
700 functions work that way */
701 authstatus->done = TRUE;
702 }
703#endif
704#ifndef CURL_DISABLE_BEARER_AUTH
705 if(authstatus->picked == CURLAUTH_BEARER) {
C2: The bearer auth block at lines 705-713 checks only !proxy, data->set.str[STRING_BEARER], and !Curl_checkheaders — no Curl_auth_allowed_to_host() call
706 /* Bearer */
707 if(!proxy && data->set.str[STRING_BEARER] &&
708 !Curl_checkheaders(data, STRCONST("Authorization"))) {
709 auth = "Bearer";
710 result = http_output_bearer(data);
711 if(result)
712 return result;
713 }
714
715 /* NOTE: this function should set 'done' TRUE, as the other auth
716 functions work that way */
717 authstatus->done = TRUE;
718 }
719#endif
720
721 if(auth) {
722#ifndef CURL_DISABLE_PROXY
723 infof(data, "%s auth using %s with user '%s'",
724 proxy ? "Proxy" : "Server", auth,
725 proxy ? (data->state.aptr.proxyuser ?
726 data->state.aptr.proxyuser : "") :
727 (data->state.aptr.user ?
728 data->state.aptr.user : ""));
729#else
730 (void)proxy;
731 infof(data, "Server auth using %s with user '%s'",
732 auth, data->state.aptr.user ?
733 data->state.aptr.user : "");
734#endif
735 authstatus->multipass = !authstatus->done;
736 }
737 else
738 authstatus->multipass = FALSE;
739
740 return result;
741}
lib/http.clines 1803–1858 · lines 1828-1833 cited by the report
1803 /* a Host: header was sent already, do not pass on any custom
1804 Host: header as that will produce *two* in the same
1805 request! */
1806 curlx_str_casecompare(&name, "Host"))
1807 ;
1808 else if(data->state.httpreq == HTTPREQ_POST_FORM &&
1809 /* this header (extended by formdata.c) is sent later */
1810 curlx_str_casecompare(&name, "Content-Type"))
1811 ;
1812 else if(data->state.httpreq == HTTPREQ_POST_MIME &&
1813 /* this header is sent later */
1814 curlx_str_casecompare(&name, "Content-Type"))
1815 ;
1816 else if(data->req.authneg &&
1817 /* while doing auth neg, do not allow the custom length since
1818 we will force length zero then */
1819 curlx_str_casecompare(&name, "Content-Length"))
1820 ;
1821 else if(curlx_str_casecompare(&name, "Connection"))
1822 /* Connection headers are handled specially */
1823 ;
1824 else if((httpversion >= 20) &&
1825 curlx_str_casecompare(&name, "Transfer-Encoding"))
1826 /* HTTP/2 does not support chunked requests */
1827 ;
1828 else if((curlx_str_casecompare(&name, "Authorization") ||
C6: Lines 1828-1833 show custom Authorization/Cookie headers are suppressed when curlx_str_casecompare matches 'Authorization' or 'Cookie', the header is omitted if !Curl_auth_allowed_to_host(data) — no netrc bypass here
1829 curlx_str_casecompare(&name, "Cookie")) &&
1830 /* be careful of sending this potentially sensitive header to
1831 other hosts */
1832 !Curl_auth_allowed_to_host(data))
1833 ;
1834 else if(blankheader)
1835 result = curlx_dyn_addf(req, "%.*s:\r\n", (int)curlx_strlen(&name),
1836 curlx_str(&name));
1837 else
1838 result = curlx_dyn_addf(req, "%s\r\n", origp);
1839
1840 if(result)
1841 return result;
1842 }
1843 }
1844
1845 return CURLE_OK;
1846}
1847
1848#ifndef CURL_DISABLE_PARSEDATE
1849CURLcode Curl_add_timecondition(struct Curl_easy *data,
1850 struct dynbuf *req)
1851{
1852 const struct tm *tm;
1853 struct tm keeptime;
1854 CURLcode result;
1855 char datestr[80];
1856 const char *condp;
1857 size_t len;
1858
lib/http.clines 1229–1282 · lines 1254-1257 cited by the report
1229 port = (int)value;
1230 curlx_free(portnum);
1231 }
1232 if(port != data->info.conn_remote_port) {
1233 infof(data, "Clear auth, redirects to port from %u to %u",
1234 data->info.conn_remote_port, port);
1235 clear = TRUE;
1236 }
1237 else {
1238 char *scheme;
1239 const struct Curl_scheme *p;
1240 uc = curl_url_get(data->state.uh, CURLUPART_SCHEME, &scheme, 0);
1241 if(uc) {
1242 curlx_free(follow_url);
1243 return Curl_uc_to_curlcode(uc);
1244 }
1245
1246 p = Curl_get_scheme(scheme);
1247 if(p && (p->protocol != data->info.conn_protocol)) {
1248 infof(data, "Clear auth, redirects scheme from %s to %s",
1249 data->info.conn_scheme, scheme);
1250 clear = TRUE;
1251 }
1252 curlx_free(scheme);
1253 }
1254 if(clear) {
C3: Lines 1254-1257 clear user and passwd on redirect but do not clear STRING_BEARER or reset authhost->picked
1255 Curl_safefree(data->state.aptr.user);
1256 Curl_safefree(data->state.aptr.passwd);
1257 }
1258 }
1259 }
1260 DEBUGASSERT(follow_url);
1261
1262 if(type == FOLLOW_FAKE) {
1263 /* we are only figuring out the new URL if we would have followed locations
1264 but now we are done so we can get out! */
1265 data->info.wouldredirect = follow_url;
1266
1267 if(reachedmax) {
1268 failf(data, "Maximum (%d) redirects followed", data->set.maxredirs);
1269 return CURLE_TOO_MANY_REDIRECTS;
1270 }
1271 return CURLE_OK;
1272 }
1273
1274 if(disallowport)
1275 data->state.allow_port = FALSE;
1276
1277 Curl_bufref_set(&data->state.url, follow_url, 0, curl_free);
1278 rewind_result = Curl_req_soft_reset(&data->req, data);
1279 infof(data, "Issue another request to this URL: '%s'", follow_url);
1280 if((data->set.http_follow_mode == CURLFOLLOW_FIRSTONLY) &&
1281 data->set.str[STRING_CUSTOMREQUEST] &&
1282 !data->state.http_ignorecustom) {
lib/vauth/vauth.clines 138–147 · definition of Curl_auth_allowed_to_host
Show 10 lines (not cited by the judge)
138bool Curl_auth_allowed_to_host(struct Curl_easy *data)
139{
140 struct connectdata *conn = data->conn;
141 return !data->state.this_is_a_follow ||
142 data->set.allow_auth_to_other_hosts ||
143 (data->state.first_host &&
144 curl_strequal(data->state.first_host, conn->host.name) &&
145 (data->state.first_remote_port == conn->remote_port) &&
146 (data->state.first_remote_protocol == conn->scheme->protocol));
147}
lib/vauth/vauth.c@curl-8_18_0lines 138–147 · definition of Curl_auth_allowed_to_host as in release curl-8_18_0; differs from master; commits that changed it since: 8edc0338f3 lib: separate scheme info from protocol implementation
Show 10 lines (not cited by the judge)
138bool Curl_auth_allowed_to_host(struct Curl_easy *data)
139{
140 struct connectdata *conn = data->conn;
141 return !data->state.this_is_a_follow ||
142 data->set.allow_auth_to_other_hosts ||
143 (data->state.first_host &&
144 curl_strequal(data->state.first_host, conn->host.name) &&
145 (data->state.first_remote_port == conn->remote_port) &&
146 (data->state.first_remote_protocol == conn->handler->protocol));
147}
lib/transfer.clines 84–99 · definition of Curl_checkheaders
Show 16 lines (not cited by the judge)
84char *Curl_checkheaders(const struct Curl_easy *data,
85 const char *thisheader,
86 const size_t thislen)
87{
88 struct curl_slist *head;
89 DEBUGASSERT(thislen);
90 DEBUGASSERT(thisheader[thislen - 1] != ':');
91
92 for(head = data->set.headers; head; head = head->next) {
93 if(curl_strnequal(head->data, thisheader, thislen) &&
94 Curl_headersep(head->data[thislen]))
95 return head->data;
96 }
97
98 return NULL;
99}
lib/curl_setup.hlines 1314–1318 · definition of Curl_safefree
Show 5 lines (not cited by the judge)
1314#define Curl_safefree(ptr) \
1315 do { \
1316 curlx_free(ptr); \
1317 (ptr) = NULL; \
1318 } while(0)
lib/curl_setup.hlines 1280–1280 · definition of STRCONST
Show 1 lines (not cited by the judge)
1280#define STRCONST(x) x, sizeof(x) - 1
lib/curlx/strparse.clines 239–243 · definition of curlx_str_casecompare
Show 5 lines (not cited by the judge)
239int curlx_str_casecompare(struct Curl_str *str, const char *check)
240{
241 size_t clen = check ? strlen(check) : 0;
242 return ((str->len == clen) && curl_strnequal(str->str, check, clen));
243}
lib/http.clines 308–325 · definition of http_output_bearer
Show 18 lines (not cited by the judge)
308static CURLcode http_output_bearer(struct Curl_easy *data)
309{
310 char **userp;
311 CURLcode result = CURLE_OK;
312
313 userp = &data->state.aptr.userpwd;
314 curlx_free(*userp);
315 *userp = curl_maprintf("Authorization: Bearer %s\r\n",
316 data->set.str[STRING_BEARER]);
317
318 if(!*userp) {
319 result = CURLE_OUT_OF_MEMORY;
320 goto fail;
321 }
322
323fail:
324 return result;
325}
lib/http.c@curl-8_18_0lines 648–761 · definition of output_auth_headers as in release curl-8_18_0; differs from master; commits that changed it since: af78b199b2 tidy-up: miscellaneous
Show 114 lines (not cited by the judge)
648static CURLcode output_auth_headers(struct Curl_easy *data,
649 struct connectdata *conn,
650 struct auth *authstatus,
651 const char *request,
652 const char *path,
653 bool proxy)
654{
655 const char *auth = NULL;
656 CURLcode result = CURLE_OK;
657 (void)conn;
658
659#ifdef CURL_DISABLE_DIGEST_AUTH
660 (void)request;
661 (void)path;
662#endif
663#ifndef CURL_DISABLE_AWS
664 if((authstatus->picked == CURLAUTH_AWS_SIGV4) && !proxy) {
665 /* this method is never for proxy */
666 auth = "AWS_SIGV4";
667 result = Curl_output_aws_sigv4(data);
668 if(result)
669 return result;
670 }
671 else
672#endif
673#ifdef USE_SPNEGO
674 if(authstatus->picked == CURLAUTH_NEGOTIATE) {
675 auth = "Negotiate";
676 result = Curl_output_negotiate(data, conn, proxy);
677 if(result)
678 return result;
679 }
680 else
681#endif
682#ifdef USE_NTLM
683 if(authstatus->picked == CURLAUTH_NTLM) {
684 auth = "NTLM";
685 result = Curl_output_ntlm(data, proxy);
686 if(result)
687 return result;
688 }
689 else
690#endif
691#ifndef CURL_DISABLE_DIGEST_AUTH
692 if(authstatus->picked == CURLAUTH_DIGEST) {
693 auth = "Digest";
694 result = Curl_output_digest(data,
695 proxy,
696 (const unsigned char *)request,
697 (const unsigned char *)path);
698 if(result)
699 return result;
700 }
701 else
702#endif
703#ifndef CURL_DISABLE_BASIC_AUTH
704 if(authstatus->picked == CURLAUTH_BASIC) {
705 /* Basic */
706 if(
707#ifndef CURL_DISABLE_PROXY
708 (proxy && conn->bits.proxy_user_passwd &&
709 !Curl_checkProxyheaders(data, conn, STRCONST("Proxy-authorization"))) ||
710#endif
711 (!proxy && data->state.aptr.user &&
712 !Curl_checkheaders(data, STRCONST("Authorization")))) {
713 auth = "Basic";
714 result = http_output_basic(data, proxy);
715 if(result)
716 return result;
717 }
718
719 /* NOTE: this function should set 'done' TRUE, as the other auth
720 functions work that way */
721 authstatus->done = TRUE;
722 }
723#endif
724#ifndef CURL_DISABLE_BEARER_AUTH
725 if(authstatus->picked == CURLAUTH_BEARER) {
726 /* Bearer */
727 if((!proxy && data->set.str[STRING_BEARER] &&
728 !Curl_checkheaders(data, STRCONST("Authorization")))) {
729 auth = "Bearer";
730 result = http_output_bearer(data);
731 if(result)
732 return result;
733 }
734
735 /* NOTE: this function should set 'done' TRUE, as the other auth
736 functions work that way */
737 authstatus->done = TRUE;
738 }
739#endif
740
741 if(auth) {
742#ifndef CURL_DISABLE_PROXY
743 infof(data, "%s auth using %s with user '%s'",
744 proxy ? "Proxy" : "Server", auth,
745 proxy ? (data->state.aptr.proxyuser ?
746 data->state.aptr.proxyuser : "") :
747 (data->state.aptr.user ?
748 data->state.aptr.user : ""));
749#else
750 (void)proxy;
751 infof(data, "Server auth using %s with user '%s'",
752 auth, data->state.aptr.user ?
753 data->state.aptr.user : "");
754#endif
755 authstatus->multipass = !authstatus->done;
756 }
757 else
758 authstatus->multipass = FALSE;
759
760 return result;
761}