Categories
Coding

NTLM Proxy Authentication with Neon

Neon is really a great library, and has recently been released as version 0.25.0, which has built-in support for NTLM authentication. Here is a sample program showing how this can be used in practise.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ne_socket.h"
#include "ne_session.h"
#include "ne_request.h"
#include "ne_auth.h"

typedef struct {
static const int challenge_issued = 0;
} user_data;

/*
* Response reader callback function
*
*/
void my_response_reader(void *userdata, const char *buf, size_t len) {
printf("Received: %s\n", buf);
}

/*
* Authentication callback
*/

static int my_auth(void *userdata, const char *realm, int attempts, char *username, char *password)
{
strncpy(username, "username", NE_ABUFSIZ);
strncpy(password, "password", NE_ABUFSIZ);
user_data* data = (user_data*)userdata;
return attempts;
}

int main(int argc, char* argv[]) {
user_data data;
int success = ne_sock_init();
char dropbuf[4096];

if (success != 0) {
printf("Cannot initialize Neon library");
exit(1);
}

ne_session* session = ne_session_create("http", "www.google.com", 80);
ne_session_proxy(session, "proxy1.researchkitchen.co.uk", 8080);
ne_set_proxy_auth(session, my_auth, (void*)&data);
ne_request *req = ne_request_create(session, "GET", "/");
ne_add_request_header(req, "Connection", "Keep-Alive");

ne_debug_init(stdout, NE_DBG_HTTPAUTH);

if (ne_request_dispatch(req))
{
printf("An error occurred\n");
const char* error = ne_get_error(session);
printf("%s", error);
exit(1);
}
else
{
printf("Response status code was %d\n", ne_get_status(req)->code);
ne_request_destroy(req);
}

ne_close_connection(session);
ne_session_destroy(session);
return 0;
}

Categories
Coding

JDK-Based NTLM Authentication

When Sun released the 1.4.2 version of the JDK, they slipped in support for native NTLM authentication on Windows. This is done by retrieving the logged-on user’s username and password from the OS whenever an NTLM challenge is received. The only information that needs to be supplied is the NT domain. Here is an example that authenticates through an MS proxy, using my currently active credentials.


package uk.co.researchkitchen.ntlm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

public class TestJDKNTLM {

    private void execute() throws IOException {
        System.setProperty("proxySet""true");
        System.setProperty("http.proxyHost""proxy1.researchkitchen.co.uk");
        System.setProperty("http.proxyPort""8080");
        System.setProperty("http.auth.ntlm.domain""MYDOMAIN");

        URL url = new URL("http://www.yahoo.com");
        URLConnection conn = url.openConnection();

        conn.setAllowUserInteraction(true);
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        int read = 0;
        String body = null;

        do {
          body = reader.readLine();
          System.out.println(body);
        while (body != null);

    }

    public static void main(String[] argsthrows IOException {
        new TestJDKNTLM().execute();
    }

}

Categories
Coding

NTLM Proxy Authentication and Jakarta HttpClient

In my current work environment, our Web access is proxied via a MS ISA server, which uses NTML proxy authentication. I was recently looking at NTLM proxy authentication, as I had problems running Subversion inside the proxy (this should be fixed now with the newest release of Neon, Subversion’s WebDAV layer). I am currently looking at some NTLM providers in the Java space, and one of the obvious ones I came across is the Jakarta HttpClient. Here is an example that will authenticate to an NTLM-based proxy. The code is for HttpClient 3.0-RC2.


package uk.co.researchkitchen.ntlm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.auth.AuthPolicy;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;

public class TestNTLM {

    private void execute() throws HttpException, IOException {
        HttpClient proxyclient = new HttpClient();

        proxyclient.getHostConfiguration().setHost("www.yahoo.com");
        proxyclient.getHostConfiguration().setProxy("lproxyhost.researchkitchen.co.uk"8080);


        List authPrefs = new ArrayList();
        authPrefs.add(AuthPolicy.NTLM);

        proxyclient.getState().setProxyCredentials(
            new AuthScope(null, 8080null),
            new NTCredentials("username""password""""MYDOMAIN"));

        proxyclient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);

        GetMethod get = new GetMethod("/");
        int status = proxyclient.executeMethod(get);

        System.out.println(status);

        BufferedReader bis = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream()));

        int count = 0;
        int read = 0;
        System.out.println("Content length: " + get.getResponseContentLength());
        char[] body = new char[2048];
        do {
          count = bis.read(body);
          read += count;
          System.out.println(body);
        while (count != -1);

        System.out.println("Read " + read + " bytes");
    }


    public static void main(String[] argsthrows HttpException, IOException {
        new TestNTLM().execute();
    }

}