winapi - NTLM Authorization in Perl -
i trying implement ntlm authorisation web server written in perl (or perhaps xs module). understanding should work in following way:
c -> s: s -> c: 401, www-authenticate: ntlm c -> s: get, authorization: ntlm [type1 message] s -> c: 401, www-authenticate: ntlm [type2 message] c -> s: get, authorization: ntlm [type3 message] if s.check([type3 message]): s -> c: 200 else: s -> c: 401
to generate type3 message have used both authen::perl::ntlm , authen::ntlm::http, both of these seem generate messages fine, however, offer no functionality check type3 message.
my next step has been try , use win32::intauth authenticate ntlm token. this have been running in trouble, developer , other snippets of information found searching module should able authenticate ntlm binary token.
the module wraps around win32 api calls, namely acquirecredntialshandle, acceptsecuritycontext, completeauthtoken , impersonatesecuritycontext.
unfortunately attempts authenticate ntlm token have failed @ acceptsecuritycontext either sec_e_invalid_token or sec_e_insufficient_memory leading me suggest ntlm token isn't correct. below snippets of code show methods.
# other code ... if (not defined $headers->header('authorization')) { inithandshake($response); } else { $authheader = $headers->header('authorization'); if ($authheader =~ m/^ntlm\s(.+)$/i) { $message = $1; if (length($message) == 56) { handletype1($response, $message); } else { handletype3($response, $message); } } else { printf "error - unable pull out ntlm message.\n"; print $authheader . "\n"; } } ... sub handletype3 { $response = shift(); $message = shift(); print "handletype3 - ", $message, "\n"; $auth = win32::intauth->new(debug => 1); $token = $auth->get_token_upn(decode_base64($message)) or die "couldn'timpersonate user, ", $auth->last_err_txt(); print "hurrargh. user ", $auth->get_username(), " authed!\n"; $response->status(200); } ..
the full code can viewed here: http://codepad.org/cpmwnfru
i managed working bastardizing win32::intauth (which believe has bug in it). wasn't holding partial context created during creation of type 2 token, , fact there error in win32::intauth:
my $buf_size = 4096; $sec_inbuf = pack("l l p$buf_size", $buf_size, secbuffer_token, $token);
this causing token error wasn't correct length of token, therefore:
my $sec_inbuf = pack("l l p" . length($token), length($token), secbuffer_token, $token);
produced correct results.
the previous code changed to:
... sub handletype1 { $response = shift(); $message = shift(); print "handletype1 - |", ${$message}, "|\n"; $challenge = acceptsecuritycontext(${$message}); ${$response}->status(401); ${$response}->header("www-authenticate" => "ntlm " . $challenge); } ... sub handletype3 { $response = shift(); $message = shift(); print "handletype3 - ", ${$message}, "\n"; if (acceptsecuritycontext(${$message})) { ${$response}->status(200); } else { ${$response}->status(401); } } ...
acceptsecuritycontext function follows pseudoish code:
credentials = win32->acquirecredentialshandle(...) challenge = win32->acceptsecuritycontext(credentials, token, globalctx ? globalctx : 0, ...)
hopefully helps people might in similar boat. feel free contact me full demo.
Comments
Post a Comment