# Ruby Win32 SSPI 0.0.1 - Enabling NTLM/Negotiate proxy authen

**URL:** <https://www.ruby-forum.com/t/ruby-win32-sspi-0-0-1-enabling-ntlm-negotiate-proxy-authen/98491>\
**Category:** Ruby\
**Created:** [July 15, 2006, 12:57am UTC](https://www.ruby-forum.com/t/ruby-win32-sspi-0-0-1-enabling-ntlm-negotiate-proxy-authen/98491 "2006-07-15T00:57:27Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [July 15, 2006, 12:57am UTC](https://www.ruby-forum.com/t/ruby-win32-sspi-0-0-1-enabling-ntlm-negotiate-proxy-authen/98491/1 "2006-07-15T00:57:27Z")

</div>

My work place implemented install a proxy server recently, and because  
it  
demands NTLM/Negotiate authentication, a bunch of my “utility” scripts  
that  
scraped the web for me stopped working. Well, that sounded like the  
opportunity to develop a cool Ruby library!

This library provides bindings to the Win32 SSPI library, which enables  
authentication as the current user with proxy servers using the  
“Negotiate”/SPNEGO protocol (which typically just means NTLM).

There are some pure Ruby implementations of the NTLM protocol, but this  
is  
the only one I know of that will authenticate with a proxy server as the  
current user - meaning you don’t have to put your username or password  
in an  
environment variable or anywhere else.

The library also includes a patch for open-uri and Net:HTTP that will  
make  
the authentication process seamless.

I have only tested this in my own environment so I’m sure its fragile.  
Please try it out if you have run into this issue yourself.

The project can be found at:

---

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [July 15, 2006, 1:10am UTC](https://www.ruby-forum.com/t/ruby-win32-sspi-0-0-1-enabling-ntlm-negotiate-proxy-authen/98491/2 "2006-07-15T01:10:26Z")

</div>

- fingers slipped and I sent previous announcement early - oops! \*

My work place implemented install a proxy server recently, and because  
it  
demands NTLM/Negotiate authentication, a bunch of my “utility” scripts  
that  
scraped the web for me stopped working. Well, that sounded like the  
opportunity to develop a cool Ruby library!

This library provides bindings to the Win32 SSPI library, which enables  
authentication as the current user with proxy servers using the  
“Negotiate”/SPNEGO protocol (which typically just means NTLM).

There are some pure Ruby implementations of the NTLM protocol, but this  
is  
the only one I know of that will authenticate with a proxy server as the  
current user - meaning you don’t have to put your username or password  
in an  
environment variable or anywhere else.

The library also includes a patch for open-uri and Net:HTTP that will  
make  
the authentication process seamless.

I have only tested this in my own environment so I’m sure its fragile.  
Please try it out if you have run into this issue yourself.

The project can be found at: [http://rubyforge.org/projects/rubysspi/](http://rubyforge.org/projects/rubysspi/)

Gem install will be available when the index updates:

gem install rubysspi

Documentation is available in the gem, but here is the README from the  
distribution. Comments and feedback welcome!

Justin

=== README ===

= Introduction

This library provides bindings to the Win32 SSPI libraries, which  
implement  
various security protocols for Windows. The library was primarily  
developed  
to give Negotiate/NTLM proxy authentication abilities to Net::HTTP,  
similar  
to support found in Internet Explorer or Firefox.

The libary is NOT an implementation of the NTLM protocol, and does not  
give  
the ability to authenticate as any given user. It is able to  
authenticate  
with a proxy server as the current user.

This project can be found on rubyforge at:

[http://rubyforge.org/projects/rubysspi](http://rubyforge.org/projects/rubysspi)

= Using with open-uri

To use the library with open-uri, make sure to set the environment  
variable  
+http\_proxy+ to your proxy server. This must be a hostname and port in  
URL  
form. E.g.:

[http://proxy.corp.com:8080](http://proxy.corp.com:8080)

The library will grab your current username and domain from the  
environment  
variables +USERNAME+ and +USERDOMAIN+. This should be set for you by  
Windows  
already.

The library implements a patch on top of Net::HTTP, which means open-uri  
gets it too. At the top of your script, make sure to require the patch  
after  
+open-uri+:

require +open-uri+  
require +rubysspi/proxy\_auth+

open(“[http://www.google.com](http://www.google.com)”) { |f| puts(f.gets(nil)) }

Note that this patch does NOT work with the +http\_proxy\_user+ and  
+http\_proxy\_password+ environment variables. The library will ONLY  
authenticate as the current user.

= Using with Net::HTTP

Net::HTTP will not use the proxy server supplied in the environment  
variable  
automatically, so you have to supply the proxy address yourself.  
Otherwise,  
it’s exactly the same:

require ‘net/http’  
require 'rubysspi/proxy\_auth+

Net::HTTP::Proxy(“[proxy.corp.com](http://proxy.corp.com)”, 8080).start(“[www.google.com](http://www.google.com)”) do  
|http|  
resp = http.request\_get “/”  
puts resp.body  
end

= Using rubysspi directly

As stated, the library is geared primarily towards supporting  
Negotiate/NTLM  
authentication with proxy servers. In this vein, you can manually  
authenticate a given HTTP connection with a single call:

require ‘rubysspi’

Net::HTTP.Proxy(proxy.host, proxy.port).start(“[www.google.com](http://www.google.com)”) do  
|http|  
resp = SSPI::NegotiateAuth.proxy\_auth\_get http, “/”  
end

The +resp+ variable will contain the response from Google, with any  
proxy  
authorization necessary taken care of automatically. Note that if the  
+http+  
connection is not closed, any subsequent requests will NOT require  
authentication.

If the above method is used, it is recommended that you do NOT require  
the  
‘rubysspi/proxy\_auth’ library, as the interaction between the two will  
fail.

The library can be used directly to generate tokens appropriate for the  
current user, too.

To get started, first create an instance of the SSPI::NegotiateAuth  
class:

require ‘rubysspi’

n = SSPI::NegotiateAuth.new

Next, get the first token by calling get\_initial\_token:

token = n.get\_initial\_token

This token returned will be Base64 encoded and can be directly placed in  
an  
HTTP header. This token can be easily decoded, however, and is usually  
an  
NTLM Type 1 message.

After getting a response from the server (usually an NTLM Type 2  
message),  
pass it into the complete\_authentication:

token = n.complete\_authentication(server\_token)

Note that server\_token can be Base64 encoded or not, and if it starts  
with  
“Negotiate”, that phrase will be stripped off. This allows the response  
from  
a Proxy-Authentication header to be passed into the method directly. The  
token can be decoded externally and passed in, too.

The token returned (usually an NTLM Type 3) message can then be sent to  
the  
server and the connection should be authenticated.

= Thanks & References

Many references were used in decoding both NTLM messages and integrating  
with the SSPI library. Among them are:

- Managed SSPI Sample - A .NET implementation of a simple client/server  
using SSPI. A complex undertaking but provides a great resource for  
playing  
with the API.  
\*  
[Technical documentation | Microsoft Learn](http://msdn.microsoft.com/library/?url=/library/en-us/dndotnet/html/remsspi.asp?frame=true)
- John L.'s RubyCLR - [http://www.rubyclr.com](http://www.rubyclr.com)
  - Originally, I used RubyCLR to call into the Managed SSPI sample  
which  
really helped me decode what the SSPI interface did and how it worked. I  
did  
not end up using that implementation but it was great for research.

- The NTLM Authentication Protocol - The definitive explanation for the  
NTLM  
protocol (outside MS internal documents, I presume).
  - [The NTLM Authentication Protocol and Security Support Provider](http://davenport.sourceforge.net/ntlm.html)

- Ruby/NTLM - A pure Ruby implementation of the NTLM protocol. Again,  
not  
used in this project but invaluable for decoding NTLM messages and  
figuring  
out what SSPI was returning.
  - [http://rubyforge.org/projects/rubyntlm/](http://rubyforge.org/projects/rubyntlm/)

- Seamonkey/Mozilla NTLM implementation - The only source for an  
implementation in an actual browser. How they figured out how to use  
SSPI  
themselves is beyond me.  
\*  
[http://lxr.mozilla.org/seamonkey/source/mailnews/base/util/nsMsgProtocol.cpp#899](http://lxr.mozilla.org/seamonkey/source/mailnews/base/util/nsMsgProtocol.cpp#899)

And of course, thanks to my Lord and Savior, Jesus Christ. In the name  
of  
the Father, the Son, and the Holy Spirit.
