@@ -787,19 +787,20 @@ static void ntlm_stop(struct HXproc &pi)
787787 pi.p_pid = 0 ;
788788}
789789
790- static int auth_ntlmssp (http_context &ctx, const char *encinput, size_t encsize ,
791- const char *input, size_t isize , std::string &output)
790+ static int htp_auth_ntlmssp (http_context &ctx, const char *prog ,
791+ const char *encinput , std::string &output)
792792{
793+ auto encsize = strlen (encinput);
793794 auto &pinfo = ctx.ntlm_proc ;
794795 output.clear ();
795796
796797 if (pinfo.p_pid <= 0 ) {
797- auto prog = g_config_file->get_value (" ntlm_auth" );
798798 if (prog == nullptr || *prog == ' \0 ' )
799- prog = " /usr/bin/ntlm_auth" ;
800- const char *argv[] = {prog, " -d0" , " --helper-protocol=squid-2.5-ntlmssp" , nullptr };
799+ prog = " /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp" ;
800+ auto args = HX_split (prog, " " , nullptr , 0 );
801+ auto cl_0 = make_scope_exit ([&]() { HX_zvecfree (args); });
801802 pinfo.p_flags = HXPROC_STDIN | HXPROC_STDOUT | HXPROC_STDERR;
802- auto ret = HXproc_run_async (argv , &pinfo);
803+ auto ret = HXproc_run_async (&args[ 0 ] , &pinfo);
803804 if (ret < 0 ) {
804805 mlog (LV_ERR, " execv ntlm_auth: %s" , strerror (-ret));
805806 return -1 ;
@@ -1005,6 +1006,38 @@ static int auth_krb(http_context &ctx, const char *input, size_t isize,
10051006}
10061007#endif
10071008
1009+ static tproc_status htp_auth_spnego (http_context &ctx, const char *past_method)
1010+ {
1011+ bool rq_ntlmssp = strncmp (past_method, " TlRMTVNT" , 8 ) == 0 ;
1012+ auto the_helper = g_config_file->get_value (rq_ntlmssp ? " ntlmssp_program" : " gss_program" );
1013+
1014+ if (strcmp (the_helper, " internal-gss" ) != 0 ) {
1015+ auto ret = htp_auth_ntlmssp (ctx, the_helper, past_method,
1016+ ctx.last_gss_output );
1017+ ctx.auth_status = ret <= 0 ? http_status::unauthorized : http_status::ok;
1018+ ctx.auth_method = auth_method::negotiate_b64;
1019+ if (ret <= 0 && ret != -99 )
1020+ ntlm_stop (ctx.ntlm_proc );
1021+ } else {
1022+ #ifdef HAVE_GSSAPI
1023+ char decoded[4096 ];
1024+ size_t decode_len = 0 ;
1025+ if (decode64 (past_method, strlen (past_method), decoded,
1026+ std::size (decoded), &decode_len) != 0 )
1027+ return tproc_status::runoff;
1028+ auto ret = auth_krb (ctx, decoded, decode_len, ctx.last_gss_output );
1029+ ctx.auth_status = ret <= 0 ? http_status::unauthorized : http_status::ok;
1030+ ctx.auth_method = auth_method::negotiate;
1031+ #else
1032+ static bool y = false ;
1033+ if (!y)
1034+ mlog (LV_DEBUG, " Cannot handle Negotiate request: software built without GSSAPI" );
1035+ y = true ;
1036+ #endif
1037+ }
1038+ return tproc_status::runoff;
1039+ }
1040+
10081041/*
10091042 * Implementation notes.
10101043 *
@@ -1055,38 +1088,16 @@ static tproc_status htp_auth(http_context &ctx)
10551088 *p++ = ' \0 ' ;
10561089 gx_strlcpy (ctx.username , decoded, std::size (ctx.username ));
10571090 gx_strlcpy (ctx.password , p, std::size (ctx.password ));
1058- return htp_auth_basic (&ctx);
1059- } else if (strcasecmp (method, " Negotiate" ) == 0 &&
1060- strncmp (past_method, " TlRMTVNT" , 8 ) == 0 &&
1061- g_config_file->get_ll (" http_auth_spnego" ) &&
1062- g_config_file->get_ll (" http_auth_spnego_ntlmssp" )) {
1063- char decoded[4096 ];
1064- size_t decode_len = 0 ;
1065- if (decode64 (past_method, strlen (past_method), decoded, std::size (decoded), &decode_len) != 0 )
1066- return tproc_status::runoff;
1067- auto ret = auth_ntlmssp (ctx, past_method, strlen (past_method),
1068- decoded, decode_len, ctx.last_gss_output );
1069- ctx.auth_status = ret <= 0 ? http_status::unauthorized : http_status::ok;
1070- ctx.auth_method = auth_method::negotiate_b64;
1071- if (ret <= 0 && ret != -99 )
1072- ntlm_stop (ctx.ntlm_proc );
1091+ auto ret = htp_auth_basic (&ctx);
1092+ if (ret != tproc_status::runoff)
1093+ return ret;
10731094 } else if (strcasecmp (method, " Negotiate" ) == 0 &&
10741095 g_config_file->get_ll (" http_auth_spnego" )) {
1075- #ifdef HAVE_GSSAPI
1076- char decoded[4096 ];
1077- size_t decode_len = 0 ;
1078- if (decode64 (past_method, strlen (past_method), decoded, std::size (decoded), &decode_len) != 0 )
1079- return tproc_status::runoff;
1080- auto ret = auth_krb (ctx, decoded, decode_len, ctx.last_gss_output );
1081- ctx.auth_status = ret <= 0 ? http_status::unauthorized : http_status::ok;
1082- ctx.auth_method = auth_method::negotiate;
1083- #else
1084- static bool y = false ;
1085- if (!y)
1086- mlog (LV_DEBUG, " Cannot handle Negotiate request: software built without GSSAPI" );
1087- y = true ;
1088- #endif
1096+ auto ret = htp_auth_spnego (ctx, past_method);
1097+ if (ret != tproc_status::runoff)
1098+ return ret;
10891099 }
1100+
10901101 if (g_enforce_auth && ctx.auth_status != http_status::ok)
10911102 ctx.auth_status = http_status::unauthorized;
10921103 return tproc_status::runoff;
0 commit comments