root/examples/gss-server.pl

Revision 2, 3.3 kB (checked in by jroth2, 2 years ago)

intial import of gssapi examples

  • Property svn:executable set to
Line 
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use lib "/afs/acm.uiuc.edu/user/cclausen/perl/lib/perl/5.8.7";
7
8 use Getopt::Long;
9 use Sys::Hostname;
10
11 use IO::Socket::INET;
12
13 use GSSAPI;
14 use MIME::Base64;
15
16
17 my %opt;
18
19 #
20 # Arguments:
21 #   kname syntax is prodid@hostname or prodid@servicename
22 #         e.g.: host@server1
23 #         e.g.: mqm@mqserver1
24 #
25
26 unless (GetOptions(\%opt, qw(keytabfile=s hostname=s port=s))) {
27     exit(1);
28 }
29
30 if(! $opt{port}) {
31     warn "$0: -port not specified, defaulting to 10000\n";
32     $opt{port} = 10000;
33 }
34
35 if(! $opt{hostname}) {
36     $opt{hostname} = hostname();
37     warn "$0: -name not specified, using hostname result [" . $opt{hostname} . "]\n";
38 }
39 warn "$0: using [" . $opt{hostname} .':' .$opt{port} . "]\n";
40 #
41 # Servers need keytab files, the only standard so far is /etc/krb5.keytab.
42 # That's the file meant to contain keys for the local machine. It is readable
43 # only by root for security reasons. In this case the name is host@machinename.
44 #
45
46 $ENV{KRB5_KTNAME} = "FILE:" . $opt{keytabfile};
47 if (! -r $opt{keytabfile}) {
48     die "Cannot read ". $opt{keytabfile} .": $!";
49 }
50
51 print "SERVER set environment variable KRB5_KTNAME to " . $ENV{KRB5_KTNAME} . "\n";
52
53 my $listen_socket = IO::Socket::INET->new (
54                            Listen    => 16,
55                            LocalHost => $opt{hostname},
56                            LocalPort => $opt{port},
57                            ReuseAddr => 1,
58                            Proto     => 'tcp',
59                         );
60
61 die "Unable to create listen socket: $!" unless $listen_socket;
62
63 print "Listening on port $opt{port} ...\n";
64
65 my $error = 0;
66
67 while (! $error) {
68
69     my $server_context;
70     print "\nSERVER::waiting for request ...\n";
71     my $client_socket = $listen_socket->accept();
72     unless ($client_socket) {
73         warn "SERVER::accept failed: $!";
74         next;
75     }
76
77     print "SERVER::accepted connection from client ...\n";
78     my $gss_input_token = <$client_socket>;
79
80     $gss_input_token = decode_base64($gss_input_token);
81     print "SERVER::received token (length is " . length($gss_input_token) . "):\n";
82
83     if (length($gss_input_token) ) {
84         my $status = GSSAPI::Context::accept(
85                         $server_context,
86                         GSS_C_NO_CREDENTIAL,
87                         $gss_input_token,
88                         GSS_C_NO_CHANNEL_BINDINGS,
89                         my $gss_client_name,
90                         my $out_mech,
91                         my $gss_output_token,
92                         my $out_flags,
93                         my $out_time,
94                         my $gss_delegated_cred);
95
96         $status or $error = gss_exit("Unable to accept security context", $status);
97         $gss_client_name->display(my $client_name, my $type);
98         print "SERVER::authenticated client name is $client_name\n" if $client_name;
99
100         if($gss_output_token) {
101             print "SERVER::Have mutual token to send ...\n";
102             print "SERVER::GSS token size: " . length($gss_output_token) . "\n";
103
104             #
105             # $gss_output_token is binary data
106             #
107
108             my $enc_token = encode_base64($gss_output_token, '');
109
110             print $client_socket "$enc_token\n";
111             print "SERVER::sent token (length is " . length($gss_output_token) . ")\n";
112         }
113    }
114    # $server_context->DESTROY() if $server_context;
115 }
116
117 print "SERVER::exiting after error\n";
118
119 ################################################################################
120
121 sub gss_exit {
122   my $errmsg = shift;
123   my $status = shift;
124
125   my @major_errors = $status->generic_message();
126   my @minor_errors = $status->specific_message();
127  
128   print STDERR "$errmsg:\n";
129   foreach my $s (@major_errors) {
130     print STDERR "  MAJOR::$s\n";
131   }
132   foreach my $s (@minor_errors) {
133     print STDERR "  MINOR::$s\n";
134   }
135   return 1;
136 }
Note: See TracBrowser for help on using the browser.