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

Popular posts from this blog

c# - How to get the current UAC mode -

postgresql - Lazarus + Postgres: incomplete startup packet -

javascript - Ajax jqXHR.status==0 fix error -