Google Answers Logo
View Question
 
Q: Perl Socket programming and SSL ( No Answer,   0 Comments )
Question  
Subject: Perl Socket programming and SSL
Category: Computers > Programming
Asked by: mactac-ga
List Price: $30.00
Posted: 16 Jun 2004 09:20 PDT
Expires: 16 Jul 2004 09:20 PDT
Question ID: 361922
I am a perl programmer, but do not quite grasp what needs to be done
to set up SSL sockets.  I am trying to set up a server to receive
incoming TCP requests on a port & respond to them.  I have it set up
right now using IO::sockets::INET (which is working properly), but
want to add encryption so
sensitive data may be passed back and forth.

my questions are:

1.  I need to know how to correctly us IO:SOCKET::SSL  with my
certificate.  I can't create the socket.  I read that IO::SOCKET::SSL
is a drop in replacement for IO:SOCKET::INET, but when i replaced it,
it didn't function (I think I need to make reference to the cert or
something, can't find good docs on this).  I need to make my script
work with my certificate.  It may in fact be working, but I am unsure
as to how to test it.

3.  I've read all sorts of things about closing sockets properly, esp
with SSL.  am I doing this right?

4.  I want this app to be able to accept multiple sockets at once. 
mine waits for each socket until the prev is done.

I would like my code modified to incorporate all of these 3 issues. 
here is what I have currently (in the non-ssl version, and it is
working correctly...except for threading):

#!/usr/bin/perl

use IO::Socket::INET;

$server_port=11194;     #this is the port to listen on !

#  open a socket, start listening for connections, for some reason
changing this to IO::SOCKET::SSL doesn't work.. prob needs more
parameters?

$server = IO::Socket::INET->new(LocalPort => $server_port,
                                Type      => SOCK_STREAM, 
                                Reuse     => 1,
                                Listen    => 10 )
or die "Couldn't be a tcp server on port $server_port: $!\n";

while ($client = $server->accept()) {
    # $client is the new connection   
    $text=<$client>;
    
    #  do some stuff with $text
    
    # send to the client whatever I did in $return
    print $client $return;
    close($client);
    
    # clear query because it seems to keep old stuff in $text
    $text="";
    undef($text);
}   
close($server);
 

--------------------------------------------------------------------------------

Request for Question Clarification by studboy-ga on 16 Jun 2004 16:06 PDT
Hi mactac-ga

The SSL.pm man pages gives a pretty good description of each of the
fields for SSL->new.  Here's an example (based on a combo of your
script and from under example/ in the IO::SSL package).  As you can
see,

1) Add more fields to your SSL->new )-- as compared to INET->new.  See
man pages for other fields.  Also see
www.openssl.org/docs/apps/ciphers.html.

2) Assuming you use $server = $server = IO::Socket::new(...), the
proper way to close it is $server->close();

3) Put it under a while(1) loop to look for multiple connections.

Make sure you've Leay installed.  Let me know if this helps and I will
post a formal answer.  Thanks.

-----

#!/usr/bin/perl

use IO::Socket::SSL;

$server_port=11194;     #this is the port to listen on !

#  open a socket, start listening for connections, for some reason
changing this to IO::SOCKET::SSL doesn't work.. prob needs more
parameters?

$server = IO::Socket::SSL->new(LocalPort => $server_port,
                                Type      => SOCK_STREAM, 
                                Reuse     => 1,
                                Listen    => 10 ,			
				   Proto     => 'tcp',
				   SSL_verify_mode => 0x01,
				   SSL_passwd_cb => sub {return "bluebell"})
or die "Couldn't be a tcp server on port $server_port: $!\n";

while (1) {
  warn "waiting for next connection.\n";
  
while ($client = $server->accept()) {
    # $client is the new connection   
    $text=<$client>;
    
    #  do some stuff with $text
    
    # send to the client whatever I did in $return
    print $client $return;
    close($client);
    
    # clear query because it seems to keep old stuff in $text
    $text="";
    undef($text);
}   
}
$server->close();

Request for Question Clarification by studboy-ga on 16 Jun 2004 16:09 PDT
FYI From the example/ dir: sample server.pl and client.pl

Let me know how it goes.  Thanks.

server.pl:

#
# a test server for testing IO::Socket::SSL-class's behavior
# (marko.asplund at kronodoc.fi).
#
# $Id: ssl_server.pl,v 1.7 2000/11/08 09:25:21 aspa Exp $.
#

use strict;
use IO::Socket::SSL;


my ($sock, $s, $v_mode);

if($ARGV[0] eq "DEBUG") { $IO::Socket::SSL::DEBUG = 1; }

# Check to make sure that we were not accidentally run in the wrong
# directory:
unless (-d "certs") {
    if (-d "../certs") {
	chdir "..";
    } else {
	die "Please run this example from the IO::Socket::SSL distribution directory!\n";
    }
}

if(!($sock = IO::Socket::SSL->new( Listen => 5,
				   LocalAddr => 'localhost',
				   LocalPort => 9000,
				   Proto     => 'tcp',
				   Reuse     => 1,
				   SSL_verify_mode => 0x01,
				   SSL_passwd_cb => sub {return "bluebell"},
				 )) ) {
    warn "unable to create socket: ", &IO::Socket::SSL::errstr, "\n";
    exit(0);
}
warn "socket created: $sock.\n";

while (1) {
  warn "waiting for next connection.\n";
  
  while(($s = $sock->accept())) {
      my ($peer_cert, $subject_name, $issuer_name, $date, $str);
      
      if( ! $s ) {
	  warn "error: ", $sock->errstr, "\n";
	  next;
      }
      
      warn "connection opened ($s).\n";
      
      if( ref($sock) eq "IO::Socket::SSL") {
	  $subject_name = $s->peer_certificate("subject");
	  $issuer_name = $s->peer_certificate("issuer");
      }
      
      warn "\t subject: '$subject_name'.\n";
      warn "\t issuer: '$issuer_name'.\n";
  
      my $date = localtime();
      print $s "my date command says it's: '$date'";
      close($s);
      warn "\t connection closed.\n";
  }
}


$sock->close();

warn "loop exited.\n";

----------

client.pl:

#
# a test client for testing IO::Socket::SSL-class's behavior
# (marko.asplund at kronodoc.fi).
#
# $Id: ssl_client.pl,v 1.7 2002/01/04 08:45:12 aspa Exp $.
#


use strict;
use IO::Socket::SSL;

my ($v_mode, $sock, $buf);

if($ARGV[0] eq "DEBUG") { $IO::Socket::SSL::DEBUG = 1; }

# Check to make sure that we were not accidentally run in the wrong
# directory:
unless (-d "certs") {
    if (-d "../certs") {
	chdir "..";
    } else {
	die "Please run this example from the IO::Socket::SSL distribution directory!\n";
    }
}

if(!($sock = IO::Socket::SSL->new( PeerAddr => 'localhost',
				   PeerPort => '9000',
				   Proto    => 'tcp',
				   SSL_use_cert => 1,
				   SSL_verify_mode => 0x01,
				   SSL_passwd_cb => sub { return "opossum" },
				 ))) {
    warn "unable to create socket: ", &IO::Socket::SSL::errstr, "\n";
    exit(0);
} else {
    warn "connect ($sock).\n" if ($IO::Socket::SSL::DEBUG);
}

# check server cert.
my ($subject_name, $issuer_name, $cipher);
if( ref($sock) eq "IO::Socket::SSL") {
    $subject_name = $sock->peer_certificate("subject");
    $issuer_name = $sock->peer_certificate("issuer");
    $cipher = $sock->get_cipher();
}
warn "cipher: $cipher.\n", "server cert:\n", 
    "\t '$subject_name' \n\t '$issuer_name'.\n\n";

my ($buf) = $sock->getlines;

$sock->close();

print "read: '$buf'.\n";

Request for Question Clarification by studboy-ga on 16 Jun 2004 16:12 PDT
BTW, the client "tests" the server.

Clarification of Question by mactac-ga on 16 Jun 2004 16:58 PDT
I think that your methos for opening many sockets will only open &
answer them in series, no?   I don't see any threading.

Clarification of Question by mactac-ga on 16 Jun 2004 17:18 PDT
"Please run this example from the IO::Socket::SSL distribution directory!"

also, I cannot do this.  I am hosted with an ISP, and they do not
allow me access to this

Obviously there is some way around this, I assume I have to put my
certs in a specific directory, with specific names (what names?)

I did see these examples, but they didn't work.  see, the problem is,
adding the client part just compounds the problem - i don't even know
if the client is working properly, so it's extremely difficult to test
with this.

Request for Question Clarification by studboy-ga on 17 Jun 2004 13:51 PDT
Hi mactac-ga

1) If you want a true parallel, enclose the dispatch part within a
fork-join (like a daemon) and/or threads.

2) Please see the man pages on SSL.pm: the documentation says the
SSL_cert_file option can be used to specify your own path/file.  See
also SSL_key_file, SSL_ca_file, ...  The default certificates are in
certs/ under the distribution.

I believe the client/server scripts are well testes by CPAN users, so
I'm sure they work OK.

Let me know how it goes.  Thanks.

Request for Question Clarification by studboy-ga on 17 Jun 2004 13:53 PDT
Also, since you have a PC(linux)/unix machine at home,  I receommend
downloading the SSL perl module and play with it with apache at home
before uploading your work to your host/ISP.

Request for Question Clarification by studboy-ga on 19 Jun 2004 00:36 PDT
Hi mactac-ga

Any good news?

Thanks

Request for Question Clarification by studboy-ga on 23 Jun 2004 07:44 PDT
Hi mactac-ga

Any updates on this one?

Thanks!

Clarification of Question by mactac-ga on 23 Jun 2004 15:24 PDT
OK, the reason It still isn't working is because my questions are not
really being answered.

1.  What files EXACTLY do I need as far as certs go?  I have them in a
subdir called certs/ off the dir where my script lives - is this
right?

2.  Can I test it by ssh-ing in with a telnet program?  it's hard
enough getting one script going, let alone 2.  impossible to test this
way.

3. I can read the doc myself, so "read the docs" isn;t really helping
me :)  my problem is that i'm having a hard time understnading EXACTLY
what I need to do to make this work.

still getting "unable to create socket: Invalid certificate authority locations"

I will also need someone to show me how to do the form properly as
well once this is going...

thanks

if you want to email me directly you can email me at paul (at )
merchantsense.com  to speed this process all up

Clarification of Question by mactac-ga on 23 Jun 2004 15:44 PDT
here is what I added to the socket call:

SSL_cert_file => '/path to my files/server-cert.pem',
SSL_key_file => '/path to my files/server-key.pem',
SSL_passwd_cb => sub {return "my password for my certs"},
Answer  
There is no answer at this time.

Comments  
There are no comments at this time.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy