#!/usr/bin/perl -w

use IO::Socket::INET;
use Getopt::Std;
use Crypt::CBC;
use MIME::Base64;
use strict;

our %Prefs;

# Default configuration values
# (command line options will override these settings)
#
$Prefs{p} = 51324;          # peer port
$Prefs{d} = 'localhost';    # peer host, destination
$Prefs{k} = 'e2wq3KBz';     # DES key
$Prefs{f} = 23;             # function code

#
$Prefs{l} = 8;              # password length

# process command line options and read the config file
sub getOptions {
    my $opt_string = 'p:f:d:k:hv';
    getopts( "$opt_string", \%Prefs ) or usage();

    usage() if $Prefs{h};
}

# print some usage hints
sub usage() {
    system "clear";
    print STDERR << "EOF";

   +-----------------------------------------------------------+
   |                       =  O P E N E R  =                   |
   |                       jcb 2004  (c) LNM                   |
   +-----------------------------------------------------------+

    usage: $0 [-hvpdfk ]  
     
     -h        : this help message
     -v        : verbose
     -p <port> : udp port number (stealth port)
     -d <addr> : destination host name or ip addr
     -f <0-99> : function code
     -k <key>  : DES key
     

    example: $0 -d 192.168.1.1 -p 1234 -f 23 
    
    Default values for all options as well as some other 
    preferences are hard coded in the script. The command
    line options will override the script values of the
    same name. 
        
EOF

    exit;
}

# Passwort-Generator
sub generate_pw {
    my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
      localtime( time() );
    my $seedval = ( $yday * 24 + $hour ) * 60 + $min;
    srand($seedval);
    my @KeyElem = ( ( 'a' .. 'z' ), ( 'A' .. 'Z' ), ( 0 .. 9 ) );
    my $pw = '';
    for ( 1 .. $Prefs{l} ) {
        my $i = int( rand(61) );
        $pw .= $KeyElem[$i];
    }
    if ( $Prefs{v} ) { print "Password $pw generated with seedval $seedval \n"; }
    return $pw;
}

# DES-Verschluesselung
sub encrypt_pw {
    my ( $plaintext, $deskey ) = @_;
    my $cipher = Crypt::CBC->new( $Prefs{k}, "Crypt::DES" );
    my $ciphertext = encode_base64( $cipher->encrypt($plaintext) );
    return $ciphertext;
}

#
# ==--> M A I N <--==
#

getOptions();

# Create a new socket
my $Socket = new IO::Socket::INET->new(
    PeerPort => $Prefs{p},
    Proto    => 'udp',
    PeerAddr => $Prefs{d}
);

# Send messages
my $pw = generate_pw();
$pw = $pw . ":" . $Prefs{f};
my $key = encrypt_pw( $pw, $Prefs{k} );
if ( $Prefs{v} ) { print "Decrypted password + function $Prefs{f} = $key \n"; }

$Socket->send($key);


