#!/usr/bin/env perl use warnings; use strict; use Term::ReadKey; # For the noecho use GnuPG::Tie::Encrypt; use GnuPG::Tie::Decrypt; # Global vars here my $message_separator = "!"; # Separate messages on !, because gpg will put newlines into the message, but never uses '!' in ascii-armor # End of global vars client( $ARGV[0], $ARGV[1] ) if( @ARGV == 2 ); daemon( $ARGV[0] ) if( @ARGV == 1 ); usage() if( @ARGV != 1 && @ARGV != 2 ); sub usage { print "Usage:\n"; print "$0 # For listening as a daemon\n"; print "$0 # For connecting to other servers\n"; } sub client { my $target = shift; my $port = shift; my $status = `nc -z $target $port` or die "Can't open data connection (port closed or host unreachable)"; print "Who do I encrypt to: "; my $keyname = ; chomp( $keyname ); ReadMode('noecho'); print "PGP Key passphrase (not echoed): "; my $passphrase = ; chomp $passphrase; print "\n"; # The user's return key won't be echoed ReadMode(0); # Reset term status open (NET, "|-", "nc $target $port") or die "Can't open netcat: $!"; while( 0 == 0 ) { my $message = encrypt( $keyname, $passphrase ); last if $message eq "exit"; select(NET); # We select NET so $| will effect it $| = 1; # We can't buffer because of interactions with netcat. print $message . $message_separator; # Send it through the tubes! } close NET; select(STDOUT); print "Connection Terminated.\n"; } sub encrypt { select(STDOUT); my $keyname = shift; my $passphrase = shift; print "Message: "; my $message = ; chomp( $message ); return "exit" if( length($message) == 0 ); # Quit if blank message tie *ENCRYPT, 'GnuPG::Tie::Encrypt', recipient => $keyname, sign => 1, passphrase => $passphrase, armor => 1; print ENCRYPT $message; local $/ = undef; # Don't stop reading from ENCRYPT at a newline like normal my $encrypted_message = ; close ENCRYPT; untie *ENCRYPT; return $encrypted_message; } sub daemon # Listen for incomming connections { my $port = shift or die "Usage: $0 "; ReadMode('noecho'); print "PGP Key passphrase (not echoed): "; my $passphrase = ; chomp $passphrase; print "\n"; # The user's return key won't be echoed ReadMode(0); # Reset term status print( msg_time(), " Server started.\n"); open (NET, "-|", "nc -k -l $port" ) or die "Can't open netcat!"; local $/ = $message_separator; # Seperate off chosen symbol instead of newline while( ) { my $plaintext = decrypt($passphrase, $_); print( msg_time(), " ", $plaintext); } close NET; } sub msg_time { my( $hours, $minutes, $seconds ) = (localtime)[2,1,0]; return "$hours:$minutes:$seconds"; } sub decrypt { my $passphrase = shift; my $message = shift; tie *DECRYPT, 'GnuPG::Tie::Decrypt', passphrase => $passphrase; print DECRYPT $message; # Here's where I error out my $plaintext_message = ; close DECRYPT; untie *DECRYPT; return $plaintext_message; }