A GSSAPI Authenticated / Preforked Server
sabato 31 Maggio 2008
From its name, it sounds good , but really complicated! I had two lazy hours during my last working day and I started to play with Net:
erver:
reFork and with GSSAPI. They are Perl module (the language of the future, for me!
). So I created this server that does nothing but it authenticates with GSSAPI.
It will be a good starting point for the future. I used the gss-client pre of the GSSAPI distribution. The server is this:
#!/usr/bin/perl package MyPackage; use base qw(Net:erver:
reFork); use strict; use warnings; use Getopt::Long; use Sys::Hostname; use GSSAPI; use MIME::Base64; use IO:
ocket::INET; my $self = shift; my $keytabfile; $keytabfile = "./ciccio.keytab"; $ENV{KRB5_KTNAME} = "FILE:".$keytabfile; if (! -r $keytabfile) { die "Cannot read ". $keytabfile .": $!"; } print STDERR "SERVER set environment variable KRB5_KTNAME to " . $ENV{KRB5_KTNAME} . "\n"; sub process_main { my $self = shift; while (
) { s/\r?\n$//; print "You said \"$_\"\r\n"; # basic echo last if /quit/i; } } sub process_request { # # Servers need keytab files, the only standard so far is /etc/krb5.keytab. # That's the file meant to contain keys for the local machine. It is readable # only by root for security reasons. In this case the name is host@machinename. # my $error = 0; while (! $error) { my $server_context; print STDERR "\nSERVER::waiting for request ...\n"; print STDERR "SERVER::accepted connection from client ...\n"; my $gss_input_token = ; print STDERR "SERVER::received token (length is " . length($gss_input_token) . ") n"; $gss_input_token = depre_base64($gss_input_token); if (length($gss_input_token) ) { my $status = GSSAPI::Context::accept($server_context, GSS_C_NO_CREDENTIAL, $gss_input_token, GSS_C_NO_CHANNEL_BINDINGS, my $gss_client_name, my $out_mech, my $gss_output_token, my $out_flags, my $out_time, my $gss_delegated_cred); $status or gss_exit("Unable to accept security context", $status); my $client_name; $status = $gss_client_name->display($client_name); $status or gss_exit("Unable to display client name", $status); print STDERR "SERVER::authenticated client name is $client_name\n" if $client_name; if($gss_output_token) { print STDERR "SERVER::Have mutual token to send ...\n"; print STDERR "SERVER::GSS token size: " . length($gss_output_token) . "\n"; # # $gss_output_token is binary data # my $enc_token = enpre_base64($gss_output_token, ''); print "$enc_token\n"; print STDERR "SERVER::sent token (length is " . length($gss_output_token) . ")\n"; } } else { print STDERR "SERVER::Token fails"; exit; } # Client is authenticated process_main(); } print "SERVER::exiting after error\n"; ################################################################################ } #process request sub gss_exit { my $errmsg = shift; my $status = shift; my @major_errors = $status->generic_message(); my @minor_errors = $status->specific_message(); print STDERR "$errmsg
n"; foreach my $s (@major_errors) { print STDERR " MAJOR::$s\n"; } foreach my $s (@minor_errors) { print STDERR " MINOR::$s\n"; } return 1; } MyPackage->run(port => 3000);

