1#!/usr/local/bin/perl
2
3# simple_server
4# uses rd_req & rd_priv to decrypt an authentic encrypted message
5
6use blib; # remove if not in module build directory
7use IO::Socket;
8use Sys::Hostname;
9use Authen::Krb5 (ADDRTYPE_INET,ADDRTYPE_IPPORT,KRB5_NT_SRV_HST);
10
11# replace with your own stuff
12$SERVICE = "sample";
13$KEYTAB_FILE = "/etc/krb5.keytab";
14
15chomp($SERVER = hostname());
16
17Authen::Krb5::init_context();
18
19$ac = new Authen::Krb5::AuthContext;
20
21$s = new IO::Socket::INET(
22	LocalAddr => $SERVER,
23	LocalPort => 12345,
24	Proto => 'tcp',
25	Reuse => 1,
26	Listen => 5
27);
28defined $s or die $!;
29
30$ns = $s->accept();
31
32# grab the client's address
33$addr = new Authen::Krb5::Address(ADDRTYPE_INET,pack("N",$ns->peeraddr()));
34$ports = new Authen::Krb5::Address(ADDRTYPE_IPPORT,pack("n",$ns->peerport()));
35
36# get authentication info
37while (defined($line = <$ns>)) {
38	$d .= $line;
39	if ($line =~ /__END$/) {
40		chomp $d;
41		$d =~ s/__END$//;
42		last;
43	}
44}
45
46# get encrypted message
47while (defined($line = <$ns>)) {
48	$enc .= $line;
49	if ($line =~ /__END$/) {
50		chomp $enc;
51		$enc =~ s/__END$//;
52		last;
53	}
54}
55
56$sprinc = Authen::Krb5::sname_to_principal($SERVER,$SERVICE,KRB5_NT_SRV_HST);
57$kt = Authen::Krb5::kt_resolve("FILE:$KEYTAB_FILE");
58$t = Authen::Krb5::rd_req($ac,$d,$sprinc,$kt);
59unless ($t) {
60	print "rd_req error: ",Authen::Krb5::error(),"\n";
61	exit(1);
62}
63
64$client = $t->enc_part2->client;
65print "Hello, ",$client->data,"\n";
66
67# set the remote address
68$ac->setaddrs(undef,$addr);
69$ac->setports(undef,$ports);
70
71# decrypt the message
72$dec = Authen::Krb5::rd_priv($ac,$enc);
73unless ($dec) {
74	print "rd_priv error: ",Authen::Krb5::error(),"\n";
75	exit(1);
76}
77
78print "Decrypted message is: '$dec'\n";
79
80Authen::Krb5::free_context();
81