lundi 28 juillet 2008

Bonjour Robert B3302!

Aha, there we go! Finally our Tomcat Server was able to say Bonjour Robert! Well, not quite, since Robert's first name is actually Robert B3302 but hey who would like their name not spelled entirely?

So how did we get there?

Well any HTTP Servlet should implement the following methods:

doGet(HttpServletRequest request, HttpServletResponse response)
doPost (HttpServletRequest request, HttpServletResponse response)

Whenever a GET or POST request is sent to the server from the HTTP Client, either the doGet or doPost method is triggered. We can then use the request and response parameters to treat incoming information and return the results.

This looks a bit like this:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Enumeration headers = request.getHeaderNames();

String message = new String("");
message += "Bonjour " +request.getHeader("First_Name")+"!\n";
Writer w = response.getWriter();
w.write(message);
}


This extracts the value of the "First_Name" header from the GET request and sends the response "Bonjour !"

Now how are we going to make sure the first name of Robert is present in this "First_Name" header. Well since Robert
identified himself with his eID card, the informations of his certificate are set as environment variables on the apache server. There is a CGI script called "printenv" in any apache server that gives the current environment variables and their value. If we connect in SSL on our proxy and trigger this script ( https://localhost/cgi-bin/printenv ), here is what we get:

DOCUMENT_ROOT="/usr/local/apache2/htdocs"
GATEWAY_INTERFACE="CGI/1.1"
HTTPS="on"
HTTP_ACCEPT="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
HTTP_ACCEPT_CHARSET="ISO-885
9-1,utf-8;q=0.7,*;q=0.7"
HTTP_ACCEPT_ENCODING="gzip,deflate"
HTTP_ACCEPT_LANGUAGE="en-us,en;q=0.5"
HTTP_CERTIFICATE_INFO="/C=BE/CN=Robert SPECIMEN (Authentication)/SN=SPECIMEN/GN=Robert B3302/serialNumber=71717100052"
HTTP_CERTIFICATE_NAME="Robert SPECIMEN (Authentication)"
HTTP_CONNECTION="keep-alive"
HTTP_COUNTRY_CODE="BE"
HTTP_HOST="192.168.212.128"
HTTP_KEEP_ALIVE="300"
HTTP_NATIONAL_REGISTER="71717100052"
HTTP_USER_AGENT="Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.1) Gecko/2008070206 Firefox/3.0.1"
HTTP_USER_NAME="(null)"

HTTP_USER_SURNAME="(null)"
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin"
QUERY_STRING=""
REMOTE_ADDR="192.168.212.1"
REMOTE_PORT="51616"
REQUEST_METHOD="GET"
REQUEST_URI="/cgi-bin/printenv"
SCRIPT_FILENAME="/usr/local/apache2/cgi-bin/printenv"
SCRIPT_NAME="/cgi-bin/printenv"
SERVER_ADDR="192.168.212.128"
SERVER_ADMIN="you@example.com"
SERVER_NAME="192.168.212.128"

SERVER_PORT="443"
SERVER_PROTOCOL="HTTP/1.1"
SERVER_SIGNATURE="
Apache/2.0.54 (Unix) mod_ssl/2.0.54+OCSP (1.0.8) OpenSSL/0.9.8g Server at 192.168.212.128 Port 443
\n"
SERVER_SOFTWARE="Apache/2.0.54 (Unix) mod_ssl/2.0.54+OCSP (1.0.8) OpenSSL/0.9.8g"
SSL_CIPHER="DHE-RSA-AES256-SHA"
SSL_CIPHER_ALGKEYSIZE="256"
SSL_CIPHER_EXPORT="false"
SSL_CIPHER_USEKEYSIZE="256"
SSL_CLIENT_A_KEY="rsaEncryption" SSL_CLIENT_A_SIG="sha1WithRSAEncryption" SSL_CLIENT_I_DN="/C=BE/CN=SPECIMEN Citizen CA/serialNumber=200501"
SSL_CLIENT_I_DN_C="BE" SSL_CLIENT_I_DN_CN="SPECIMEN Citizen CA" SSL_CLIENT_M_SERIAL="0100000000011AC9A7F30E" SSL_CLIENT_M_VERSION="3" SSL_CLIENT_S_DN="/C=BE/CN=Robert SPECIMEN (Authentication)/SN=SPECIMEN/GN=Robert B3302/serialNumber=71717100052" SSL_CLIENT_S_DN_C="BE" SSL_CLIENT_S_DN_CN="Robert SPECIMEN (Authentication)" SSL_CLIENT_S_DN_G="Robert B3302" SSL_CLIENT_S_DN_S="SPECIMEN" SSL_CLIENT_S_DN_serialNumber="71717100052" SSL_CLIENT_VERIFY="SUCCESS" SSL_CLIENT_V_END="Jun 27 10:53:24 2010 GMT" SSL_CLIENT_V_START="Jun 27 10:53:24 2008 GMT"
SSL_PROTOCOL="TLSv1"
SSL_SERVER_A_KEY="rsaEncryption"
SSL_SERVER_A_SIG="sha1WithRSAEncryption"
SSL_SERVER_I_DN="/C=BE/ST=Belgium
/L=Wavre/O=Imexis/OU=eid.imexis/CN=jeango.imexis.net/emailAddress=jeangobert.decoster@imexis.net"
SSL_SERVER_I_DN_C="BE"
SSL_SERVER_I_DN_CN="jeango.imexis.net"
SSL_SERVER_I_DN_Email="jeangobert.decoster@imexis.net"
SSL_SERVER_I_DN_L="Wavre"
SSL_SERVER_I_DN_O="Imexis"
SSL_SERVER_I_DN_OU="eid.imexis"

SSL_SERVER_I_DN_ST="Belgium"
SSL_SERVER_M_SERIAL="F34F01731A03C4B7"
SSL_SERVER_M_VERSION="1"
SSL_SERVER_S_DN="/C=BE/ST=Belgium/L=Wavre/O=Imexis/OU=eid.imexis/CN=jeango.imexis.net/emailAddress=jeangobert.decoster@imexis.net"
SSL_SERVER_S_DN_C="BE"
SSL_SERVER_S_DN_CN="jeango.imexis.net"
SSL_SERVER_S_DN_Email="jeangobert.decoster@imexis.net"
SSL_SERVER_S_DN_L="Wavre"
SSL_SERVER_S_DN_O="Imexis"
SSL_SERVER_S_DN_OU="eid.imexis"

SSL_SERVER_S_DN_ST="Belgium"
SSL_SERVER_V_END="Jan 15 09:27:41 2014 GMT"
SSL_SERVER_V_START="Jul 25 09:27:41 2008 GMT"
SSL_SESSION_ID="AB9DEAC038C8A1F4625898D8141620FCEB596E1369E83ECAE76A704B8C23B0BA"
SSL_VERSION_INTERFACE="mod_ssl/2.0.54+OCSP (1.0.8)"
SSL_VERSION_LIBRARY="OpenSSL/0.9.8g"


As you can see there is a lot of information about the current SSL session. The part highlighted in red is all information regarding the client that connected. We can see that there is a variable containing robert's first name: SSL_CLIENT_S_DN_G

We can then use the RequestHeader primitive in the Apache configuration to add that information to a header we will call "First_Name":

RequestHeader set First_Name "%{SSL_CLIENT_S_DN_G}e"

Now with our reverse proxy correctly configured, our tomcat server running with our implementation of doGet, let's see what happens.



Yay!


Aucun commentaire: