Use this to make a key:
perl -e 'print pack("H16",join("",map{$_=chr(int(rand(177)));}(1..56))
+);' >>keyfile.key
Here is the server:
#!/usr/bin/perl -w
#
# bleh bleh OO perl ownz j00
#
use strict;
use Crypt::Blowfish;
use IO::Socket;
use Fcntl qw(:flock);
use vars qw($sock $cipher $acpt_sock $key $pid $in);
#
# takes a string of any size and pads string with SOH char
# if the string does not split into $blocksize byte segments evenly
#
sub pad {
my($string) = shift;
my($blocksize) = shift;
my($strlen) = length($string);
return($string) if ($strlen == $blocksize);
return($string.chr(1)x($blocksize - $strlen)) if ($strlen < $blocksi
+ze);
if ($strlen > $blocksize) {
while($strlen = $strlen - $blocksize) {
last if ($strlen < $blocksize);
}
return($string.chr(1)x($blocksize - $strlen));
}
return($string);
}
#
# takes a Crypt::Blowfish handle and a string of any size
# then uses pads string useing pad() function then chunks
# off 8 byte segments of string and encrypt's those and
# assembles encrypted string in a scalar to be returned
#
sub encrypt {
my($handle) = shift || return(undef());
my($string) = pad(shift,8) || return(undef());
my($ret,$offset);
$offset = 0;
while(defined($_ = substr($string,$offset,8))) {
$ret .= $handle->encrypt($_) unless(!$_);
$offset = int($offset) + 8;
last if ($offset >= length($string));
}
return($ret);
}
#
# takes encrypted string (in binary of course).
# then decryptes string in 8 byte segments
# and assembles in scalar to be returned
#
sub decrypt {
my($handle) = shift || return(undef());
my($string) = shift || return(undef());
my($ret,$offset);
$offset = 0;
while(defined($_ = substr($string,$offset,8))) {
$ret .= $handle->decrypt($_) unless(!$_);
$offset = int($offset) + 8;
last if ($offset >= length($string));
}
return($ret);
}
#
# main code starts here (i.e. not sub routines)
#
#
# spout usage is less than or more than one argument
#
die "Usage: $0 <keyfile>\n" unless(@ARGV==1);
#
# read in key file for use with Crypt::Blowfish
#
local(*KEY);
open(KEY,$ARGV[0]) || die "$!: \"$ARGV[0]\"\n";
flock(KEY,LOCK_EX);
$key = <KEY>;
close(KEY);
#
# build my Crypt::Blowfish handle useing $key
#
$cipher = new Crypt::Blowfish $key;
#
# build my IO::Socket handle for being a tcp server
#
$sock = IO::Socket::INET->new(
LocalPort =>9200, # set port to listen on to 9200
Listen =>5, # Accept only 5 connections at once (pointless)
Proto =>'tcp', # use tcp proto
Reuse =>1 # my kernel happy by free ports immediatly
);
#
# loop to handle accepting connections as well as server
# type mombo jumpo such as server codes, parsing, decryption
#
while($acpt_sock = $sock->accept()) {
print "Connection from ",$acpt_sock->peerhost(),":",$acpt_sock
+->peerport(),"\n" unless(!$acpt_sock);
unless($pid = fork() && $acpt_sock) {
print $acpt_sock "-OK- Crypted Server\n\r" unless(!$ac
+pt_sock);
while(<$acpt_sock>) {
s/(\r|\n)//g;
print $acpt_sock encrypt($cipher,decrypt($ciph
+er,$_)),"\r\n";
}
print "Connection closed by ",$acpt_sock->peerhost(),"
+:",$acpt_sock->peerport(),"\n" unless(!$acpt_sock);
close($acpt_sock);
exit(0);
}
}
And here is the client:
#!/usr/bin/perl -w
#
# bleh bleh OO perl ownz j00
#
use strict;
use Crypt::Blowfish;
use IO::Socket;
use Term::ReadLine;
use Fcntl qw(:flock);
use vars qw($sock $cipher $acpt_sock $key $in $term);
#
# takes a string of any size and pads string with SOH char
# if the string does not split into $blocksize byte segments evenly
#
sub pad {
my($string) = shift;
my($blocksize) = shift;
my($strlen) = length($string);
return($string) if ($strlen == $blocksize);
return($string.chr(1)x($blocksize - $strlen)) if ($strlen < $blocksi
+ze);
if ($strlen > $blocksize) {
while($strlen = $strlen - $blocksize) {
last if ($strlen < $blocksize);
}
return($string.chr(1)x($blocksize - $strlen));
}
return($string);
}
#
# takes a Crypt::Blowfish handle and a string of any size
# then uses pads string useing pad() function then chunks
# off 8 byte segments of string and encrypt's those and
# assembles encrypted string in a scalar to be returned
#
sub encrypt {
my($handle) = shift || return(undef());
my($string) = pad(shift,8) || return(undef());
my($ret,$offset);
$offset = 0;
while(defined($_ = substr($string,$offset,8))) {
$ret .= $handle->encrypt($_) unless(!$_);
$offset = int($offset) + 8;
last if ($offset >= length($string));
}
return($ret);
}
#
# takes encrypted string (in binary of course)
# then decryptes string in 8 byte segments
# and assembles in scalar to be returned
#
sub decrypt {
my($handle) = shift || return(undef());
my($string) = shift || return(undef());
my($ret,$offset);
$offset = 0;
while(defined($_ = substr($string,$offset,8))) {
$ret .= $handle->decrypt($_) unless(!$_);
$offset = int($offset) + 8;
last if ($offset >= length($string));
}
return($ret);
}
#
# prompts user for data
#
sub prompt {
my($handle) = shift;
my($prompt) = shift;
my($ret);
while(!($ret = $handle->readline($prompt))) {};
return($ret);
}
#
# main code starts here (i.e. not sub routines)
#
#
# spout usage is less than or more than two argument
#
die "Usage: $0 <hostname> <keyfile>\n" unless(@ARGV==2);
#
# read in key file for use with Crypt::Blowfish
#
local(*KEY);
open(KEY,$ARGV[1]) || die "$!: \"$ARGV[0]\"\n";
flock(KEY,LOCK_EX);
$key = <KEY>;
close(KEY);
#
# buile my Crypt::Blowfish handle useing $key
#
$cipher = new Crypt::Blowfish $key;
#
# build my IO::Socket handle for being a tcp client
#
$sock = IO::Socket::INET->new(
PeerAddr =>$ARGV[0], # set host to connect to from $ARGV[0]
PeerPort =>9200, # connecting to port 9200 on PeerAddr
Proto =>'tcp' # we are using tcp proto
);
die "Could not connect to $ARGV[0] !\n" unless($sock);
#
# build my Term::ReadLine handle;
#
$term = new Term::ReadLine undef;
$term->ornaments(0);
#
# check for server output dont do crap until gotten -ok-
#
while(<$sock>) {
if (/-ok- crypted server/i) {
print "*** Connected to server ***\n";
last;
}
}
#
# loop for server output and user input
#
while($_ = prompt($term,"> ")) {
die "Lost connection to $ARGV[0]\n" unless($sock);
print $sock encrypt($cipher,$_),"\r\n";
$in = <$sock>;
$in =~ s/(\r|\n)//g;
print decrypt($cipher,$in),"\n";
undef($in);
}
P.S. this is just test code, only a demonstration on how one
would write such a client/server :)
|